]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/PrincipalTypes.java
Multiple reader thread support for db client
[simantics/platform.git] / bundles / org.simantics.db.impl / src / org / simantics / db / impl / query / PrincipalTypes.java
index 25e2b6fe3d317e682d41ebf42f60c2f6a628a83d..298fcfd841f5df17c3ed68dd868040581093b342 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.db.impl.query;
 
-import gnu.trove.procedure.TIntProcedure;
-import gnu.trove.set.hash.TIntHashSet;
-
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.concurrent.Semaphore;
 
+import org.simantics.db.common.utils.Logger;
+import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.impl.graph.ReadGraphImpl;
-import org.simantics.db.impl.procedure.IntProcedureAdapter;
 import org.simantics.db.impl.procedure.InternalProcedure;
-import org.simantics.db.procedure.ListenerBase;
 
-final public class PrincipalTypes extends CollectionUnaryQuery<IntProcedure> {
+import gnu.trove.procedure.TIntProcedure;
+import gnu.trove.set.hash.TIntHashSet;
 
-//     public ArrayList<IntProcedure> procs = null;
+public final class PrincipalTypes extends CollectionUnaryQuery {
 
-       private PrincipalTypes(final int resource) {
+       PrincipalTypes(final int resource) {
                super(resource);
        }
 
-       final static PrincipalTypes entry(final QueryProcessor provider, final int r) {
-               return (PrincipalTypes)provider.principalTypesMap.get(r);
-       }
-
-       final static void runner(ReadGraphImpl graph, final int r, final CacheEntry parent, final ListenerBase listener, final IntProcedure procedure) {
-
-       QueryProcessor processor = graph.processor;
-               
-               PrincipalTypes entry = (PrincipalTypes)processor.principalTypesMap.get(r); 
-               if(entry == null) {
-
-                       entry = new PrincipalTypes(r);
-               entry.setPending();
-               entry.clearResult(processor.querySupport);
-               entry.putEntry(processor);
-                       
-               processor.performForEach(graph, entry, parent, listener, procedure);
-                       
-               } else {
-                       
-            if(entry.isPending()) {
-                synchronized(entry) {
-                    if(entry.isPending()) {
-                        throw new IllegalStateException();
-//                                             if(entry.procs == null) entry.procs = new ArrayList<IntProcedure>(1);
-//                                             entry.procs.add(procedure);
-//                                             processor.registerDependencies(graph, entry, parent, listener, procedure, false);
-//                                             return;
-                                       }
-                               }
-                       }
-            processor.performForEach(graph, entry, parent, listener, procedure);
-               }
-
-       }
-
-       final public static void queryEach(ReadGraphImpl graph, final int r, final QueryProcessor provider, final CacheEntry parent, final ListenerBase listener, final IntProcedure procedure) {
-
-               assert(r != 0);
-
-        if(parent == null && listener == null) {
-               PrincipalTypes.computeForEach(graph, r, null, graph.processor, procedure);
-        } else {
-               runner(graph, r, parent, listener, procedure);
-        }
-
-       }
-
-       @Override
-       public UnaryQuery<IntProcedure> getEntry(QueryProcessor provider) {
-               return provider.principalTypesMap.get(id);
-       }
-
-       @Override
-       public void putEntry(QueryProcessor provider) {
-               provider.principalTypesMap.put(id, this);
-       }
-
        @Override
        final public void removeEntry(QueryProcessor provider) {
-               provider.principalTypesMap.remove(id);
+               provider.cache.remove(this);
        }
 
-       static class Koss {
+       static class Ints {
 
                private TIntHashSet set = null;
                public int single = 0;
@@ -134,25 +73,33 @@ final public class PrincipalTypes extends CollectionUnaryQuery<IntProcedure> {
        }
 
        @Override
-       public Object computeForEach(final ReadGraphImpl procedureGraph, final QueryProcessor provider, final IntProcedure proc, final boolean store) {
-
-               return computeForEach(procedureGraph, id, this, provider, proc);
-               
+       public void compute(final ReadGraphImpl graph, final IntProcedure proc) throws DatabaseException {
+               computeForEach(graph, id, this, proc);
        }
        
-       public static Object computeForEach(final ReadGraphImpl graph, final int id, final PrincipalTypes entry, final QueryProcessor provider, final IntProcedure proc) {
+       public static Object computeForEach(final ReadGraphImpl graph, final int id, final PrincipalTypes entry, final IntProcedure procedure_) throws DatabaseException {
+
+           IntProcedure procedure = entry != null ? entry : procedure_;
+           
+           Object result = computeForEach2(graph, id, entry, procedure);
+           
+           if(entry != null) entry.performFromCache(graph, procedure_);
+           
+           return result;
+           
+       }
+           
+       public static Object computeForEach2(final ReadGraphImpl graph, final int id, final PrincipalTypes parent, final IntProcedure procedure) throws DatabaseException {
+
+           QueryProcessor provider = graph.processor;
                
                provider.querySupport.ensureLoaded(graph, id);
                assert(id != 0);
 
                int ret = provider.querySupport.getSingleInstance(id);
                if(ret > 0) {
-                       if(entry != null) {
-                               entry.add(ret);
-                               entry.finish(graph, provider);
-                       }
-                       proc.execute(graph, ret);
-                       proc.finished(graph);
+                       procedure.execute(graph, ret);
+                       procedure.finished(graph);
                        return ret;
                }
 
@@ -160,8 +107,8 @@ final public class PrincipalTypes extends CollectionUnaryQuery<IntProcedure> {
                final int inherits = provider.getInherits();
                final int subrelationOf = provider.getSubrelationOf();
 
-               final Koss indirect = new Koss();
-               final Koss material = new Koss();
+               final Ints indirect = new Ints();
+               final Ints material = new Ints();
 
                IntProcedure directProc = new IntProcedure() {
 
@@ -171,8 +118,8 @@ final public class PrincipalTypes extends CollectionUnaryQuery<IntProcedure> {
                        }
 
                        @Override
-                       public void exception(ReadGraphImpl graph, Throwable t) {
-                               proc.exception(graph, t);
+                       public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
+                               procedure.exception(graph, t);
                        }
 
                        @Override
@@ -189,8 +136,8 @@ final public class PrincipalTypes extends CollectionUnaryQuery<IntProcedure> {
                        }
 
                        @Override
-                       public void exception(ReadGraphImpl graph, Throwable t) {
-                               proc.exception(graph, t);
+                       public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
+                               procedure.exception(graph, t);
                        }
 
                        @Override
@@ -206,32 +153,34 @@ final public class PrincipalTypes extends CollectionUnaryQuery<IntProcedure> {
                if(indirect.size() == 0) {
                        int size = material.size(); 
                        if(size == 0) {
-                               if(entry != null) entry.finish(graph, provider);
-                               proc.finished(graph);
+                               procedure.finished(graph);
                                return null;
                        } else if(size == 1) {
                                int single = material.single; 
-                               if(entry != null) {
-                                       entry.add(single);
-                                       entry.finish(graph, provider);
-                               }
-                               proc.execute(graph, single);
-                               proc.finished(graph);
+                               procedure.execute(graph, single);
+                               procedure.finished(graph);
                                return single;
                        } else {
-                               addPrincipalType(graph, new TIntHashSet(4), material.toArray(), 0, provider, entry, proc);
+                               addPrincipalType(graph, new TIntHashSet(4), material.toArray(), 0, provider, parent, procedure);
                                return null;
                        }
                }
 
-//             final AtomicInteger finishes = new AtomicInteger(0);
-
                indirect.forEach(new TIntProcedure() {
 
                        int finishes = 0;
                        
                        @Override
                        public boolean execute(final int arg0) {
+                               try {
+                                       return execute0(arg0);
+                               } catch (DatabaseException e) {
+                                       Logger.defaultLogError(e);
+                               }
+                               return false;
+                       }
+                       
+                       public boolean execute0(final int arg0) throws DatabaseException {
 
                                // No self-loops!
                                if(arg0 == id) {
@@ -239,27 +188,22 @@ final public class PrincipalTypes extends CollectionUnaryQuery<IntProcedure> {
                                        if(current == indirect.size()) {
                                                int size = material.size(); 
                                                if(size == 0) {
-                                                       if(entry != null) entry.finish(graph, provider);
-                                                       proc.finished(graph);
+                                                       procedure.finished(graph);
                                                        return true;
                                                } else if(size == 1) {
                                                        int single = material.single; 
-                                                       if(entry != null) {
-                                                               entry.add(single);
-                                                               entry.finish(graph, provider);
-                                                       }
-                                                       proc.execute(graph, single);
-                                                       proc.finished(graph);
+                                                       procedure.execute(graph, single);
+                                                       procedure.finished(graph);
                                                        return true;
                                                } else {
-                                                       addPrincipalType(graph, new TIntHashSet(4), material.toArray(), 0, provider, entry, proc);
+                                                       addPrincipalType(graph, new TIntHashSet(4), material.toArray(), 0, provider, parent, procedure);
                                                        return true;
                                                }
                                        }
                                        return true;
                                }
 
-                               PrincipalTypes.queryEach(graph, arg0, provider, entry, null, new IntProcedure() {
+                               QueryCache.runnerPrincipalTypes(graph, arg0, parent, null, new IntProcedure() {
 
                                        @Override
                                        public void execute(ReadGraphImpl graph, int i) {
@@ -269,26 +213,21 @@ final public class PrincipalTypes extends CollectionUnaryQuery<IntProcedure> {
                                        }
 
                                        @Override
-                                       public void finished(ReadGraphImpl graph) {
+                                       public void finished(ReadGraphImpl graph) throws DatabaseException {
 
                                                int current = (++finishes);
                                                if(current == indirect.size()) {
                                                        int size = material.size(); 
                                                        if(size == 0) {
-                                                               if(entry != null) entry.finish(graph, provider);
-                                                               proc.finished(graph);
+                                                               procedure.finished(graph);
                                                                return;
                                                        } else if(size == 1) {
                                                                int single = material.single; 
-                                                               if(entry != null) {
-                                                                       entry.add(single);
-                                                                       entry.finish(graph, provider);
-                                                               }
-                                                               proc.execute(graph, single);
-                                                               proc.finished(graph);
+                                                               procedure.execute(graph, single);
+                                                               procedure.finished(graph);
                                                                return;
                                                        } else {
-                                                               addPrincipalType(graph, new TIntHashSet(4), material.toArray(), 0, provider, entry, proc);
+                                                               addPrincipalType(graph, new TIntHashSet(4), material.toArray(), 0, provider, parent, procedure);
                                                                return;
                                                        }
                                                }
@@ -296,8 +235,8 @@ final public class PrincipalTypes extends CollectionUnaryQuery<IntProcedure> {
                                        }
 
                                        @Override
-                                       public void exception(ReadGraphImpl graph, Throwable t) {
-                                               proc.exception(graph, t);
+                                       public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
+                                               procedure.exception(graph, t);
                                        }
 
                                });
@@ -312,16 +251,7 @@ final public class PrincipalTypes extends CollectionUnaryQuery<IntProcedure> {
 
        }
 
-       private static void finish(ReadGraphImpl graph, final TIntHashSet rejects, final int[] material, final PrincipalTypes entry, final QueryProcessor provider, final IntProcedure proc) {
-
-               if(entry != null) {
-                       for(int i : material) {
-                               if(!rejects.contains(i)) {
-                                       entry.add(i);
-                               }
-                       }
-                       entry.finish(graph, provider);
-               }
+       private static void finish(ReadGraphImpl graph, final TIntHashSet rejects, final int[] material, final IntProcedure proc) throws DatabaseException {
 
                for(int i : material) {
                        if(!rejects.contains(i)) {
@@ -335,29 +265,28 @@ final public class PrincipalTypes extends CollectionUnaryQuery<IntProcedure> {
 
        }
 
-       private static void addPrincipalType(final ReadGraphImpl graph, final TIntHashSet rejects, final int[] material, int index, final QueryProcessor provider, final PrincipalTypes entry, final IntProcedure proc) {
-
-               //        if((counter++ % 500) == 0) System.out.println("PT " + counter + " mat = " + material.length);
+       private static void addPrincipalType(final ReadGraphImpl graph, final TIntHashSet rejects, final int[] material, int index, final QueryProcessor provider, final PrincipalTypes parent, final IntProcedure proc) throws DatabaseException {
 
                if(index == material.length) { 
-                       finish(graph, rejects, material, entry, provider, proc);
+                       finish(graph, rejects, material, proc);
                        return;
                }
 
                int type = material[index++];
                while(rejects.contains(type)) {
                        if(index == material.length) { 
-                               finish(graph, rejects, material, entry, provider, proc);
+                               finish(graph, rejects, material, proc);
                                return;
                        }
                        type = material[index++];
                }
+               
                final int nextIndex = index;
 
-               SuperTypes.queryEach(graph, type, provider, entry, null, new InternalProcedure<IntSet>() {
+               QueryCache.runnerSuperTypes(graph, type, parent, null, new InternalProcedure<IntSet>() {
 
                        @Override
-                       public void execute(ReadGraphImpl graph, IntSet supers) {
+                       public void execute(ReadGraphImpl graph, IntSet supers) throws DatabaseException {
 
                                synchronized(rejects) {
 
@@ -373,12 +302,12 @@ final public class PrincipalTypes extends CollectionUnaryQuery<IntProcedure> {
 
                                }
 
-                               addPrincipalType(graph, rejects, material, nextIndex, provider, entry, proc);
+                               addPrincipalType(graph, rejects, material, nextIndex, provider, parent, proc);
 
                        }
 
                        @Override
-                       public void exception(ReadGraphImpl graph, Throwable t) {
+                       public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
                                proc.exception(graph, t);
                        }
 
@@ -390,104 +319,9 @@ final public class PrincipalTypes extends CollectionUnaryQuery<IntProcedure> {
        public String toString() {
                return "PrincipalTypes[" + id + "]";
        }
-
-       final private void add(int val) {
-               assert(isPending());
-               IntArray v = (IntArray)getResult();
-               v.add(val);
-       }
-
-       final private void finish(ReadGraphImpl graph, QueryProcessor provider) {
-
-               assert(isPending());
-
-//             ArrayList<IntProcedure> p = null;
-
-               synchronized(this) {
-
-                       setReady();
-//                     p = procs;
-//                     procs = null;
-
-               }
-
-//             if(p != null) {
-//
-//                     IntArray v = (IntArray)getResult();
-//                     if(v != null) {
-//                             if(v.data == null) {
-//                                     if(v.sizeOrData != IntArray.NO_DATA) {
-//                                             for(IntProcedure proc : p) proc.execute(graph, v.sizeOrData);
-//                                     }
-//                             } else {
-//                                     for(IntProcedure proc : p) {
-//                                             for(int i = 0;i < v.sizeOrData ; i++) proc.execute(graph, v.data[i]);
-//                                     }
-//                             }
-//                     }
-//
-//                     for(IntProcedure proc : p) proc.finished(graph);
-//
-//             }
-
-
-       }
-
-       @Override
-       public Object performFromCache(ReadGraphImpl graph, QueryProcessor provider, final IntProcedure procedure) {
-
-               assert(isReady());
-
-       if(handleException(graph, procedure)) return EXCEPTED;
-               
-               final IntArray value = (IntArray)getResult();
-               if(value.data == null) {
-                       if(value.sizeOrData != IntArray.NO_DATA) procedure.execute(graph, value.sizeOrData);
-               } else {
-                       for(int i = 0;i < value.sizeOrData ; i++) procedure.execute(graph, value.data[i]);
-               }
-
-               procedure.finished(graph);
-               
-               return getResult();
-
-       }
-
-       @Override
-       public void recompute(ReadGraphImpl graph, QueryProcessor provider) {
-
-               final Semaphore s = new Semaphore(0);
-
-               computeForEach(graph, provider, new IntProcedureAdapter() {
-
-                       @Override
-                       public void finished(ReadGraphImpl graph) {
-                               s.release();
-                       }
-
-                       @Override
-                       public void exception(ReadGraphImpl graph, Throwable t) {
-                               s.release();
-                               new Error("Error in recompute.", t).printStackTrace();
-                       }
-
-               }, true);
-
-       while(!s.tryAcquire()) {
-               provider.resume(graph);
-       }
-
-       }
-
-
-    @Override
-    boolean isImmutable(ReadGraphImpl graph) {
-       return graph.processor.isImmutable(id);
-    }
     
     @Override
-    protected void fillImpliedParents(QueryProcessor processor, ArrayList<CacheEntry> result) {
-//             for(Objects o : Objects.entries(processor, id)) result.add(o);
+    protected void fillImpliedParents(QueryProcessor processor, ArrayList<CacheEntry<?>> result) {
     }
 
 }