@@ -28,6 +28,8 @@ type Workflow struct {
2828 Start * StartTask
2929 Tasks map [TaskId ]Task
3030 End * EndTask
31+
32+ prevTasks map [TaskId ][]TaskId
3133}
3234
3335func newWorkflow () Workflow {
@@ -71,6 +73,47 @@ func isEndTask(task Task) bool {
7173 return ok
7274}
7375
76+ func (w * Workflow ) GetPreviousTasks (task Task ) []TaskId {
77+ if w .prevTasks == nil {
78+ w .computePreviousTasks ()
79+ }
80+
81+ return w .prevTasks [task .GetId ()]
82+ }
83+
84+ func (w * Workflow ) GetAllPreviousTasks () map [TaskId ][]TaskId {
85+ if w .prevTasks == nil {
86+ w .computePreviousTasks ()
87+ }
88+
89+ return w .prevTasks
90+ }
91+
92+ func (w * Workflow ) computePreviousTasks () {
93+ w .prevTasks = make (map [TaskId ][]TaskId )
94+ visited := make (map [TaskId ]bool )
95+ for tid , _ := range w .Tasks {
96+ w .prevTasks [tid ] = make ([]TaskId , 0 )
97+ visited [tid ] = false
98+ }
99+
100+ toVisit := []Task {w .Start }
101+
102+ for len (toVisit ) > 0 {
103+ task := toVisit [0 ]
104+ toVisit = toVisit [1 :]
105+ visited [task .GetId ()] = true
106+
107+ for _ , nextTask := range task .GetNext () {
108+ // task -> nextTask
109+ w .prevTasks [nextTask ] = append (w .prevTasks [nextTask ], task .GetId ())
110+ if ! visited [nextTask ] {
111+ toVisit = append (toVisit , w .Tasks [nextTask ])
112+ }
113+ }
114+ }
115+ }
116+
74117// Visit visits the workflow starting from the given task and return a list of visited tasks.
75118// If excludeEnd = true, the EndTask will not be in the output list
76119func Visit (workflow * Workflow , taskId TaskId , tasks []Task , excludeEnd bool ) []Task {
0 commit comments