From: Jussi Koskela Date: Thu, 2 Apr 2020 11:01:04 +0000 (+0300) Subject: Improved element reordering performance X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=commitdiff_plain;h=99174cb4476954c91687ff5625227e91bdee9e67 Improved element reordering performance Performance was especially poor when moving element from top to bottom as it caused changes all elements in the ordered set. gitlab #508 Change-Id: I140bf8ad552f06477751842f6e3da9e0d294e247 --- diff --git a/bundles/org.simantics.db.common/src/org/simantics/db/common/utils/OrderedSetUtils.java b/bundles/org.simantics.db.common/src/org/simantics/db/common/utils/OrderedSetUtils.java index 143d3e443..8e8171f85 100644 --- a/bundles/org.simantics.db.common/src/org/simantics/db/common/utils/OrderedSetUtils.java +++ b/bundles/org.simantics.db.common/src/org/simantics/db/common/utils/OrderedSetUtils.java @@ -220,6 +220,27 @@ public class OrderedSetUtils { } } + /** + * Reorders elements with a minimum number of writes. The set of elements must remain the same. + */ + public static void reorder(WriteGraph g, Resource l, Iterable order) throws DatabaseException { + Resource newPrev = l; + for (Resource r : order) { + Resource prev = OrderedSetUtils.prev(g, l, r); + if (!prev.equals(newPrev)) { + g.deny(prev, l, r); + g.claim(newPrev, l, r); + } + newPrev = r; + } + Resource newLast = newPrev; + Resource last = OrderedSetUtils.prev(g, l, l); + if (!last.equals(newLast)) { + g.deny(last, l, l); + g.claim(newLast, l, l); + } + } + /** * Converts ordered set into a list. */ diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/synchronization/graph/ElementReorder.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/synchronization/graph/ElementReorder.java index b0146cc21..e0d757417 100644 --- a/bundles/org.simantics.diagram/src/org/simantics/diagram/synchronization/graph/ElementReorder.java +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/synchronization/graph/ElementReorder.java @@ -55,9 +55,7 @@ public class ElementReorder extends ModificationAdapter { List graphOrder = OrderedSetUtils.toList(g, l); Set graphContents = new HashSet(graphOrder); - List diagramOrder = new ArrayList(order.size()); - Map diagramOrderIndex = new HashMap(order.size()); - int i = 0; + List newGraphOrder = new ArrayList<>(); for (IElement e : order) { Object obj = ElementUtils.getObject(e); if (obj instanceof Resource) { @@ -66,41 +64,22 @@ public class ElementReorder extends ModificationAdapter { // This prevents errors in situations where #order contains // elements that no longer exist in the diagram. if (graphContents.contains(r)) { - diagramOrder.add(r); - diagramOrderIndex.put(r, Integer.valueOf(i)); - ++i; + newGraphOrder.add(r); } } } - // Reorder the backend list according to diagramOrder - i = 0; - for (Resource r : graphOrder) { - Integer di = diagramOrderIndex.get(r); - if (di != null) { - int targetIndex = di; - int graphIndex = i++; - if (graphIndex != targetIndex) { - // Check if the predecessor of r is already correct. - // If it is, we don't have to do anything for r. - Resource graphPrev = OrderedSetUtils.prev(g, l, r); - Resource after = null; - if (targetIndex == 0) { - after = l; - if (l.equals(graphPrev)) - continue; - } else { - after = diagramOrder.get(targetIndex - 1); - if (after.equals(graphPrev)) - continue; - } - - // r needs to be repositioned. - OrderedSetUtils.remove(g, l, r); - OrderedSetUtils.addAfter(g, l, after, r); + // Safety measure for possible missing elements + if (graphOrder.size() != newGraphOrder.size()) { + Set added = new HashSet(newGraphOrder); + for (Resource r : graphOrder) { + if (!added.contains(r)) { + newGraphOrder.add(r); } } } + + OrderedSetUtils.reorder(g, l, newGraphOrder); } }