Skip to content

Commit

Permalink
Building an array of node ids instead of functions
Browse files Browse the repository at this point in the history
  • Loading branch information
rustedgrail committed Feb 5, 2018
1 parent f529d9a commit ee72d87
Showing 1 changed file with 30 additions and 60 deletions.
90 changes: 30 additions & 60 deletions lib/position/bk.js
Expand Up @@ -211,77 +211,47 @@ function horizontalCompaction(g, layering, root, align, reverseSep) {
// coordinates. The second sweep removes unused space by moving blocks to the
// greatest coordinates without violating separation.
var xs = {},
visited = {},
blockG = buildBlockGraph(g, layering, root, reverseSep),
borderType = reverseSep ? "borderLeft" : "borderRight";

// This function handles iterating over the graph without adding functions
// calls to the stack. The argument, getNextTraversalFuncs, returns an array
// of functions. These returned functions are the recursive and base function
// calls. By returning the functions and calling them here, we do not add
// additional function calls to the stack. If the recursive case generates
// additional function calls, they will be prepended to the array.
function iterate(getNextTraversalFuncs, v) {
var traversalFuncs = getNextTraversalFuncs(v);

while(traversalFuncs.length) {
traversalFuncs = traversalFuncs.shift()().concat(traversalFuncs);
}
}
function iterate(setXsFunc, nextNodesFunc) {
var stack = blockG.nodes();
var elem = stack.pop();
var visited = {};
while (elem) {
if (visited[elem]) {
setXsFunc(elem);
} else {
visited[elem] = true;
stack.push(elem);
stack = stack.concat(nextNodesFunc(elem));
}

// pass1 maps over the inEdges of a node and creates a recursive function that
// will be called by iterate. Finally, it sets xs[v] to the smallest
// coordinates.
function pass1(v) {
if (_.has(visited, v)) {
return [];
elem = stack.pop();
}

visited[v] = true;

return _.map(blockG.inEdges(v), function(e) {
return function() { return pass1(e.v); };
}).concat([function () {
xs[v] = _.reduce(blockG.inEdges(v), function(acc, e) {
return Math.max(acc, xs[e.v] + blockG.edge(e));
}, 0);

return [];
}]);
}

// pass2 maps over the outEdges of a node and creates a recursive function
// that will be called by iterate. Finally, it sets xs[v] to the greatest
// coordinates.
function pass2(v) {
if (_.has(visited, v)) {
return [];
}

visited[v] = true;

return _.map(blockG.outEdges(v), function(e) {
return function() { return pass2(e.w); };
}).concat([function () {
var min = _.reduce(blockG.outEdges(v), function(acc, e) {
return Math.min(acc, xs[e.w] - blockG.edge(e));
}, Number.POSITIVE_INFINITY);
// First pass, assign smallest coordinates
function pass1(elem) {
xs[elem] = blockG.inEdges(elem).reduce(function(acc, e) {
return Math.max(acc, xs[e.v] + blockG.edge(e));
}, 0);
}

var node = g.node(v);
if (min !== Number.POSITIVE_INFINITY && node.borderType !== borderType) {
xs[v] = Math.max(xs[v], min);
}
// Second pass, assign greatest coordinates
function pass2(elem) {
var min = blockG.outEdges(elem).reduce(function(acc, e) {
return Math.min(acc, xs[e.w] - blockG.edge(e));
}, Number.POSITIVE_INFINITY);

return [];
}]);
var node = g.node(elem);
if (min !== Number.POSITIVE_INFINITY && node.borderType !== borderType) {
xs[elem] = Math.max(xs[elem], min);
}
}

// First pass, assign smallest coordinates via DFS
_.forEach(blockG.nodes(), _.bind(iterate, null, pass1));

visited = {};
// Second pass, assign greatest coordinates via DFS
_.forEach(blockG.nodes(), _.bind(iterate, null, pass2));
iterate(pass1, _.bind(blockG.predecessors, blockG));
iterate(pass2, _.bind(blockG.successors, blockG));

// Assign x coordinates to all nodes
_.forEach(align, function(v) {
Expand Down

0 comments on commit ee72d87

Please sign in to comment.