calculateTopologicalOrder assigns a topological order to each task
(tasks []*model.Task, taskMap map[string]*model.Task)
| 95 | |
| 96 | // calculateTopologicalOrder assigns a topological order to each task |
| 97 | func calculateTopologicalOrder(tasks []*model.Task, taskMap map[string]*model.Task) map[string]int { |
| 98 | order := make(map[string]int) |
| 99 | visited := make(map[string]bool) |
| 100 | counter := 0 |
| 101 | |
| 102 | var visit func(taskID string) |
| 103 | visit = func(taskID string) { |
| 104 | if visited[taskID] { |
| 105 | return |
| 106 | } |
| 107 | |
| 108 | task, exists := taskMap[taskID] |
| 109 | if !exists { |
| 110 | return |
| 111 | } |
| 112 | |
| 113 | visited[taskID] = true |
| 114 | |
| 115 | // Visit dependencies first |
| 116 | for _, depID := range task.Dependencies { |
| 117 | visit(depID) |
| 118 | } |
| 119 | |
| 120 | // Assign order |
| 121 | order[taskID] = counter |
| 122 | counter++ |
| 123 | } |
| 124 | |
| 125 | // Visit all tasks |
| 126 | for _, task := range tasks { |
| 127 | visit(task.ID) |
| 128 | } |
| 129 | |
| 130 | return order |
| 131 | } |
| 132 | |
| 133 | // calculateCriticalPathTasks identifies tasks on the critical path |
| 134 | func calculateCriticalPathTasks(tasks []*model.Task, taskMap map[string]*model.Task) map[string]bool { |
no outgoing calls