jinaga
Version:
Data management for web and mobile applications.
79 lines • 2.77 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.TopologicalSorter = void 0;
class TopologicalSorter {
constructor() {
this.factsVisited = {};
this.factsWaiting = {};
this.factValue = {};
}
sort(facts, map) {
const factsReceived = [];
const factQueue = facts.slice(0);
while (factQueue.length > 0) {
const fact = factQueue.shift();
const predecessorKeys = this.allPredecessors(fact);
const waitingPredecessors = predecessorKeys.filter(key => {
return !this.factsVisited[key];
});
if (waitingPredecessors.length === 0) {
const key = this.factKey(fact);
this.factsVisited[key] = true;
const predecessorValues = predecessorKeys.map(k => {
return this.factValue[k];
});
const factValue = map(predecessorValues, fact);
this.factValue[key] = factValue;
factsReceived.push(factValue);
const retry = this.factsWaiting[key];
if (retry) {
retry.forEach(r => {
if (!factQueue.some(f => f.type === r.type && f.hash === r.hash)) {
factQueue.push(r);
}
});
delete this.factsWaiting[key];
}
}
else {
waitingPredecessors.forEach(key => {
let list = this.factsWaiting[key];
if (!list) {
list = [];
this.factsWaiting[key] = list;
}
if (!list.some(f => f.type === fact.type && f.hash === fact.hash)) {
list.push(fact);
}
});
}
}
return factsReceived;
}
finished() {
for (const key in this.factsWaiting) {
if (this.factsWaiting[key]) {
return false;
}
}
return true;
}
allPredecessors(fact) {
let predecessors = [];
for (const role in fact.predecessors) {
const references = fact.predecessors[role];
if (Array.isArray(references)) {
predecessors = predecessors.concat(references.map(r => this.factKey(r)));
}
else {
predecessors.push(this.factKey(references));
}
}
return predecessors;
}
factKey(fact) {
return `${fact.type}:${fact.hash}`;
}
}
exports.TopologicalSorter = TopologicalSorter;
//# sourceMappingURL=sorter.js.map