private NodeTask BuildDependencyTree(string rootTask) { Queue<NodeTask> notProcessedNodes = new Queue<NodeTask>(); NodeTask rootNode = new NodeTask(rootTask); taskToNode.Add(rootTask, rootNode); notProcessedNodes.Enqueue(rootNode); while (notProcessedNodes.Count > 0) { NodeTask currentNode = notProcessedNodes.Dequeue(); if (!taskToDescription.ContainsKey(currentNode.Name)) { throw new BuildSystemException(String.Format("No declaration for task \"{0}\" found.", rootTask)); } IList<string> dependencies = taskToDescription[currentNode.Name].Dependencies; IList<NodeTask> children = new List<NodeTask>(dependencies.Count); foreach (var child in dependencies) { if (taskToNode.ContainsKey(child)) { children.Add(taskToNode[child]); } else { NodeTask childNode = new NodeTask(child); taskToNode.Add(child, childNode); children.Add(childNode); notProcessedNodes.Enqueue(childNode); } } currentNode.Children = children; } return rootNode; }
private void SatisfyNodeTask(NodeTask node) { Stack<NodeTask> notSatisfiedTasks = new Stack<NodeTask>(); Console.WriteLine("\"{0}\" task is started.", node.Name); notSatisfiedTasks.Push(node); while (notSatisfiedTasks.Count > 0) { bool continueFlag = false; NodeTask current = notSatisfiedTasks.Peek(); foreach (var child in current.Children) { if (!child.Satisfied) { Console.WriteLine("\"{0}\" task is started.", child.Name); notSatisfiedTasks.Push(child); continueFlag = true; break; } } if (continueFlag) { continue; } ExecuteActions(taskToDescription[current.Name].Actions); current.Satisfied = true; Console.WriteLine("\"{0}\" task is finished.", current.Name); notSatisfiedTasks.Pop(); } }
private void SatisfyInitialTask() { if (!File.Exists(makefileName)) { throw new BuildSystemException(String.Format("File \"{0}\" doesn't exist.", makefileName)); } // first pass through file ReadDependeciesForAllTasks(); initialTaskDependencyTree = BuildDependencyTree(initialTask); if (!NoCycles(initialTaskDependencyTree)) { throw new BuildSystemException("Cannot determine the order of execution: circular dependency found."); } // second pass through file ReadActionsForTasksFromDependencyTree(); SatisfyNodeTask(initialTaskDependencyTree); }
private bool NoCycles(NodeTask node) { Stack<NodeTask> notProcessedNodes = new Stack<NodeTask>(); node.State = 1; notProcessedNodes.Push(node); while (notProcessedNodes.Count > 0) { bool continueFlag = false; NodeTask current = notProcessedNodes.Peek(); foreach (var child in current.Children) { if (child.State == 1) { return false; } if (child.State == 0) { child.State = 1; notProcessedNodes.Push(child); continueFlag = true; break; } } if (continueFlag) { continue; } // all children are black =) current.State = 2; notProcessedNodes.Pop(); } return true; }