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());
}
예제 #3
0
void CRUTask::RemoveAllTasksThatDependOnMe()
{
    DSListPosition pos = GetTasksThatDependOnMe().GetHeadPosition();

    while (NULL != pos)
    {
        CRUTask *pToTask = GetTasksThatDependOnMe().GetNext(pos);
        pToTask->GetTasksThatIDependOn().RemoveRefToTask(this);
    }

    GetTasksThatDependOnMe().RemoveAll();
}