]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/DiagramContentRequest.java
Multiple reader thread support for db client
[simantics/platform.git] / bundles / org.simantics.diagram / src / org / simantics / diagram / adapter / DiagramContentRequest.java
index 56063b990f71e771180a75acfd06db99b09877fa..9be72d29f53fabb6e8d2d906618a1fb0a2fb8f9f 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 Association for Decentralized Information Management
  * in Industry THTH ry.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  *******************************************************************************/
 package org.simantics.diagram.adapter;
 
-import gnu.trove.list.array.TIntArrayList;
-import gnu.trove.map.hash.THashMap;
-import gnu.trove.procedure.TIntProcedure;
-import gnu.trove.set.hash.THashSet;
-
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicInteger;
 
-import org.simantics.db.AsyncReadGraph;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.Resource;
 import org.simantics.db.common.procedure.adapter.ProcedureAdapter;
+import org.simantics.db.common.utils.OrderedSetUtils;
 import org.simantics.db.exception.DatabaseException;
-import org.simantics.db.procedure.AsyncMultiProcedure;
-import org.simantics.db.procedure.AsyncProcedure;
+import org.simantics.db.request.AsyncRead;
 import org.simantics.diagram.content.ConnectionPartData;
 import org.simantics.diagram.content.ConnectionPartRequest;
 import org.simantics.diagram.content.DiagramContents;
@@ -37,6 +32,11 @@ import org.simantics.diagram.stubs.DiagramResource;
 import org.simantics.diagram.synchronization.ErrorHandler;
 import org.simantics.g2d.canvas.ICanvasContext;
 
+import gnu.trove.list.array.TIntArrayList;
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.procedure.TIntProcedure;
+import gnu.trove.set.hash.THashSet;
+
 /**
  * @author Tuukka Lehtonen
  */
@@ -54,92 +54,91 @@ public class DiagramContentRequest extends BaseRequest<Resource, DiagramContents
     public DiagramContents perform(ReadGraph g) throws DatabaseException {
 
         final DiagramResource DIA = DiagramResource.getInstance(g);
-        final DiagramContents result = new DiagramContents();
-
-        result.elements =   new ArrayList<Resource>(previousElementCount);
-        result.nodeSet = new THashSet<Resource>();
-        result.connectionSet = new THashSet<Resource>();
-        result.connectionSegments = new THashSet<EdgeResource>();
-        result.branchPoints = new THashSet<Resource>();
-        result.routeGraphConnectionSet = new THashSet<Resource>();
-        result.routeLinks = new THashSet<EdgeResource>();
-        result.routeLines = new THashSet<Resource>();
-        result.routePoints = new THashSet<Resource>();
-
-        result.partToConnection = new THashMap<Object, Resource>();
 
         // These help loading result.elements in the correct order.
         final AtomicInteger index = new AtomicInteger();
         final TIntArrayList unrecognizedElementIndices = new TIntArrayList();
 
-        g.forOrderedSet(data, new AsyncMultiProcedure<Resource>() {
+        Collection<Resource> components = OrderedSetUtils.toList(g, data);
+        DiagramContents res = g.syncRequest((AsyncRead<DiagramContents>)(graph, procedure) -> {
 
-            @Override
-            public void execute(AsyncReadGraph graph, final Resource component) {
+            DiagramContents result = new DiagramContents();
+            procedure.execute(graph, result);
+
+            result.elements =   new ArrayList<Resource>(previousElementCount);
+            result.nodeSet = new THashSet<Resource>();
+            result.connectionSet = new THashSet<Resource>();
+            result.connectionSegments = new THashSet<EdgeResource>();
+            result.branchPoints = new THashSet<Resource>();
+            result.routeGraphConnectionSet = new THashSet<Resource>();
+            result.routeLinks = new THashSet<EdgeResource>();
+            result.routeLines = new THashSet<Resource>();
+            result.routePoints = new THashSet<Resource>();
+
+            result.partToConnection = new THashMap<Object, Resource>();
+
+            for (Resource component : components) {
 
                 // Must add the elements to the result set here in order to
                 // keep their order the same as in the ordered set.
                 final int elementIndex = index.getAndIncrement();
                 result.elements.add(component);
 
-                graph.forTypes(component, new AsyncProcedure<Set<Resource>>() {
+                graph.forTypes(component, new ProcedureAdapter<Set<Resource>>() {
 
                     @Override
-                    public void exception(AsyncReadGraph graph, Throwable t) {
-                        if (errorHandler != null)
-                            errorHandler.error(t.getMessage(), t);
-                    }
+                    public void execute(Set<Resource> types) {
 
-                    @Override
-                    public void execute(AsyncReadGraph graph, Set<Resource> types) {
                         if (types.contains(DIA.Connection)) {
                             if (types.contains(DIA.RouteGraphConnection)) {
-                                graph.asyncRequest(new RouteGraphConnectionPartRequest(errorHandler, DIA, component),
+                                graph.asyncRequest(
+                                        new RouteGraphConnectionPartRequest(errorHandler, DIA, component),
                                         new ProcedureAdapter<RouteGraphConnectionPartData>() {
-                                    @Override
-                                    public void execute(RouteGraphConnectionPartData partData) {
-                                        synchronized (result) {
-                                            for (EdgeResource link : partData.links) {
-                                                result.routeLinks.add(link);
-                                                result.partToConnection.put(link, component);
-                                                result.connectionToParts.add(component, link);
-                                            }
-                                            for (Resource line : partData.routeLines) {
-                                                result.routeLines.add(line);
-                                                result.connectionToParts.add(component, line);
-                                                result.partToConnection.put(line, component);
-                                            }
-                                            for (Resource point : partData.routePoints) {
-                                                result.routePoints.add(point);
-                                                result.connectionToParts.add(component, point);
-                                                result.partToConnection.put(point, component);
+                                            @Override
+                                            public void execute(RouteGraphConnectionPartData partData) {
+                                                synchronized (result) {
+                                                    for (EdgeResource link : partData.links) {
+                                                        result.routeLinks.add(link);
+                                                        result.partToConnection.put(link, component);
+                                                        result.connectionToParts.add(component, link);
+                                                    }
+                                                    for (Resource line : partData.routeLines) {
+                                                        result.routeLines.add(line);
+                                                        result.connectionToParts.add(component, line);
+                                                        result.partToConnection.put(line, component);
+                                                    }
+                                                    for (Resource point : partData.routePoints) {
+                                                        result.routePoints.add(point);
+                                                        result.connectionToParts.add(component, point);
+                                                        result.partToConnection.put(point, component);
+                                                    }
+                                                }
                                             }
-                                        }
-                                    }
-                                });
+                                        });
 
                                 synchronized (result.routeGraphConnectionSet) {
                                     result.routeGraphConnectionSet.add(component);
                                 }
                             } else {
-                                graph.asyncRequest(new ConnectionPartRequest(errorHandler, DIA, component),
+                                graph.asyncRequest(
+                                        new ConnectionPartRequest(errorHandler, DIA, component),
                                         new ProcedureAdapter<ConnectionPartData>() {
-                                    @Override
-                                    public void execute(ConnectionPartData partData) {
-                                        synchronized (result) {
-                                            for (EdgeResource er : partData.edges) {
-                                                result.connectionSegments.add(er);
-                                                result.partToConnection.put(er, component);
-                                                result.connectionToParts.add(component, er);
+                                            @Override
+                                            public void execute(ConnectionPartData partData) {
+                                                synchronized (result) {
+                                                    for (EdgeResource er : partData.edges) {
+                                                        result.connectionSegments.add(er);
+                                                        result.partToConnection.put(er, component);
+                                                        result.connectionToParts.add(component, er);
+                                                    }
+                                                    for (Resource bp : partData.branchPoints) {
+                                                        result.branchPoints.add(bp);
+                                                        result.connectionToParts.add(component, bp);
+                                                        result.partToConnection.put(bp, component);
+                                                    }
+                                                }
                                             }
-                                            for (Resource bp : partData.branchPoints) {
-                                                result.branchPoints.add(bp);
-                                                result.connectionToParts.add(component, bp);
-                                                result.partToConnection.put(bp, component);
-                                            }
-                                        }
-                                    }
-                                });
+                                        });
 
                                 synchronized (result.connectionSet) {
                                     result.connectionSet.add(component);
@@ -159,36 +158,25 @@ public class DiagramContentRequest extends BaseRequest<Resource, DiagramContents
                             }
                         }
                     }
-
-                });
-
-            }
-
-            @Override
-            public void finished(AsyncReadGraph graph) {
-                // Remove elements that were not recognized in descending order.
-                unrecognizedElementIndices.sort();
-                unrecognizedElementIndices.forEachDescending(new TIntProcedure() {
-                    @Override
-                    public boolean execute(int index) {
-                        result.elements.remove(index);
-                        return true;
-                    }
                 });
-
-                // Help successive request executions by remembering the previous
-                // element count. This will relieve some ArrayList reallocation
-                // strain down the road.
-                previousElementCount = result.elements.size();
             }
+        });
 
+        // Remove elements that were not recognized in descending order.
+        unrecognizedElementIndices.sort();
+        unrecognizedElementIndices.forEachDescending(new TIntProcedure() {
             @Override
-            public void exception(AsyncReadGraph graph, Throwable t) {
-                if (errorHandler != null)
-                    errorHandler.error(t.getMessage(), t);
+            public boolean execute(int index) {
+                res.elements.remove(index);
+                return true;
             }
         });
 
-        return result;
+        // Help successive request executions by remembering the previous
+        // element count. This will relieve some ArrayList reallocation
+        // strain down the road.
+        previousElementCount = res.elements.size();
+
+        return res;
     }
 }
\ No newline at end of file