topological-sort-group
Version:
Topological sorting and cycle detection. Optional grouping for parallel processing
71 lines • 2.55 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "default", {
enumerable: true,
get: function() {
return sort;
}
});
var _cycles = /*#__PURE__*/ _interop_require_default(require("./cycles.js"));
var _types = require("./types.js");
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
// find nodes with no incoming nodes
function findRoots(graph, degrees) {
var sources = [];
for(var fromKey in degrees){
if (degrees[fromKey] === 0) sources.push(graph.nodeMap[fromKey].value);
}
return sources;
}
function sort(graph) {
var _loop = function() {
nodes.push(currentLevel.slice());
// track next level's nodes
var nextLevel = [];
var processed = {};
// process all nodes in current level
currentLevel.forEach(function(node) {
var nodeKey = graph.key(node);
// remove the node
degrees[nodeKey] = -1;
// reduce degrees for all neighbors
graph.edges(nodeKey).forEach(function(neighborKey) {
degrees[neighborKey]--;
// If neighbor has no more dependencies and hasn't been processed
if (degrees[neighborKey] === 0 && processed[neighborKey] === undefined) {
nextLevel.push(graph.value(neighborKey));
processed[neighborKey] = true;
}
});
});
// Move to next level
currentLevel = nextLevel;
};
var mode = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : _types.SortMode.Group;
var degrees = graph.degrees();
// process the nodes level by level
var nodes = [];
var currentLevel = findRoots(graph, degrees);
while(currentLevel.length > 0)_loop();
// Check for cycles
var hasCycles = false;
for(var from in degrees){
if (degrees[from] > 0) {
hasCycles = true;
break;
}
}
return {
nodes: mode === _types.SortMode.Flat ? nodes.reduce(function(m, l) {
return m.concat(l);
}, []) : nodes,
cycles: hasCycles ? (0, _cycles.default)(graph) : []
};
}
/* CJS INTEROP */ if (exports.__esModule && exports.default) { try { Object.defineProperty(exports.default, '__esModule', { value: true }); for (var key in exports) { exports.default[key] = exports[key]; } } catch (_) {}; module.exports = exports.default; }