]> gerrit.simantics Code Review - simantics/interop.git/blobdiff - org.simantics.interop.update/src/org/simantics/interop/update/model/UpdateOperations.java
Process changes in smaller chunks
[simantics/interop.git] / org.simantics.interop.update / src / org / simantics / interop / update / model / UpdateOperations.java
index e24e0cba8a92653485eec00c67085041e53c0cb6..c8f4f1d6727fcc2e46f3a9ea6c97a52245d9cb8a 100644 (file)
@@ -6,10 +6,15 @@ import java.util.List;
 import java.util.Map;
 import java.util.Stack;
 
+import org.eclipse.core.runtime.IProgressMonitor;
 import org.simantics.db.ReadGraph;
 import org.simantics.db.Resource;
+import org.simantics.db.Session;
 import org.simantics.db.Statement;
+import org.simantics.db.VirtualGraph;
 import org.simantics.db.WriteGraph;
+import org.simantics.db.common.request.ReadRequest;
+import org.simantics.db.common.request.WriteRequest;
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.interop.test.GraphChanges;
 
@@ -24,6 +29,7 @@ public abstract  class UpdateOperations {
        private Map<Resource, UpdateOp> resourceMap = new HashMap<Resource, UpdateOp>();
        private Map<Statement, UpdateOp> statementMap = new HashMap<Statement, UpdateOp>();
        private GraphChanges changes;
+       private int chunkSize = -1;
        
        public UpdateOperations(GraphChanges changes) {
                this.changes = changes; 
@@ -37,16 +43,101 @@ public abstract  class UpdateOperations {
                return statementMap.get(s);
        }
        
-       public void applyAll(WriteGraph g) throws DatabaseException {
+       public int getChunkSize() {
+               return chunkSize;
+       }
+       
+       public void setChunkSize(int chunkSize) {
+               this.chunkSize = chunkSize;
+       }
+       
+       /**
+        * Applies all changes.
+        * 
+        * @param graph
+        * @throws DatabaseException
+        */
+       public void applyAll(WriteGraph graph) throws DatabaseException {
+               List<UpdateOp> list = operations;
+               apply(graph, list);
+       }
+
+       /**
+        * Applies selected changes.
+        * @param graph
+        * @throws DatabaseException
+        */
+       public void applySelected(WriteGraph graph) throws DatabaseException {
+               List<UpdateOp> list = new ArrayList<UpdateOp>();
                for (UpdateOp op : operations) {
-                       apply(g, op);
+                       if (op.selected())
+                               list.add(op);
                }
+               apply(graph, list);
+       }
+       
+       /**
+        * Applies all changes with chunked DB writes.
+        * 
+        * @param session
+        * @throws DatabaseException
+        */
+       public void applyAll(Session session, VirtualGraph vg) throws DatabaseException {
+               List<UpdateOp> list = operations;
+               apply(session, list, vg);
        }
 
-       public void applySelected(WriteGraph g) throws DatabaseException {
+       /**
+        * Applies selected changes with chunked DB writes.
+        * 
+        * @param session
+        * @throws DatabaseException
+        */
+       public void applySelected(Session session, VirtualGraph vg) throws DatabaseException {
+               List<UpdateOp> list = new ArrayList<UpdateOp>();
                for (UpdateOp op : operations) {
                        if (op.selected())
-                               apply(g, op);
+                               list.add(op);
+               }
+               apply(session, list, vg);
+       }
+       
+       protected void apply(WriteGraph graph, List<UpdateOp> list) throws DatabaseException {
+               for (UpdateOp op : list) {
+                       apply(graph, op);
+               }
+       }
+       
+       protected void apply(Session session, List<UpdateOp> list, VirtualGraph vg) throws DatabaseException {
+               if (getChunkSize() > 0) {
+                       for (int s = 0; s < list.size(); ) {
+                               int e = s + getChunkSize();
+                               if (e > list.size())
+                                       e = list.size();
+                               List<UpdateOp> subList = list.subList(s, e);
+                               session.syncRequest(new WriteRequest(vg) {
+                                       
+                                       @Override
+                                       public void perform(WriteGraph graph) throws DatabaseException {
+                                               
+                                               for (UpdateOp op : subList) {
+                                                       apply(graph, op);
+                                               }
+                                       }
+                               });
+                               s = e;
+                       }
+               } else {
+                       session.syncRequest(new WriteRequest(vg) {
+                               
+                               @Override
+                               public void perform(WriteGraph graph) throws DatabaseException {
+                                       
+                                       for (UpdateOp op : list) {
+                                               apply(graph, op);
+                                       }
+                               }
+                       });
                }
        }
        
@@ -57,6 +148,14 @@ public abstract  class UpdateOperations {
        public GraphChanges getChanges() {
                return changes;
        }
+       
+       public Map<Resource, UpdateOp> getResourceMap() {
+               return resourceMap;
+       }
+       
+       public Map<Statement, UpdateOp> getStatementMap() {
+               return statementMap;
+       }
 
        private void apply(WriteGraph g, UpdateOp op) throws DatabaseException {
                Stack<UpdateOp> stack = new Stack<UpdateOp>();
@@ -71,16 +170,16 @@ public abstract  class UpdateOperations {
                        return;
                }
                stack.push(op);
-               if (op.requiresParentOps()) {
-                       for (UpdateOp pop : op.getParentOps())
-                               if (!pop.applied())
-                                       _apply(g, stack, pop);
-               
-               if (op.requiresSubOps()) {
-                       for (UpdateOp sop : op.getSubOps())
-                               if (!sop.applied())
-                                       _apply(g, stack, sop);
-               }
+               for (UpdateOp pop : op.getParentOps())
+                   if (op.requiresOp(pop)) {
+                if (!pop.applied())
+                    _apply(g, stack, pop);
+        } 
+               for (UpdateOp sop : op.getSubOps())
+                   if (op.requiresOp(sop)) {
+                if (!sop.applied())
+                    _apply(g, stack, sop);
+        }
                stack.pop();
                op.apply(g);
        }
@@ -120,6 +219,21 @@ public abstract  class UpdateOperations {
 
        public abstract void populate(ReadGraph g) throws DatabaseException;
        
+       /**
+        * Secondary populate method. Override this for chunked DB operations.  
+        * @param session
+        * @throws DatabaseException
+        */
+       public void populate(Session session, IProgressMonitor monitor) throws DatabaseException {
+               session.syncRequest(new ReadRequest() {
+                       
+                       @Override
+                       public void run(ReadGraph graph) throws DatabaseException {
+                               populate(graph);
+                       }
+               });
+       }
+       
        protected boolean compares(Resource r1, Resource r2) {
                if (r1.equals(r2))
                        return true;