2022-08-14 14:14:14 +00:00
|
|
|
module ProjectItem = ReducerProject_ProjectItem
|
|
|
|
module T = ReducerProject_T
|
2022-09-11 15:22:07 +00:00
|
|
|
type t = T.t
|
2022-08-14 14:14:14 +00:00
|
|
|
|
2022-09-11 15:22:07 +00:00
|
|
|
let getSourceIds = T.getSourceIds
|
|
|
|
let getItem = T.getItem
|
2022-08-14 14:14:14 +00:00
|
|
|
|
|
|
|
let getImmediateDependencies = (this: t, sourceId: string): ProjectItem.T.includesType =>
|
2022-09-11 15:22:07 +00:00
|
|
|
this->getItem(sourceId)->ProjectItem.getImmediateDependencies
|
2022-08-14 14:14:14 +00:00
|
|
|
|
|
|
|
type topologicalSortState = (Belt.Map.String.t<bool>, list<string>)
|
|
|
|
let rec topologicalSortUtil = (
|
|
|
|
this: t,
|
|
|
|
sourceId: string,
|
|
|
|
state: topologicalSortState,
|
|
|
|
): topologicalSortState => {
|
|
|
|
let dependencies = getImmediateDependencies(this, sourceId)->Belt.Result.getWithDefault([])
|
|
|
|
let (visited, stack) = state
|
|
|
|
let myVisited = Belt.Map.String.set(visited, sourceId, true)
|
|
|
|
let (newVisited, newStack) = dependencies->Belt.Array.reduce((myVisited, stack), (
|
|
|
|
(currVisited, currStack),
|
|
|
|
dependency,
|
|
|
|
) => {
|
|
|
|
if !Belt.Map.String.getWithDefault(currVisited, dependency, false) {
|
|
|
|
topologicalSortUtil(this, dependency, (currVisited, currStack))
|
|
|
|
} else {
|
|
|
|
(currVisited, currStack)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
(newVisited, list{sourceId, ...newStack})
|
|
|
|
}
|
|
|
|
|
|
|
|
let getTopologicalSort = (this: t): array<string> => {
|
2022-09-11 15:22:07 +00:00
|
|
|
let (_visited, stack) = this->getSourceIds->Belt.Array.reduce((Belt.Map.String.empty, list{}), (
|
2022-08-14 14:14:14 +00:00
|
|
|
(currVisited, currStack),
|
|
|
|
currId,
|
|
|
|
) =>
|
|
|
|
if !Belt.Map.String.getWithDefault(currVisited, currId, false) {
|
|
|
|
topologicalSortUtil(this, currId, (currVisited, currStack))
|
|
|
|
} else {
|
|
|
|
(currVisited, currStack)
|
|
|
|
}
|
|
|
|
)
|
|
|
|
Belt.List.reverse(stack)->Belt.List.toArray
|
|
|
|
}
|
|
|
|
|
|
|
|
let getRunOrder = getTopologicalSort
|
|
|
|
|
2022-09-01 13:57:04 +00:00
|
|
|
let getRunOrderFor = (this: t, sourceId) => {
|
|
|
|
let (_visited, stack) = topologicalSortUtil(this, sourceId, (Belt.Map.String.empty, list{}))
|
|
|
|
Belt.List.reverse(stack)->Belt.List.toArray
|
2022-08-14 14:14:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
let getDependencies = (this: t, sourceId: string): array<string> => {
|
2022-09-01 13:57:04 +00:00
|
|
|
let runOrder = getTopologicalSort(this)
|
|
|
|
let index = runOrder->Js.Array2.indexOf(sourceId)
|
|
|
|
Js.Array2.slice(runOrder, ~start=0, ~end_=index)
|
2022-08-14 14:14:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
let getDependents = (this: t, sourceId: string): array<string> => {
|
2022-09-01 13:57:04 +00:00
|
|
|
let runOrder = getTopologicalSort(this)
|
|
|
|
let index = runOrder->Js.Array2.indexOf(sourceId)
|
|
|
|
Belt.Array.sliceToEnd(runOrder, index + 1)
|
2022-08-14 14:14:14 +00:00
|
|
|
}
|
2022-08-25 19:59:15 +00:00
|
|
|
|
|
|
|
let runOrderDiff = (current: array<string>, previous0: array<string>): array<string> => {
|
|
|
|
let extraLength =
|
|
|
|
Belt.Array.length(current) > Belt.Array.length(previous0)
|
|
|
|
? Belt.Array.length(current) - Belt.Array.length(previous0)
|
|
|
|
: 0
|
|
|
|
let previous = Belt.Array.copy(previous0)
|
|
|
|
let filler = Belt.Array.make(extraLength, "")
|
|
|
|
Belt.Array.forEach(filler, _ => {
|
|
|
|
let _ = Js.Array2.push(previous, "")
|
|
|
|
})
|
2022-08-25 22:45:13 +00:00
|
|
|
let zipped: array<(string, string)> = Belt.Array.zip(current, previous)
|
|
|
|
|
|
|
|
// zipped
|
|
|
|
// ->Belt.Array.map(((curr, prev)) => {
|
|
|
|
// let result = `(${curr}, ${prev})`
|
|
|
|
// result
|
|
|
|
// })
|
|
|
|
// ->Js.Array2.joinWith(", ")
|
|
|
|
// ->Js.log
|
|
|
|
|
2022-08-25 19:59:15 +00:00
|
|
|
let (_, affected) = Belt.Array.reduce(zipped, (true, []), ((wasEqual, acc), (curr, prev)) => {
|
|
|
|
switch wasEqual {
|
|
|
|
| true =>
|
|
|
|
if curr == prev {
|
2022-08-25 22:45:13 +00:00
|
|
|
(true, acc)
|
2022-08-25 19:59:15 +00:00
|
|
|
} else {
|
2022-08-25 22:45:13 +00:00
|
|
|
(false, Belt.Array.concat(acc, [curr]))
|
2022-08-25 19:59:15 +00:00
|
|
|
}
|
2022-08-25 22:45:13 +00:00
|
|
|
| false => (false, Belt.Array.concat(acc, [curr]))
|
2022-08-25 19:59:15 +00:00
|
|
|
}
|
|
|
|
})
|
|
|
|
affected
|
|
|
|
}
|