void CRUTopologicalDGIterator::Next() { RUASSERT(FALSE == allTasksLinkMap_.IsEmpty()); CRUTask *pTask = GetCurrentTask(); if (NULL == pTask) { return; // all the tasks have been already traversed } // The tasks that need to be traversed after me CRUTaskList &refTaskList = (DIRECT == dir_) ? pTask->GetTasksThatDependOnMe() : pTask->GetTasksThatIDependOn(); // For all of these tasks, decrecase the reference count // Update the "ready" list, if any of the tasks have become ready. UpdateIterator(refTaskList); // Select a new current task if (TRUE == readyTasksList_.IsEmpty()) { SetCurrentTask(NULL); // The last task has just been traversed } else { // Retrieve a new task from the "ready" list SetCurrentTask(readyTasksList_.RemoveHead()); } }
void CRUTopologicalDGIterator::Build() { TaskLink link; // Fill the data structures by references to available tasks DSListPosition pos = GetAllTasksList().GetHeadPosition(); while (NULL != pos) { CRUTask *pTask = GetAllTasksList().GetNext(pos); link.pTask_ = pTask; // The tasks that need to be traversed before me CRUTaskList &refTaskList = (DIRECT == dir_) ? pTask->GetTasksThatIDependOn() : pTask->GetTasksThatDependOnMe(); link.refCount_ = refTaskList.GetCount(); // Place the link into the hash allTasksLinkMap_[pTask->GetId()] = link; // If this is a ready task, // place a reference to it into the ready list if (0 == link.refCount_) { readyTasksList_.AddHead(link.pTask_); } } // My guess is that this is a circular graph RUASSERT(FALSE == readyTasksList_.IsEmpty()); SetCurrentTask(readyTasksList_.RemoveHead()); }
void CRUTask::RemoveAllTasksThatDependOnMe() { DSListPosition pos = GetTasksThatDependOnMe().GetHeadPosition(); while (NULL != pos) { CRUTask *pToTask = GetTasksThatDependOnMe().GetNext(pos); pToTask->GetTasksThatIDependOn().RemoveRefToTask(this); } GetTasksThatDependOnMe().RemoveAll(); }