Skip to content

Commit

Permalink
Sort nodes before sorting ports since in-layer feedback dummies exist.
Browse files Browse the repository at this point in the history
  • Loading branch information
soerendomroes committed Aug 19, 2024
1 parent 68691d8 commit 291247c
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ public void process(final LGraph graph, final IElkProgressMonitor progressMonito
layer.id = layerIndex;
final int previousLayerIndex = layerIndex == 0 ? 0 : layerIndex - 1;
Layer previousLayer = graph.getLayers().get(previousLayerIndex);
// Sort nodes before port sorting to have sorted nodes for in-layer feedback edge dummies.
ModelOrderNodeComparator comparator = new ModelOrderNodeComparator(previousLayer,
graph.getProperty(LayeredOptions.CONSIDER_MODEL_ORDER_STRATEGY),
graph.getProperty(LayeredOptions.CONSIDER_MODEL_ORDER_LONG_EDGE_STRATEGY));
SortByInputModelProcessor.insertionSort(layer.getNodes(), comparator);
for (LNode node : layer.getNodes()) {
if (node.getProperty(LayeredOptions.PORT_CONSTRAINTS) != PortConstraints.FIXED_ORDER
&& node.getProperty(LayeredOptions.PORT_CONSTRAINTS) != PortConstraints.FIXED_POS) {
Expand All @@ -79,7 +84,7 @@ public void process(final LGraph graph, final IElkProgressMonitor progressMonito
}
}
// Sort nodes.
ModelOrderNodeComparator comparator = new ModelOrderNodeComparator(previousLayer,
comparator = new ModelOrderNodeComparator(previousLayer,
graph.getProperty(LayeredOptions.CONSIDER_MODEL_ORDER_STRATEGY),
graph.getProperty(LayeredOptions.CONSIDER_MODEL_ORDER_LONG_EDGE_STRATEGY));
SortByInputModelProcessor.insertionSort(layer.getNodes(), comparator);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,18 +116,17 @@ public int compare(final LPort originalP1, final LPort originalP2) {
// Sort nodes by their ports sides NORTH < EAST < SOUTH < WEST.
if (p1.getSide() != p2.getSide()) {
int result = new PortSideComparator().compare(p1.getSide(), p2.getSide());

if (result == -1) {
updateBiggerAndSmallerAssociations(p2, p1);
} else {
if (result > 0) {
updateBiggerAndSmallerAssociations(p1, p2);
} else {
updateBiggerAndSmallerAssociations(p2, p1);
}
return result;
}

// Sort incoming edges by sorting their ports by the order of the nodes they connect to.
if (!p1.getIncomingEdges().isEmpty() && !p2.getIncomingEdges().isEmpty()) {
if (p1.getSide() == PortSide.WEST && p2.getSide() == PortSide.WEST
if (p1.getSide() == PortSide.WEST && p2.getSide() == PortSide.WEST
|| p1.getSide() == PortSide.NORTH && p2.getSide() == PortSide.NORTH
|| p1.getSide() == PortSide.SOUTH && p2.getSide() == PortSide.SOUTH) {
// Some ports are ordered in the way around.
Expand Down Expand Up @@ -165,34 +164,49 @@ public int compare(final LPort originalP1, final LPort originalP2) {
// ___1___|
//
Layer previousLayer = p1Node.getLayer();
// if it is a SOUTH or EAST port reverse the order.
// checkReferenceLayer already updates the transitive ordering association.
int inPreviousLayer = checkReferenceLayer(previousLayer, p1Node, p2Node, p1, p2);
if (inPreviousLayer != 0) {
if (p1.getSide() == PortSide.EAST && p2.getSide() == PortSide.EAST) {
// Some ports are ordered in the way around.
// Previously this did not matter, since the north south processor did override the ordering.
inPreviousLayer = -inPreviousLayer;
}
if (inPreviousLayer > 0) {
updateBiggerAndSmallerAssociations(p1, p2);
} else {
updateBiggerAndSmallerAssociations(p1, p2);
updateBiggerAndSmallerAssociations(p2, p1);
}
return inPreviousLayer;
}
}

// Check which of the nodes connects first to the previous layer.
// checkReferenceLayer already updates the transitive ordering association.
int inPreviousLayer = checkReferenceLayer(Arrays.stream(previousLayer).collect(Collectors.toList()), p1Node, p2Node, p1, p2);
if (inPreviousLayer != 0) {
return inPreviousLayer;
if (inPreviousLayer > 0) {
updateBiggerAndSmallerAssociations(p1, p2);
return 1;
} else {
updateBiggerAndSmallerAssociations(p2, p1);
return -1;
}
}
// If both ports do not connect to the previous layer, use the port model order.
// If port order is used instead of edge order, consult it to make decisions.
// If not both ports have a model order fall back to the edge order.
if (portModelOrder) {
int result = checkPortModelOrder(p1, p2);
if (result != 0) {
if (result < 0) {
updateBiggerAndSmallerAssociations(p2, p1);
} else if (result > 0) {
if (result > 0) {
updateBiggerAndSmallerAssociations(p1, p2);
return 1;
} else {
updateBiggerAndSmallerAssociations(p2, p1);
return -1;
}
return result;
}
}
}
Expand All @@ -218,24 +232,27 @@ public int compare(final LPort originalP1, final LPort originalP2) {
int p2MO = p2TargetNode.getProperty(InternalProperties.MODEL_ORDER);
if (p1MO > p2MO) {
updateBiggerAndSmallerAssociations(p1, p2);
return 1;
} else {
updateBiggerAndSmallerAssociations(p2, p1);
return -1;
}
return Integer.compare(p1MO, p2MO);
}

// If port order is used instead of edge order, consult it to make decisions.
// If not both ports have a model order fall back to the edge order.
if (portModelOrder) {
int result = checkPortModelOrder(p1, p2);
if (result != 0) {
if (result == -1) {
updateBiggerAndSmallerAssociations(p2, p1);
} else if (result == 1) {
if (result > 0) {
updateBiggerAndSmallerAssociations(p1, p2);
return 1;
} else {
updateBiggerAndSmallerAssociations(p2, p1);
return -1;
}
return result;
}
// If one of the ports has no model order, find something else to compare them which is the edge order.
}

int p1Order = 0;
Expand All @@ -252,10 +269,11 @@ public int compare(final LPort originalP1, final LPort originalP2) {
// If both edges are reversed or not reversed, just use their model order.
if (p1Order > p2Order) {
updateBiggerAndSmallerAssociations(p1, p2);
return 1;
} else {
updateBiggerAndSmallerAssociations(p2, p1);
return -1;
}
return Integer.compare(p1Order, p2Order);
}
// Use precomputed ordering value if possible to utilize order inheritence of edges connected to a node.
// This allows to bundle edges leading to the same node, disregarding their model order.
Expand All @@ -270,10 +288,11 @@ public int compare(final LPort originalP1, final LPort originalP2) {
// If the nodes have different targets just use their order.
if (p1Order > p2Order) {
updateBiggerAndSmallerAssociations(p1, p2);
return 1;
} else {
updateBiggerAndSmallerAssociations(p2, p1);
return -1;
}
return Integer.compare(p1Order, p2Order);

}
// Sort outgoing ports before incoming ports.
Expand All @@ -290,11 +309,11 @@ public int compare(final LPort originalP1, final LPort originalP2) {
int p2MO = p2.getProperty(InternalProperties.MODEL_ORDER);
if (p1MO > p2MO) {
updateBiggerAndSmallerAssociations(p1, p2);
return 1;
} else {
updateBiggerAndSmallerAssociations(p2, p1);
return -1;
}
return Integer.compare(p1MO,
p2MO);
} else {
updateBiggerAndSmallerAssociations(p2, p1);
return -1;
Expand Down Expand Up @@ -342,7 +361,7 @@ private void updateBiggerAndSmallerAssociations(final LPort bigger, final LPort

/**
* Given a previous layer, check which of the two reference nodes of a port is the first in it.
* Updates the bigger/smaller association.
*
* @param layer The layer to check
* @param p1Node The reference node of port p1
* @param p2Node The reference node of port p2
Expand All @@ -353,14 +372,14 @@ private void updateBiggerAndSmallerAssociations(final LPort bigger, final LPort
private int checkReferenceLayer(Iterable<LNode> layer, LNode p1Node, LNode p2Node, LPort p1, LPort p2) {
for (LNode node : layer) {
if (node.equals(p1Node)) {
updateBiggerAndSmallerAssociations(p2, p1);
// If the first node is found first, it has to be above the second one and does hence have a smaller
// Model order.
return -1;
} else if (node.equals(p2Node)) {
updateBiggerAndSmallerAssociations(p1, p2);
return 1;
}
}
return 0; // Would never happen.
return 0; // Should never happen, the previous layer needs these nodes in it.
}

private class PortSideComparator implements Comparator<PortSide> {
Expand Down

0 comments on commit 291247c

Please sign in to comment.