]> gerrit.simantics Code Review - simantics/platform.git/commitdiff
Improved element reordering performance 87/4087/1
authorJussi Koskela <jussi.koskela@semantum.fi>
Thu, 2 Apr 2020 11:01:04 +0000 (14:01 +0300)
committerJussi Koskela <jussi.koskela@semantum.fi>
Thu, 2 Apr 2020 11:01:04 +0000 (14:01 +0300)
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

bundles/org.simantics.db.common/src/org/simantics/db/common/utils/OrderedSetUtils.java
bundles/org.simantics.diagram/src/org/simantics/diagram/synchronization/graph/ElementReorder.java

index 143d3e443099f31c703503dfea77b1da7ea115f1..8e8171f85273e460bdf519df9eab706ba395b539 100644 (file)
@@ -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<Resource> 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.
      */
index b0146cc21bf7ad2b7be6b6b7e3a9bb0516e00aeb..e0d757417dc83250ba9f62702499bdf8334d9090 100644 (file)
@@ -55,9 +55,7 @@ public class ElementReorder extends ModificationAdapter {
         List<Resource> graphOrder = OrderedSetUtils.toList(g, l);
         Set<Resource> graphContents = new HashSet<Resource>(graphOrder);
 
-        List<Resource> diagramOrder = new ArrayList<Resource>(order.size());
-        Map<Resource, Integer> diagramOrderIndex = new HashMap<Resource, Integer>(order.size());
-        int i = 0;
+        List<Resource> 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<Resource> added = new HashSet<Resource>(newGraphOrder);
+            for (Resource r : graphOrder) {
+                if (!added.contains(r)) {
+                    newGraphOrder.add(r);
                 }
             }
         }
+
+        OrderedSetUtils.reorder(g, l, newGraphOrder);
     }
 
 }