Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix always existing bug in model order port sorting. #1067

Merged
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
74b69bc
Make sure that the order of incoming ports matches the order given by
soerendomroes Aug 15, 2024
a366479
Fixed all but one case for port model order and feedback nodes.
soerendomroes Aug 16, 2024
e4b1d04
Check whether model order exists and do not sort in this case.
soerendomroes Aug 16, 2024
cf3911e
Removed comment for unnecessary backward edges below.
soerendomroes Aug 16, 2024
3b8cc6f
Do insertionsort to handle comparator errors.
soerendomroes Aug 16, 2024
f6b1dbc
Fixed typos in node comparator.
soerendomroes Aug 16, 2024
68691d8
Always use insertion sort and more small fixes.
soerendomroes Aug 16, 2024
291247c
Sort nodes before sorting ports since in-layer feedback dummies exist.
soerendomroes Aug 19, 2024
55dfd55
Found the last inconsistency in port ordering.
soerendomroes Aug 19, 2024
b2b1e82
Define all corner cases of node model order.
soerendomroes Aug 19, 2024
1af5370
Use normal sorting instead of insertion sort but keep insertion sort.
soerendomroes Aug 19, 2024
72b658b
Make sure that exchanging ports does not lead to bugs by using a scalar.
soerendomroes Aug 19, 2024
4ef8eb5
Readded second node sorting.
soerendomroes Aug 19, 2024
976c869
Added first patch of sortbyinputmodel correctness examples.
soerendomroes Aug 19, 2024
b033594
Added correctness tests with multiple nodes.
soerendomroes Aug 19, 2024
b35b534
Port model order basic concrete tests.
soerendomroes Aug 19, 2024
78539e5
Nodes have to be sorted with insertion sort.
soerendomroes Aug 19, 2024
2316c9e
Added optimization fixme to model order port comparator.
soerendomroes Aug 19, 2024
af1d590
long edge and feedback edge corner cases.
soerendomroes Aug 20, 2024
56949cf
Handle unconnected ports.
soerendomroes Aug 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.eclipse.elk.alg.layered.graph.Layer;
import org.eclipse.elk.alg.layered.options.InternalProperties;
import org.eclipse.elk.alg.layered.options.LayeredOptions;
import org.eclipse.elk.alg.layered.options.OrderingStrategy;
import org.eclipse.elk.core.alg.ILayoutProcessor;
import org.eclipse.elk.core.options.PortConstraints;
import org.eclipse.elk.core.options.PortSide;
Expand Down Expand Up @@ -169,7 +170,8 @@ public void process(final LGraph layeredGraph, final IElkProgressMonitor monitor
}

// Sort the port list if we have control over the port order
if (!node.getProperty(LayeredOptions.PORT_CONSTRAINTS).isOrderFixed()) {
if (!node.getProperty(LayeredOptions.PORT_CONSTRAINTS).isOrderFixed()
&& node.getGraph().getProperty(LayeredOptions.CONSIDER_MODEL_ORDER_STRATEGY) == OrderingStrategy.NONE) {
sortPortList(node);
}

Expand All @@ -188,6 +190,10 @@ public void process(final LGraph layeredGraph, final IElkProgressMonitor monitor
LinkedList<LPort> portList = Lists.newLinkedList();
Iterables.addAll(portList, node.getPorts(PortSide.NORTH));

if (node.getGraph().getProperty(LayeredOptions.CONSIDER_MODEL_ORDER_STRATEGY) != OrderingStrategy.NONE) {
portList = modelOrderNorthSouthInputReversing(portList, node);
}

createDummyNodes(layeredGraph, portList, northDummyNodes, southDummyNodes,
barycenterAssociates);

Expand Down Expand Up @@ -241,6 +247,10 @@ public void process(final LGraph layeredGraph, final IElkProgressMonitor monitor
portList.addFirst(port);
}

if (node.getGraph().getProperty(LayeredOptions.CONSIDER_MODEL_ORDER_STRATEGY) != OrderingStrategy.NONE) {
portList = modelOrderNorthSouthInputReversing(portList, node);
}

createDummyNodes(layeredGraph, portList, southDummyNodes, null,
barycenterAssociates);

Expand Down Expand Up @@ -358,6 +368,22 @@ private void sortPortList(final LNode node) {
}
});
}

private LinkedList<LPort> modelOrderNorthSouthInputReversing(LinkedList<LPort> portList, LNode node) {
// Reverse port list if edges are incoming edges.
LinkedList<LPort> incoming = new LinkedList<LPort>();
LinkedList<LPort> outgoing = new LinkedList<LPort>();
for (LPort port : portList) {
if (!port.getIncomingEdges().isEmpty()) {
// Incoming edge
incoming.add(port);
} else {
outgoing.add(port);
}
}
Lists.reverse(incoming).addAll(outgoing);
return incoming;
}

// /////////////////////////////////////////////////////////////////////////////
// DUMMY NODE CREATION
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.elk.alg.layered.graph.LEdge;
Expand Down Expand Up @@ -55,8 +56,16 @@ public void process(final LGraph graph, final IElkProgressMonitor progressMonito
+ graph.getProperty(LayeredOptions.CONSIDER_MODEL_ORDER_STRATEGY), 1);
int layerIndex = 0;
for (Layer layer : graph) {
// The layer.id is necessary to check whether nodes really connect to the previous layer.
// Feedback long edge dummies do might have a long-edge dummy in the same layer.
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), true);
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 @@ -65,7 +74,6 @@ public void process(final LGraph graph, final IElkProgressMonitor progressMonito
// Therefore all ports that connect to the same node should have the same
// (their minimal) model order.
// Get minimal model order for target node

Collections.sort(node.getPorts(),
new ModelOrderPortComparator(previousLayer,
graph.getProperty(LayeredOptions.CONSIDER_MODEL_ORDER_STRATEGY),
Expand All @@ -74,11 +82,12 @@ public void process(final LGraph graph, final IElkProgressMonitor progressMonito
progressMonitor.log("Node " + node + " ports: " + node.getPorts());
}
}
// Sort nodes.
Collections.sort(layer.getNodes(),
new ModelOrderNodeComparator(previousLayer,
graph.getProperty(LayeredOptions.CONSIDER_MODEL_ORDER_STRATEGY),
graph.getProperty(LayeredOptions.CONSIDER_MODEL_ORDER_LONG_EDGE_STRATEGY)));
// Sort nodes after port sorting to also sort dummy feedback nodes from the current layer correctly.
comparator = new ModelOrderNodeComparator(previousLayer,
graph.getProperty(LayeredOptions.CONSIDER_MODEL_ORDER_STRATEGY),
graph.getProperty(LayeredOptions.CONSIDER_MODEL_ORDER_LONG_EDGE_STRATEGY), false);
SortByInputModelProcessor.insertionSort(layer.getNodes(), comparator);

progressMonitor.log("Layer " + layerIndex + ": " + layer);
layerIndex++;
}
Expand Down Expand Up @@ -138,5 +147,35 @@ public static LNode getTargetNode(final LPort port) {
} while (node != null && node.getType() != NodeType.NORMAL);
return node;
}

public static void insertionSort(final List<LNode> layer,
final ModelOrderNodeComparator comparator) {
LNode temp;
for (int i = 1; i < layer.size(); i++) {
temp = layer.get(i);
int j = i;
while (j > 0 && comparator.compare(layer.get(j - 1), temp) > 0) {
layer.set(j, layer.get(j - 1));
j--;
}
layer.set(j, temp);
}
comparator.clearTransitiveOrdering();
}

public static void insertionSortPort(final List<LPort> layer,
final ModelOrderPortComparator comparator) {
LPort temp;
for (int i = 1; i < layer.size(); i++) {
temp = layer.get(i);
int j = i;
while (j > 0 && comparator.compare(layer.get(j - 1), temp) > 0) {
layer.set(j, layer.get(j - 1));
j--;
}
layer.set(j, temp);
}
comparator.clearTransitiveOrdering();
}
}

Loading