Skip to content

Instantly share code, notes, and snippets.

@DimitryDushkin
Last active June 5, 2022 23:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DimitryDushkin/2c50d784fd8529da072dacc083d6b9cc to your computer and use it in GitHub Desktop.
Save DimitryDushkin/2c50d784fd8529da072dacc083d6b9cc to your computer and use it in GitHub Desktop.
/**
* Graph respects explicit dependencies
* and implicit by resources (via positions)
*/
export const makeGraphFromTasks = (tasks: Array<Task>): Graph => {
// task and blockedBy
const graph: Graph = new Map();
const resourcesTasks = new Map<ID, Array<Task>>();
// Create graphs
for (const t of tasks) {
// resource and its tasks
const tasksOfResource = resourcesTasks.get(t.resourceId) ?? [];
tasksOfResource.push(t);
resourcesTasks.set(t.resourceId, tasksOfResource);
graph.set(t.id, new Set(t.blockedBy ?? []));
}
// Now add deps
for (const tasksOfResource of resourcesTasks.values()) {
// first sort by position so links of tasks starts with higher position
// then topological sort to reduce cyclic deps
tasksOfResource.sort((a, b) => a.position - b.position);
// is toposort needed?
const sortedTasks = toposort(graph, tasksOfResource);
// add to graph such edges so current node has prev as dependency (blocked by prev)
let prevTask: Task | void;
for (const task of sortedTasks) {
if (
prevTask &&
prevTask.id !== task.id &&
// has no incoming edge as well (otherwise it will be cyclic dep)
!graph.get(prevTask.id)?.has(task.id)
) {
graph.get(task.id)?.add(prevTask.id);
}
prevTask = task;
}
}
return graph;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment