]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryCacheBase.java
Still working for multiple readers
[simantics/platform.git] / bundles / org.simantics.db.impl / src / org / simantics / db / impl / query / QueryCacheBase.java
index e2737f891385911bdb321139dcd7b93a45ff518c..24a2dbe960be9ec03877a241ca0580f79ef4b3ab 100644 (file)
@@ -2,9 +2,11 @@ package org.simantics.db.impl.query;
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.concurrent.Semaphore;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.simantics.db.AsyncReadGraph;
+import org.simantics.db.ObjectResourceIdMap;
 import org.simantics.db.RelationInfo;
 import org.simantics.db.common.utils.Logger;
 import org.simantics.db.exception.DatabaseException;
@@ -15,6 +17,7 @@ import org.simantics.db.procedure.AsyncMultiProcedure;
 import org.simantics.db.procedure.AsyncProcedure;
 import org.simantics.db.procedure.Listener;
 import org.simantics.db.procedure.ListenerBase;
+import org.simantics.db.procedure.Procedure;
 import org.simantics.db.request.AsyncMultiRead;
 import org.simantics.db.request.AsyncRead;
 import org.simantics.db.request.ExternalRead;
@@ -38,7 +41,8 @@ public class QueryCacheBase {
        public boolean                                         collecting            = false;
 
        final protected THashMap<String, URIToResource>                      uRIToResourceMap;
-       final protected THashMap<String, NamespaceIndex>                     namespaceIndexMap;
+       //final protected THashMap<String, NamespaceIndex>                     namespaceIndexMap;
+       final protected UnaryQueryHashMap<InternalProcedure<ObjectResourceIdMap<String>>> childMapMap;
        final protected DoubleKeyQueryHashMap<IntProcedure>                     objectsMap;
        final protected DoubleKeyQueryHashMap<TripleIntProcedure>               assertedStatementsMap;
        final protected DoubleKeyQueryHashMap<IntProcedure>                     directObjectsMap;
@@ -79,7 +83,8 @@ public class QueryCacheBase {
                valueQueryMap = new UnaryQueryHashMap();
                principalTypesMap = new UnaryQueryHashMap();
                uRIToResourceMap = new THashMap<String, URIToResource>();
-               namespaceIndexMap = new THashMap<String, NamespaceIndex>();
+               //namespaceIndexMap = new THashMap<String, NamespaceIndex>();
+               childMapMap = new UnaryQueryHashMap<InternalProcedure<ObjectResourceIdMap<String>>>();
                relationInfoQueryMap = new UnaryQueryHashMap();
                typeHierarchyMap = new UnaryQueryHashMap();
                superTypesMap = new UnaryQueryHashMap();
@@ -197,9 +202,9 @@ public class QueryCacheBase {
                                        
                                        // Just for safety
                                        if(entry.isDiscarded()) return;
-                                       if(entry.isExcepted()) entry.setPending();
                                        
                                        if(used.compareAndSet(false, true)) {
+                           //entry.setPending();
                                                entry.addOrSet(parentGraph.processor, result);
                                                procedure.execute(parentGraph, result);
                                        } else {
@@ -373,12 +378,15 @@ public class QueryCacheBase {
                
        }
        
-       synchronized public ListenerEntry registerDependencies(ReadGraphImpl graph, CacheEntry child, CacheEntry parent, ListenerBase listener, Object procedure, boolean inferred) {
+       public ListenerEntry registerDependencies(ReadGraphImpl graph, CacheEntry child, CacheEntry parent, ListenerBase listener, Object procedure, boolean inferred) {
 
                if (parent != null && !inferred) {
                        try {
-                               if(!child.isImmutable(graph))
-                                       child.addParent(parent);
+                               if(!child.isImmutable(graph)) {
+                                       synchronized(child) {
+                                               child.addParent(parent);
+                                       }
+                               }
                        } catch (DatabaseException e) {
                                Logger.defaultLogError(e);
                        }
@@ -393,7 +401,7 @@ public class QueryCacheBase {
 
        }
        
-       public ListenerEntry registerListener(final CacheEntry entry, final ListenerBase base, final Object procedure) {
+       public synchronized ListenerEntry registerListener(final CacheEntry entry, final ListenerBase base, final Object procedure) {
 
                assert (entry != null);
 
@@ -510,7 +518,8 @@ public class QueryCacheBase {
                realSize += directSuperRelationsMap.size();
                realSize += principalTypesMap.size();
                realSize += uRIToResourceMap.size();
-               realSize += namespaceIndexMap.size();
+               //realSize += namespaceIndexMap.size();
+               realSize += childMapMap.size();
                
                realSize += relationInfoQueryMap.size();
                realSize += superTypesMap.size();
@@ -547,9 +556,11 @@ public class QueryCacheBase {
                for(CacheEntryBase e : uRIToResourceMap.values())
                        if(e.getLevel() <= level)
                                result.add(e);
-               for(CacheEntryBase e : namespaceIndexMap.values())
-                       if(e.getLevel() <= level)
-                               result.add(e);
+//             for(CacheEntryBase e : namespaceIndexMap.values())
+//                     if(e.getLevel() <= level)
+//                             result.add(e);
+
+               childMapMap.values(level, result);
                
                relationInfoQueryMap.values(level, result);
                superTypesMap.values(level, result);
@@ -585,7 +596,8 @@ public class QueryCacheBase {
                entries.addAll(directSuperRelationsMap.values());
                entries.addAll(principalTypesMap.values());
                entries.addAll(uRIToResourceMap.values());
-               entries.addAll(namespaceIndexMap.values());
+               //entries.addAll(namespaceIndexMap.values());
+               entries.addAll(childMapMap.values());
                entries.addAll(relationInfoQueryMap.values());
                entries.addAll(superTypesMap.values());
                entries.addAll(superRelationsMap.values());
@@ -629,7 +641,7 @@ public class QueryCacheBase {
                        try {
                                Thread.sleep(1);
                                counter++;
-                               if(counter > 1000) {
+                               if(counter > 5000) {
                                        CacheEntryBase base = ((CacheEntryBase)entry);
 //                                     if(base.created != null) {
 //                                             System.err.println("created:");
@@ -643,7 +655,9 @@ public class QueryCacheBase {
 //                                             System.err.println("ready:");
 //                                             base.ready.printStackTrace();
 //                                     }
-                                       System.err.println("asd");
+                                       new Exception("Timeout waiting for request to complete: " + entry.getOriginalRequest().toString()).printStackTrace();
+                                       throw new DatabaseException("Timeout waiting for request to complete.");
+                                       //System.err.println("asd");
                                        //base.getQuery().recompute(null, null, entry);
                                }
                        } catch (InterruptedException e) {
@@ -796,6 +810,19 @@ public class QueryCacheBase {
                
        }; 
 
+    protected static InternalProcedure<ObjectResourceIdMap<String>> emptyChildMapProcedure = new InternalProcedure<ObjectResourceIdMap<String>>() {
+
+               @Override
+               public void execute(ReadGraphImpl graph, ObjectResourceIdMap<String> i) {
+               }
+
+               @Override
+               public void exception(ReadGraphImpl graph, Throwable throwable) {
+               }
+               
+       }; 
+
+       
        
        protected static IntProcedure emptyIntProcedure = new IntProcedure() {
                
@@ -878,6 +905,7 @@ public class QueryCacheBase {
     
     protected static InternalProcedure<Integer> emptyProcedureURIToResource = emptyIntegerProcedure;
     protected static InternalProcedure<TObjectIntHashMap<String>> emptyProcedureNamespaceIndex = emptyNamespaceProcedure;
+    protected static InternalProcedure<ObjectResourceIdMap<String>> emptyProcedureChildMap = emptyChildMapProcedure;
     protected static InternalProcedure<RelationInfo> emptyProcedureRelationInfoQuery = emptyRelationInfoProcedure;
 
     protected static AsyncProcedure emptyProcedureReadEntry = emptyAsyncProcedure;
@@ -891,6 +919,7 @@ public class QueryCacheBase {
        private AsyncProcedure<T> procedure;
        private T result = null;
        private Throwable throwable = null;
+       private Semaphore s = new Semaphore(0);
        
        AsyncProcedureWrapper(AsyncProcedure<T> procedure) {
                this.procedure = procedure;
@@ -900,15 +929,22 @@ public class QueryCacheBase {
                public void execute(AsyncReadGraph graph, T result) {
                        if(procedure != null) procedure.execute(graph, result);
                        this.result = result;
+                       s.release();
                }
 
                @Override
                public void exception(AsyncReadGraph graph, Throwable throwable) {
                        if(procedure != null) procedure.exception(graph, throwable);
                        this.throwable = throwable;
+                       s.release();
                }
                
                public T get() throws DatabaseException {
+                       try {
+                               s.acquire();
+                       } catch (InterruptedException e) {
+                               e.printStackTrace();
+                       }
                        if(throwable != null) {
                                if(throwable instanceof DatabaseException) throw (DatabaseException)throwable;
                                else throw new DatabaseException(throwable);
@@ -919,6 +955,39 @@ public class QueryCacheBase {
                
     }
 
+    static class ExternalProcedureWrapper<T> implements AsyncProcedure<T> {
+        
+        private Procedure<T> procedure;
+        private T result = null;
+        private Throwable throwable = null;
+        
+        ExternalProcedureWrapper(Procedure<T> procedure) {
+            this.procedure = procedure;
+        }
+
+        @Override
+        public void execute(AsyncReadGraph graph, T result) {
+            if(procedure != null) procedure.execute(result);
+            this.result = result;
+        }
+
+        @Override
+        public void exception(AsyncReadGraph graph, Throwable throwable) {
+            if(procedure != null) procedure.exception(throwable);
+            this.throwable = throwable;
+        }
+        
+        public T get() throws DatabaseException {
+            if(throwable != null) {
+                if(throwable instanceof DatabaseException) throw (DatabaseException)throwable;
+                else throw new DatabaseException(throwable);
+            } else {
+                return result;
+            }
+        }
+        
+    }
+
     
     static class InternalProcedureWrapper<T> implements InternalProcedure<T> {
        
@@ -956,11 +1025,12 @@ public class QueryCacheBase {
     static class IntSetWrapper implements IntProcedure {
        
        private IntProcedure procedure;
-       private IntSet result = new IntSet();
+       final private IntSet result;
        private Throwable throwable = null;
        
-       IntSetWrapper(IntProcedure procedure) {
+       IntSetWrapper(ReadGraphImpl graph, IntProcedure procedure) {
                this.procedure = procedure;
+               result = new IntSet(graph.processor.querySupport);
        }
 
                @Override
@@ -1031,59 +1101,95 @@ public class QueryCacheBase {
 
     }
 
+    public static <T> T resultExternalReadEntry(ReadGraphImpl graph, ExternalRead r, CacheEntry parent, ListenerBase listener, Procedure<T> procedure) throws DatabaseException {
+        ExternalProcedureWrapper<T> wrap = new ExternalProcedureWrapper<>(procedure);
+        QueryCache.runnerExternalReadEntry(graph, r, parent, listener, wrap);
+        return wrap.get();
+    }
+
     public static <T> T resultReadEntry(ReadGraphImpl graph, Read r, CacheEntry parent, ListenerBase listener, AsyncProcedure<T> procedure) throws DatabaseException {
        AsyncProcedureWrapper<T> wrap = new AsyncProcedureWrapper<>(procedure);
-        QueryCache.runnerReadEntry(graph, r, parent, listener, wrap);
+        QueryCache.runnerReadEntry(graph, r, parent, listener, wrap, true);
+        return wrap.get();
+    }
+
+    public static <T> T resultAsyncReadEntry(ReadGraphImpl graph, AsyncRead r, CacheEntry parent, ListenerBase listener, AsyncProcedure<T> procedure) throws DatabaseException {
+       AsyncProcedureWrapper<T> wrap = new AsyncProcedureWrapper<>(procedure);
+        QueryCache.runnerAsyncReadEntry(graph, r, parent, listener, wrap, true);
         return wrap.get();
     }
 
-    public static byte[] resultValueQuery(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener, InternalProcedure<byte[]> procedure) throws DatabaseException {
-       InternalProcedureWrapper<byte[]> wrap = new InternalProcedureWrapper<>(procedure);
+    public static byte[] resultValueQuery(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener) throws DatabaseException {
+       InternalProcedureWrapper<byte[]> wrap = new InternalProcedureWrapper<>(null);
         QueryCache.runnerValueQuery(graph, r, parent, listener, wrap);
         return wrap.get();
     }
 
-    public static RelationInfo resultRelationInfoQuery(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener, InternalProcedure<RelationInfo> procedure) throws DatabaseException {
-       InternalProcedureWrapper<RelationInfo> wrap = new InternalProcedureWrapper<>(procedure);
+    public static RelationInfo resultRelationInfoQuery(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener) throws DatabaseException {
+       InternalProcedureWrapper<RelationInfo> wrap = new InternalProcedureWrapper<>(null);
         QueryCache.runnerRelationInfoQuery(graph, r, parent, listener, wrap);
         return wrap.get();
     }
 
-    public static IntSet resultSuperRelations(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener, InternalProcedure<IntSet> procedure) throws DatabaseException {
-       InternalProcedureWrapper<IntSet> wrap = new InternalProcedureWrapper<>(procedure);
+    public static IntSet resultSuperRelations(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener) throws DatabaseException {
+       InternalProcedureWrapper<IntSet> wrap = new InternalProcedureWrapper<>(null);
         QueryCache.runnerSuperRelations(graph, r, parent, listener, wrap);
         return wrap.get();
     }
 
-    public static IntSet resultSuperTypes(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener, InternalProcedure<IntSet> procedure) throws DatabaseException {
-       InternalProcedureWrapper<IntSet> wrap = new InternalProcedureWrapper<>(procedure);
+    public static IntSet resultSuperTypes(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener) throws DatabaseException {
+       InternalProcedureWrapper<IntSet> wrap = new InternalProcedureWrapper<>(null);
         QueryCache.runnerSuperTypes(graph, r, parent, listener, wrap);
         return wrap.get();
     }
     
-    public static IntSet resultTypes(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener, InternalProcedure<IntSet> procedure) throws DatabaseException {
-       InternalProcedureWrapper<IntSet> wrap = new InternalProcedureWrapper<>(procedure);
+    public static IntSet resultTypes(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener) throws DatabaseException {
+       InternalProcedureWrapper<IntSet> wrap = new InternalProcedureWrapper<>(null);
         QueryCache.runnerTypes(graph, r, parent, listener, wrap);
         return wrap.get();
     }
 
-    public static IntSet resultPredicates(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener, InternalProcedure<IntSet> procedure) throws DatabaseException {
-       InternalProcedureWrapper<IntSet> wrap = new InternalProcedureWrapper<>(procedure);
+    public static IntSet resultPredicates(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener) throws DatabaseException {
+       InternalProcedureWrapper<IntSet> wrap = new InternalProcedureWrapper<>(null);
         QueryCache.runnerPredicates(graph, r, parent, listener, wrap);
         return wrap.get();
     }
 
-    public static IntSet resultDirectPredicates(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener, InternalProcedure<IntSet> procedure) throws DatabaseException {
-       InternalProcedureWrapper<IntSet> wrap = new InternalProcedureWrapper<>(procedure);
+    public static IntSet resultDirectPredicates(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener) throws DatabaseException {
+       InternalProcedureWrapper<IntSet> wrap = new InternalProcedureWrapper<>(null);
         QueryCache.runnerDirectPredicates(graph, r, parent, listener, wrap);
         return wrap.get();
     }
 
-    public static IntArray resultAssertedStatements(ReadGraphImpl graph, int r1, int r2, CacheEntry parent, ListenerBase listener, TripleIntProcedure procedure) throws DatabaseException {
-       TripleIntProcedureWrapper wrap = new TripleIntProcedureWrapper(procedure);
+    public static IntArray resultAssertedStatements(ReadGraphImpl graph, int r1, int r2, CacheEntry parent, ListenerBase listener) throws DatabaseException {
+       TripleIntProcedureWrapper wrap = new TripleIntProcedureWrapper(null);
         QueryCache.runnerAssertedStatements(graph, r1, r2, parent, listener, wrap);
         return wrap.get();
     }
 
+    public static Integer resultURIToResource(ReadGraphImpl graph, String id, CacheEntry parent, ListenerBase listener) throws DatabaseException {
+       InternalProcedureWrapper<Integer> wrap = new InternalProcedureWrapper<Integer>(null);
+        QueryCache.runnerURIToResource(graph, id, parent, listener, wrap);
+        return wrap.get();
+    }
+
+    public static ObjectResourceIdMap<String> resultChildMap(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener) throws DatabaseException {
+       InternalProcedureWrapper<ObjectResourceIdMap<String>> wrap = new InternalProcedureWrapper<ObjectResourceIdMap<String>>(null);
+        QueryCache.runnerChildMap(graph, r, parent, listener, wrap);
+        return wrap.get();
+    }
+
+    static boolean shouldCache(QueryProcessor processor, int r) {
+       return processor.isImmutable(r);
+    }
+    
+    static boolean shouldCache(QueryProcessor processor, int r, int r2) {
+       return processor.isImmutable(r);
+    }
+
+    static boolean shouldCache(QueryProcessor processor, Object o) {
+       return false;
+    }
+    
 }