]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/QuerySupportImpl.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.db.procore / src / fi / vtt / simantics / procore / internal / QuerySupportImpl.java
diff --git a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/QuerySupportImpl.java b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/QuerySupportImpl.java
new file mode 100644 (file)
index 0000000..c2af012
--- /dev/null
@@ -0,0 +1,1745 @@
+package fi.vtt.simantics.procore.internal;\r
+\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
+import java.io.ByteArrayInputStream;\r
+import java.io.InputStream;\r
+import java.util.Collection;\r
+\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.Session;\r
+import org.simantics.db.Statement;\r
+import org.simantics.db.VirtualGraph;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.StandardStatement;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.common.utils.Logger;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.exception.InvalidResourceReferenceException;\r
+import org.simantics.db.exception.ResourceNotFoundException;\r
+import org.simantics.db.impl.ClusterI;\r
+import org.simantics.db.impl.ClusterSupport;\r
+import org.simantics.db.impl.ForEachObjectContextProcedure;\r
+import org.simantics.db.impl.ForEachObjectProcedure;\r
+import org.simantics.db.impl.ResourceImpl;\r
+import org.simantics.db.impl.TransientGraph;\r
+import org.simantics.db.impl.VirtualGraphImpl;\r
+import org.simantics.db.impl.graph.ReadGraphImpl;\r
+import org.simantics.db.impl.query.IntProcedure;\r
+import org.simantics.db.impl.query.QueryProcessor;\r
+import org.simantics.db.impl.query.QuerySupport;\r
+import org.simantics.db.impl.support.BuiltinSupport;\r
+import org.simantics.db.impl.support.ResourceSupport;\r
+import org.simantics.db.procore.cluster.ClusterImpl;\r
+import org.simantics.db.procore.cluster.ClusterSmall;\r
+import org.simantics.db.service.SerialisationSupport;\r
+import org.simantics.utils.DataContainer;\r
+import org.simantics.utils.datastructures.Callback;\r
+\r
+public class QuerySupportImpl implements QuerySupport {\r
+       \r
+       final SessionImplSocket session;\r
+       final State state;\r
+       final ClusterTable clusterTable;\r
+       final BuiltinSupport builtinSupport;\r
+       final ClusterSupport clusterSupport;\r
+       final ResourceSupport resourceSupport;\r
+       final SerialisationSupport serializationSupport;\r
+       final VirtualGraphServerSupportImpl virtualGraphServerSupport;\r
+       final GraphSession graphSession;\r
+       final SessionRequestManager syncThreads;\r
+       final int root;\r
+\r
+    private boolean pendingPrimitives = false;\r
+       \r
+       QuerySupportImpl(SessionImplSocket session, ClusterSupport clusterSupport, SerialisationSupport serializationSupport, SessionRequestManager syncThreads) {\r
+               this.session = session;\r
+               this.state = session.state;\r
+               this.clusterTable = session.clusterTable;\r
+               this.resourceSupport = session.resourceSupport;\r
+               this.virtualGraphServerSupport = session.virtualGraphServerSupport;\r
+               this.graphSession = session.graphSession;\r
+               this.builtinSupport = session.builtinSupport;\r
+               this.clusterSupport = clusterSupport;\r
+               this.serializationSupport = serializationSupport;\r
+               this.syncThreads = syncThreads;\r
+               this.root = getBuiltin("http:/");\r
+               assert(this.session != null);\r
+               assert(this.state != null);\r
+               assert(this.clusterTable != null);\r
+               assert(this.resourceSupport != null);\r
+               assert(this.virtualGraphServerSupport != null);\r
+               assert(this.graphSession != null);\r
+               assert(this.builtinSupport != null);\r
+               assert(this.clusterSupport != null);\r
+               assert(this.serializationSupport != null);\r
+               assert(this.syncThreads != null);\r
+       }\r
+\r
+       @Override\r
+       public ResourceSupport getSupport() {\r
+               return resourceSupport;\r
+       }\r
+       \r
+    @Override\r
+    public Statement getStatement(int s, int p, int o) {\r
+        return getStatement(null, s, p, o);\r
+    }\r
+\r
+    @Override\r
+    public Statement getStatement(ReadGraphImpl graph, int s, int p, int o) {\r
+        Resource sr = getResource(s);\r
+        Resource pr = getResource(p);\r
+        Resource or = getResource(o);\r
+        return new StandardStatement(sr, pr, or);\r
+    }\r
+\r
+       @Override\r
+       public Session getSession() {\r
+               return session;\r
+       }\r
+\r
+    @Override\r
+    public long getClusterId(int id) {\r
+       ClusterI cluster = clusterTable.getClusterByResourceKey(id);\r
+       if(cluster == null) return 0;\r
+       return cluster.getClusterId();\r
+    }\r
+    \r
+    @Override\r
+    public boolean isImmutable(int id) {\r
+       // Virtuals are mutable\r
+       if(id < 0) return false;\r
+       // Root library is mutable\r
+       if(root == id) return false;\r
+       // Anything goes in service mode\r
+       if(session.serviceMode > 0) return false;\r
+       return clusterTable.isImmutable(id);\r
+    }\r
+\r
+    @Override\r
+    public int getId(Resource resource) {\r
+        if (resource instanceof ResourceImpl)\r
+            return ((ResourceImpl)resource).id;\r
+        return 0;\r
+    }\r
+\r
+       @Override\r
+       public Resource getResource(int id) {\r
+               try {\r
+                       return serializationSupport.getResource(id);\r
+               } catch (DatabaseException e) {\r
+                       e.printStackTrace();\r
+               }\r
+               return null;\r
+       }\r
+\r
+       @Override\r
+    public boolean resume(ReadGraphImpl graph) {\r
+               \r
+               return syncThreads.session.queryProvider2.resume(graph);\r
+               \r
+    }\r
+\r
+//    @Override\r
+//    final public void sync(int resumeThread, final SessionRunnable runnable) {\r
+//     \r
+//     syncThreads.session.queryProvider2.schedule(Integer.MIN_VALUE, new SessionTask(resumeThread) {\r
+//\r
+//                     @Override\r
+//                     public void run(int thread) {\r
+//                             runnable.run(thread);\r
+//                     }\r
+//             \r
+//     });\r
+//     \r
+//    }\r
+\r
+//    @Override\r
+//    final public int nextSyncThread() {\r
+//     throw new Error();\r
+////        return syncThreads.nextThread();\r
+//    }\r
+\r
+       @Override\r
+    public void dirtyPrimitives() {\r
+        session.dirtyPrimitives = true;\r
+        if(state.getWriteCount() == 0 && !pendingPrimitives) {\r
+            pendingPrimitives = true;\r
+            session.asyncRequest(new WriteRequest() {\r
+\r
+                @Override\r
+                public void perform(WriteGraph graph) throws DatabaseException {\r
+                    pendingPrimitives = false;\r
+                }\r
+                \r
+            });\r
+        }\r
+    }\r
+\r
+    @Override\r
+    @Deprecated\r
+    final public void aboutToRead() {\r
+    }\r
+\r
+//    @Override\r
+//    public void increaseReferenceCount(int callerThread, int subject) {\r
+//        if (subject < 0)\r
+//            return;\r
+//        ClusterI proxy = clusterTable.getClusterByResourceKey(subject);\r
+//        if (null == proxy)\r
+//            return;\r
+//        proxy.increaseReferenceCount(callerThread, 1);\r
+//    }\r
+//\r
+//    @Override\r
+//    public void decreaseReferenceCount(int callerThread, int subject) {\r
+//        if (subject < 0)\r
+//            return;\r
+//        ClusterProxy proxy = clusterTable.getClusterByResourceKey(subject);\r
+//        if (null == proxy)\r
+//            return;\r
+//        proxy.decreaseReferenceCount(callerThread, 1);\r
+//    }\r
+\r
+//     @Override\r
+       public void getObjects4(final ReadGraphImpl graph, final int subject, final ForEachObjectProcedure procedure) {\r
+               \r
+               if(subject < 0) {\r
+                       \r
+                       for(TransientGraph g : virtualGraphServerSupport.providers) {\r
+                for (final int id : g.getObjects(subject, procedure.predicateKey)) {\r
+\r
+//                    int suggestSchedule = graph.processor.processor.resourceThread(id);\r
+//                    if(graph.callerThread == suggestSchedule) {\r
+                       procedure.execute(graph, new ResourceImpl(resourceSupport, id));\r
+//                    } else {\r
+//                     graph.processor.processor.schedule(graph.callerThread, new SessionTask(suggestSchedule) {\r
+//             \r
+//                             @Override\r
+//                             public void run(int thread) {\r
+//                             procedure.execute(graph.newAsync(thread), new ResourceImpl(resourceSupport, id));\r
+//                             }\r
+//             \r
+//                     });\r
+//                    }\r
+                       \r
+                }\r
+                       }\r
+                       procedure.finished(graph);\r
+//             graph.dec();\r
+               return;\r
+               \r
+               } \r
+               \r
+        final ClusterImpl cluster = (ClusterImpl)clusterTable.getClusterByResourceKey(subject);\r
+        if(!cluster.isLoaded()) {\r
+               cluster.load(session.clusterTranslator, new Runnable() {\r
+\r
+                               @Override\r
+                               public void run() {\r
+                                       getObjects4(graph, subject, procedure);\r
+                               }\r
+                       \r
+               });\r
+               return;\r
+        }\r
+               \r
+               if (cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(subject)) {\r
+                       \r
+                       for(TransientGraph g : virtualGraphServerSupport.providers) {\r
+                for (final int id : g.getObjects(subject, procedure.predicateKey)) {\r
+//                    int suggestSchedule = graph.processor.processor.resourceThread(id);\r
+//                    if(graph.callerThread == suggestSchedule) {\r
+                       procedure.execute(graph, new ResourceImpl(resourceSupport, id));\r
+//                    } else {\r
+//                     graph.processor.processor.schedule(graph.callerThread, new SessionTask(suggestSchedule) {\r
+//             \r
+//                             @Override\r
+//                             public void run(int thread) {\r
+//                             procedure.execute(graph.newAsync(thread), new ResourceImpl(resourceSupport, id));\r
+//                             }\r
+//             \r
+//                     });\r
+//                    }\r
+                }\r
+                       }\r
+                       \r
+                       try {\r
+                               cluster.forObjects(graph, subject, procedure);\r
+                       } catch (DatabaseException e) {\r
+                               e.printStackTrace();\r
+                       }\r
+                       \r
+               } else {\r
+                       \r
+                       try {\r
+                               cluster.forObjects(graph, subject, procedure);\r
+                       } catch (DatabaseException e) {\r
+                               e.printStackTrace();\r
+                       }\r
+                       \r
+               }\r
+               \r
+       }\r
+\r
+       public <C> void getObjects4(final ReadGraphImpl graph, final int subject, final C context, final ForEachObjectContextProcedure<C> procedure) {\r
+               \r
+               if(subject < 0) {\r
+                       \r
+                       for(TransientGraph g : virtualGraphServerSupport.providers) {\r
+                for (final int id : g.getObjects(subject, procedure.predicateKey)) {\r
+\r
+//                    int suggestSchedule = graph.processor.processor.resourceThread(id);\r
+//                    if(graph.callerThread == suggestSchedule) {\r
+                       procedure.execute(graph, context, new ResourceImpl(resourceSupport, id));\r
+//                    } else {\r
+//                     graph.processor.processor.schedule(graph.callerThread, new SessionTask(suggestSchedule) {\r
+//             \r
+//                             @Override\r
+//                             public void run(int thread) {\r
+//                             procedure.execute(graph.newAsync(thread), context, new ResourceImpl(resourceSupport, id));\r
+//                             }\r
+//             \r
+//                     });\r
+//                    }\r
+                       \r
+                }\r
+                       }\r
+                       procedure.finished(graph);\r
+//             graph.dec();\r
+               return;\r
+               \r
+               } \r
+               \r
+        final ClusterImpl cluster = (ClusterImpl)clusterTable.getClusterByResourceKey(subject);\r
+        if(!cluster.isLoaded()) {\r
+               cluster.load(session.clusterTranslator, new Runnable() {\r
+\r
+                               @Override\r
+                               public void run() {\r
+                                       getObjects4(graph, subject, context, procedure);\r
+                               }\r
+                       \r
+               });\r
+               return;\r
+        }\r
+               \r
+               if (cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(subject)) {\r
+                       \r
+                       for(TransientGraph g : virtualGraphServerSupport.providers) {\r
+                for (final int id : g.getObjects(subject, procedure.predicateKey)) {\r
+//                    int suggestSchedule = graph.processor.processor.resourceThread(id);\r
+//                    if(graph.callerThread == suggestSchedule) {\r
+                       procedure.execute(graph, context, new ResourceImpl(resourceSupport, id));\r
+//                    } else {\r
+//                     graph.processor.processor.schedule(graph.callerThread, new SessionTask(suggestSchedule) {\r
+//             \r
+//                             @Override\r
+//                             public void run(int thread) {\r
+//                             procedure.execute(graph.newAsync(thread), context, new ResourceImpl(resourceSupport, id));\r
+//                             }\r
+//             \r
+//                     });\r
+//                    }\r
+                }\r
+                       }\r
+                       \r
+                       try {\r
+                               cluster.forObjects(graph, subject, context, procedure);\r
+                       } catch (DatabaseException e) {\r
+                               e.printStackTrace();\r
+                       }\r
+                       \r
+               } else {\r
+                       \r
+                       try {\r
+                               cluster.forObjects(graph, subject, context, procedure);\r
+                       } catch (DatabaseException e) {\r
+                               e.printStackTrace();\r
+                       }\r
+                       \r
+               }\r
+               \r
+       }\r
+       \r
+       @Override\r
+    public int getSingleInstance(final int subject) {\r
+       \r
+       // Do not process this information for virtual resources\r
+       if(subject < 0) return 0;\r
+       \r
+        final ClusterI cluster = clusterTable.getClusterByResourceKey(subject);\r
+        if (cluster == null)\r
+            System.out.println("null cluster: " + Integer.toString(subject, 16));\r
+        assert (cluster != null);\r
+\r
+        try {\r
+        \r
+               ClusterI.CompleteTypeEnum type = cluster.getCompleteType(subject, clusterSupport);\r
+               if(ClusterI.CompleteTypeEnum.InstanceOf == type) {\r
+                       int result = cluster.getCompleteObjectKey(subject, clusterSupport);\r
+                       assert(result > 0);\r
+                       return result;\r
+               } else {\r
+                       return 0;\r
+               }\r
+        \r
+        } catch (DatabaseException e) {\r
+               \r
+               Logger.defaultLogError(e);\r
+               return 0;\r
+               \r
+        }\r
+        // This happens is the resource is bogus\r
+        catch (Throwable t) {\r
+               \r
+               analyseProblem(cluster);\r
+               \r
+               Logger.defaultLogError(t);\r
+               \r
+               return 0;\r
+               \r
+        }\r
+       \r
+    }\r
+\r
+       @Override\r
+    public int getSingleSuperrelation(final int subject) {\r
+       \r
+       // Do not process this information for virtual resources\r
+       if(subject < 0) return 0;\r
+\r
+       final ClusterI cluster = clusterTable.getClusterByResourceKey(subject);\r
+        if (cluster == null)\r
+            System.out.println("null cluster: " + Integer.toString(subject, 16));\r
+        assert (cluster != null);\r
+\r
+        try {\r
+        \r
+               ClusterI.CompleteTypeEnum type = cluster.getCompleteType(subject, clusterSupport);\r
+               if(ClusterI.CompleteTypeEnum.SubrelationOf == type) {\r
+                       int result = cluster.getCompleteObjectKey(subject, clusterSupport);\r
+                       assert(result > 0);\r
+                       return result;\r
+               } else {\r
+                       return 0;\r
+               }\r
+        \r
+        } catch (DatabaseException e) {\r
+               \r
+               Logger.defaultLogError(e);\r
+               return 0;\r
+               \r
+        }\r
+       \r
+    }\r
+\r
+//     @Override\r
+//    public void getSingleSuperrelation(ReadGraphImpl graph, final int subject, final AsyncProcedure<Resource> procedure) {\r
+//     \r
+//     // Do not process this information for virtual resources\r
+//     if(subject < 0) {\r
+//             procedure.execute(graph, null);\r
+//                     graph.state.barrier.dec();\r
+//             return;\r
+//     }\r
+//\r
+//     final ClusterI cluster = clusterTable.getClusterByResourceKey(subject);\r
+//        if (cluster == null)\r
+//            System.out.println("null cluster: " + Integer.toString(subject, 16));\r
+//        \r
+//        assert (cluster != null);\r
+//\r
+//        if(!cluster.isLoaded()) {\r
+//            \r
+//             procedure.execute(graph, null);\r
+//                     graph.state.barrier.dec();\r
+//             return;\r
+//\r
+////           queryProvider2.requestCluster(callerThread, cluster.getClusterId(), new Callback<Integer>() {\r
+////   \r
+////                           @Override\r
+////                           public void run(Integer i) {\r
+////   \r
+////                                   queryProvider2.schedule(i, callerThread, new Runnable() {\r
+////   \r
+////                                           @Override\r
+////                                           public void run() {\r
+////                                                   \r
+////                                                   try  {\r
+////                                                   \r
+////                                               ClusterI.CompleteTypeEnum type = cluster.getCompleteType(callerThread, subject, SessionImplSocket.this);\r
+////                                               if(ClusterI.CompleteTypeEnum.SubrelationOf == type) {\r
+////                                                   int result = cluster.getCompleteObjectKey(callerThread, subject, SessionImplSocket.this);\r
+////                                                   assert(result > 0);\r
+////                                                   procedure.execute(graph, getResourceByKey(result));\r
+////                                               } else {\r
+////                                                   procedure.execute(graph, null);\r
+////                                               }\r
+////                                                           graph.state.barrier.dec();\r
+////                                                           \r
+////                                                   } catch (DatabaseException e) {\r
+////                                                           e.printStackTrace();\r
+////                                                   }\r
+////                                                   \r
+////                                           }\r
+////   \r
+////                                   });\r
+////   \r
+////                           }\r
+////   \r
+////                   });\r
+//                     \r
+//        } else {\r
+//\r
+//             try {\r
+//\r
+//                     ClusterI.CompleteTypeEnum type = cluster.getCompleteType(graph.callerThread, subject, clusterSupport);\r
+//                     if(ClusterI.CompleteTypeEnum.SubrelationOf == type) {\r
+//                             int result = cluster.getCompleteObjectKey(graph.callerThread, subject, clusterSupport);\r
+//                             assert(result > 0);\r
+//                             procedure.execute(graph, new ResourceImpl(resourceSupport, result));\r
+//                     } else {\r
+//                             procedure.execute(graph, null);\r
+//                     }\r
+//                     graph.state.barrier.dec();\r
+//\r
+//             } catch (DatabaseException e) {\r
+//                     e.printStackTrace();\r
+//             }\r
+//                     \r
+//        }\r
+//        \r
+//        \r
+//    }\r
+\r
+//     @Override\r
+//    public void getObjects2(final int callerThread, final int subject, final int predicate, final IntProcedure procedure) {\r
+//             ensureLoaded(callerThread, subject, predicate, new Runnable() {\r
+//\r
+//                     @Override\r
+//                     public void run() {\r
+//                             safeGetObjects2(callerThread, subject, predicate, procedure);\r
+//                     }\r
+//                     \r
+//             });\r
+//     }\r
+\r
+//    public void safeGetObjects2(final ReadGraphImpl graph, final int subject, final int predicate, final IntProcedure procedure) {\r
+//\r
+//        assert (subject != 0);\r
+//        assert (predicate != 0);\r
+////        System.out.println("getObjects2: s=" + subject + "p=" + predicate);\r
+//        Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(subject);\r
+//        if (providers != null) {\r
+//\r
+//            final TIntHashSet result = new TIntHashSet(16);\r
+//\r
+//            for (VirtualGraph provider : providers) {\r
+//\r
+//                for (int id : ((VirtualGraphImpl)provider).getObjects(subject, predicate)) {\r
+//\r
+//                    if (result.add(id)) {\r
+//                     procedure.execute(graph, id);\r
+//                    }\r
+//\r
+//                }\r
+//\r
+//            }\r
+//\r
+//            if (subject < 0)\r
+//                return;\r
+//\r
+//            final ClusterI cluster = clusterTable.getClusterByResourceKey(subject);\r
+//\r
+//            assert (testCluster(subject, cluster));\r
+//            \r
+//            // wheels within wheels\r
+//            final ClusterI.ObjectProcedure<Object> proc = new ClusterI.ObjectProcedure<Object>() {\r
+//\r
+//                @Override\r
+//                public boolean execute(int callerThread, Object context, int object) {\r
+//\r
+//                    if (result.add(object)) {\r
+//                     procedure.execute(graph.newAsync(callerThread), object);\r
+//                    }\r
+//\r
+//                    return false; // continue looping\r
+//\r
+//                }\r
+//                \r
+//                             @Override\r
+//                             public boolean found() {\r
+//                                     throw new UnsupportedOperationException();\r
+//                             }\r
+//                \r
+//            };\r
+//\r
+//            try {\r
+//                cluster.forObjects(graph.callerThread, subject, predicate, proc, null, clusterSupport);\r
+//            } catch (DatabaseException e) {\r
+//                Logger.defaultLogError(e);\r
+//            } catch (Throwable t) {\r
+//                Logger.defaultLogError(t);\r
+//             t.printStackTrace();\r
+//            }\r
+//            return;\r
+//            \r
+//        }\r
+//        \r
+//        assert(subject > 0);\r
+//\r
+//        final ClusterI cluster = clusterTable.getClusterByResourceKey(subject);\r
+//\r
+//        assert (testCluster(subject, cluster));\r
+//        \r
+//        try {\r
+//            cluster.forObjects(graph.callerThread, subject, predicate, new Wheels(procedure), null, clusterSupport);\r
+//        } catch (DatabaseException e) {\r
+//            Logger.defaultLogError(e);\r
+//        } catch (Throwable t) {\r
+//             t.printStackTrace();\r
+//            Logger.defaultLogError(t);\r
+//        }\r
+//        \r
+//    }\r
+\r
+       @Override\r
+    public boolean getObjects(final ReadGraphImpl graph, final int subject, final int predicate, final IntProcedure procedure) {\r
+               \r
+               assert (subject != 0);\r
+               assert (predicate != 0);\r
+\r
+               if(subject < 0) {\r
+\r
+                       boolean found = false;\r
+                       \r
+                       for(TransientGraph g : virtualGraphServerSupport.providers) {\r
+                               for (final int id : g.getObjects(subject, predicate)) {\r
+                                       found = true;\r
+                                       procedure.execute(graph, id);\r
+                               }\r
+                       }\r
+                       \r
+                       return found;\r
+\r
+               }\r
+\r
+               final ClusterI cluster = clusterTable.getClusterByResourceKey(subject);\r
+               assert(cluster.isLoaded());\r
+        \r
+        if (cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(subject)) {\r
+               \r
+               final DataContainer<Boolean> found = new DataContainer<Boolean>(Boolean.FALSE);\r
+               final TIntHashSet result = new TIntHashSet(5);\r
+               \r
+                       for(TransientGraph g : virtualGraphServerSupport.providers) {\r
+                               for (final int id : g.getObjects(subject, predicate)) {\r
+\r
+                                       found.set(true);\r
+                                       if (result.add(id)) {\r
+                                               procedure.execute(graph, id);\r
+                                       }\r
+\r
+                               }\r
+                       }\r
+                       \r
+                       // Virtual predicates are not found from persistent clusters\r
+                       if(predicate < 0) return found.get();\r
+\r
+               // wheels within wheels\r
+               final ClusterI.ObjectProcedure<Object> proc = new ClusterI.ObjectProcedure<Object>() {\r
+\r
+                       @Override\r
+                       public boolean execute(Object context, int object) {\r
+\r
+                               found.set(true);\r
+                               if (result.add(object)) {\r
+                                       procedure.execute(graph, object);\r
+                               }\r
+\r
+                               return false; // continue looping\r
+\r
+                       }\r
+\r
+               };\r
+                       \r
+                       try {\r
+                cluster.forObjects(subject, predicate, proc, null, clusterSupport);\r
+                       } catch (DatabaseException e) {\r
+                               e.printStackTrace();\r
+                       }\r
+                       \r
+                       return found.get();\r
+                       \r
+               } else {\r
+                       \r
+                       // Virtual predicates are not found from persistent clusters\r
+                       if(predicate < 0) return false;\r
+                       \r
+                       class A implements ClusterI.ObjectProcedure<Object> {\r
+\r
+                       boolean found = false;\r
+\r
+                       @Override\r
+                       public boolean execute(Object context, int object) {\r
+\r
+                               found = true;\r
+                               procedure.execute(graph, object);\r
+\r
+                               return false; // continue looping\r
+\r
+                       }\r
+\r
+                               public boolean found() {\r
+                                       return found;\r
+                               }\r
+\r
+                       }\r
+                       \r
+               // wheels within wheels\r
+               final A proc = new A();\r
+               \r
+                       try {\r
+                cluster.forObjects(subject, predicate, proc, null, clusterSupport);\r
+                       } catch (DatabaseException e) {\r
+                               e.printStackTrace();\r
+                       } \r
+                       // This happens if resource is bogus\r
+                       catch (Throwable t) {\r
+                               \r
+                       analyseProblem(cluster);\r
+                       \r
+                       Logger.defaultLogError(t);\r
+                               \r
+                       }\r
+               \r
+               return proc.found();\r
+                       \r
+               }\r
+        \r
+    }\r
+\r
+//     @Override\r
+//    public boolean getFunctionalObject(final ReadGraphImpl graph, final int subject, final int predicate,\r
+//            final IntProcedure procedure) {\r
+//\r
+//        assert (subject != 0);\r
+//        assert (predicate != 0);\r
+//\r
+//        if(subject < 0) {\r
+//\r
+//             boolean found = false;\r
+//\r
+//             Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(subject);\r
+//             if (providers != null) {\r
+//\r
+//                     for (VirtualGraph provider : providers) {\r
+//\r
+//                             for (int id : ((VirtualGraphImpl)provider).getObjects(subject, predicate)) {\r
+//                                     found = true;\r
+//                     procedure.execute(graph, id);\r
+//                    }\r
+//\r
+//                }\r
+//\r
+//            }\r
+//             \r
+//             return found;\r
+//             \r
+//        }\r
+//        \r
+//        final ClusterI cluster = clusterTable.getClusterByResourceKey(subject);\r
+//        \r
+//        if (cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(subject)) {\r
+//        \r
+//             final DataContainer<Boolean> found = new DataContainer<Boolean>(false);\r
+//             final TIntHashSet result = new TIntHashSet(5);\r
+//\r
+//             Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(subject);\r
+//             if (providers != null) {\r
+//\r
+//                     for (VirtualGraph provider : providers) {\r
+//\r
+//                             for (int id : ((VirtualGraphImpl)provider).getObjects(subject, predicate)) {\r
+//                                     found.set(true);\r
+//                     procedure.execute(graph, id);\r
+//                    }\r
+//\r
+//                }\r
+//\r
+//            }\r
+//             \r
+//            // wheels within wheels\r
+//            final ClusterI.ObjectProcedure<Object> proc = new ClusterI.ObjectProcedure<Object>() {\r
+//\r
+//                @Override\r
+//                public boolean execute(int callerThread, Object context, int object) {\r
+//\r
+//                    found.set(true);\r
+//                    System.out.println("-found object " + object);\r
+//                    if (result.add(object)) {\r
+//                     procedure.execute(graph.newAsync(callerThread), object);\r
+//                    }\r
+//\r
+//                    return false; // continue looping\r
+//\r
+//                }\r
+//                \r
+//                             @Override\r
+//                             public boolean found() {\r
+//                                     throw new UnsupportedOperationException();\r
+//                             }\r
+//                \r
+//            };\r
+//            \r
+//            try {\r
+//                cluster.forObjects(graph.callerThread, subject, predicate, proc, null, clusterSupport);\r
+//            } catch (DatabaseException e) {\r
+//                Logger.defaultLogError(e);\r
+//                return false;\r
+//            } catch (Throwable t) {\r
+//                Logger.defaultLogError(t);\r
+//             t.printStackTrace();\r
+//            }\r
+//            \r
+//            return found.get();\r
+//            \r
+//        } else {\r
+//\r
+//             // wheels within wheels\r
+//             final ClusterI.ObjectProcedure<Object> proc = new ClusterI.ObjectProcedure<Object>() {\r
+//                 \r
+//                     boolean found = false;\r
+//                     \r
+//                 @Override\r
+//                 public boolean execute(int callerThread, Object context, int object) {\r
+//     \r
+//                     found = true;\r
+//                     procedure.execute(graph.newAsync(callerThread), object);\r
+//                     return false; // continue looping\r
+//                     \r
+//                 }\r
+//                 \r
+//                             @Override\r
+//                             public boolean found() {\r
+//                                     return found;\r
+//                             }\r
+//                 \r
+//                 @Override\r
+//                 public String toString() {\r
+//                     return "Wheels for " + procedure;\r
+//                 }\r
+//                 \r
+//             };\r
+//             \r
+//             try {\r
+//                 cluster.forObjects(graph.callerThread, subject, predicate, proc, null, clusterSupport);\r
+//             } catch (DatabaseException e) {\r
+//                 Logger.defaultLogError(e);\r
+//                 return false;\r
+//             } catch (Throwable t) {\r
+//                     t.printStackTrace();\r
+//                 Logger.defaultLogError(t);\r
+//                 return false;\r
+//             }\r
+//             \r
+//             return proc.found();\r
+//        \r
+//        }\r
+//        \r
+//    }\r
+       \r
+       @Override\r
+    public int getFunctionalObject(final int subject, final int predicate) {\r
+\r
+        assert (subject != 0);\r
+        assert (predicate != 0);\r
+\r
+        if(subject < 0) {\r
+\r
+               int found = 0;\r
+\r
+               Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(subject);\r
+               if (providers != null) {\r
+\r
+                       for (VirtualGraph provider : providers) {\r
+\r
+                               for (int id : ((VirtualGraphImpl)provider).getObjects(subject, predicate)) {\r
+                                       if(found == 0) found = id;\r
+                                       else found = -1;\r
+                    }\r
+\r
+                }\r
+\r
+            }\r
+               \r
+               return found;\r
+//             if(found == -1) return 0;\r
+//             else return found;\r
+               \r
+        }\r
+        \r
+        final ClusterI cluster = clusterTable.getClusterByResourceKey(subject);\r
+        \r
+        if (cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(subject)) {\r
+\r
+               int result = 0;\r
+               Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(subject);\r
+               if (providers != null) {\r
+\r
+                       for (VirtualGraph provider : providers) {\r
+\r
+                               for (int id : ((VirtualGraphImpl)provider).getObjects(subject, predicate)) {\r
+                                       if(result == 0) result = id;\r
+                                       else result = -1;\r
+                    }\r
+\r
+                }\r
+\r
+            }\r
+               \r
+               if(result != 0) return result; \r
+            \r
+               try {\r
+                               return cluster.getSingleObject(subject, predicate, clusterSupport);\r
+                       } catch (DatabaseException e) {\r
+                               return -1;\r
+                       }\r
+            \r
+        } else {\r
+\r
+               try {\r
+                               return cluster.getSingleObject(subject, predicate, clusterSupport);\r
+                       } catch (DatabaseException e) {\r
+                               return -1;\r
+                       }\r
+               // This comes if the resource is bogus\r
+               catch (Throwable t) {\r
+                       \r
+               analyseProblem(cluster);\r
+               \r
+               Logger.defaultLogError(t);\r
+                       \r
+                               return -1;\r
+                               \r
+                       }\r
+        \r
+        }\r
+        \r
+    }\r
+\r
+//     @Override\r
+//    public boolean getStatements(final ReadGraphImpl graph, final int subject, final int predicate,\r
+//            final TripleIntProcedure procedure, final Statements entry) {\r
+//\r
+//        assert (subject != 0);\r
+//        assert (predicate != 0);\r
+//\r
+//        final TIntHashSet result = new TIntHashSet(16);\r
+//        final DataContainer<Boolean> found = new DataContainer<Boolean>(false);\r
+//\r
+//        Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(subject);\r
+//        \r
+//        if (providers != null) {\r
+//\r
+//            for (VirtualGraph provider : providers) {\r
+//\r
+//                for (int id : ((VirtualGraphImpl)provider).getObjects(subject, predicate)) {\r
+//\r
+//                    found.set(true);\r
+//\r
+//                    if (result.add(id)) {\r
+//                        if (null != entry) {\r
+//                            entry.addOrSet(subject, predicate, id);\r
+//                            procedure.execute(graph, subject, predicate, id);\r
+//                            return true; // break;\r
+//                        } else {\r
+//                            procedure.execute(graph, subject, predicate, id);\r
+//                        }\r
+//                    }\r
+//\r
+//                }\r
+//\r
+//            }\r
+//\r
+//        }\r
+//\r
+//        if (subject < 0)\r
+//            return found.get();\r
+//\r
+//        final ClusterI cluster = clusterTable.getClusterByResourceKey(subject);\r
+//        assert (cluster != null);\r
+//\r
+//        // wheels within wheels\r
+//        final ClusterI.ObjectProcedure<Object> proc = new ClusterI.ObjectProcedure<Object>() {\r
+//            @Override\r
+//            public boolean execute(int callerThread, Object context, int object) {\r
+//\r
+//                found.set(true);\r
+//\r
+//                if (result.add(object)) {\r
+//                    if (null != entry) {\r
+//                        entry.addOrSet(subject, predicate, object);\r
+//                        procedure.execute(graph.newAsync(callerThread), subject, predicate, object);\r
+//                        return true; // break;\r
+//                    } else {\r
+//                        procedure.execute(graph.newAsync(callerThread), subject, predicate, object);\r
+//                    }\r
+//                }\r
+//\r
+//                return false; // continue looping\r
+//\r
+//            }\r
+//            \r
+//                     @Override\r
+//                     public boolean found() {\r
+//                             throw new UnsupportedOperationException();\r
+//                     }\r
+//            \r
+//        };\r
+//\r
+//        try {\r
+//            cluster.forObjects(graph.callerThread, subject, predicate, proc, null, clusterSupport);\r
+//        } catch (DatabaseException e) {\r
+//            Logger.defaultLogError(e);\r
+//        }\r
+//        return found.get();\r
+//\r
+//    }\r
+\r
+       @Override\r
+    public org.simantics.db.DirectStatements getStatements(final ReadGraphImpl graph, final int subject, final QueryProcessor processor, boolean ignoreVirtual) {\r
+\r
+        assert (subject != 0);\r
+\r
+        final DirectStatementsImpl result = new DirectStatementsImpl(resourceSupport, subject);\r
+\r
+        if (!ignoreVirtual) {\r
+            Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(subject);\r
+            if (providers != null) {\r
+                for (TransientGraph provider : providers) {\r
+                    for (int p : provider.getPredicates(subject)) {\r
+                        for (int o : provider.getObjects(subject, p)) {\r
+                            result.addStatement(p, o);\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+        }\r
+\r
+        if (subject < 0) {\r
+               return result;\r
+        } else {\r
+            final ClusterI cluster = clusterTable.getClusterByResourceKey(subject);\r
+            assert (cluster != null);\r
+            doGetStatements(graph, cluster, subject, result);\r
+        }\r
+        \r
+        return result;\r
+\r
+    }\r
+\r
+//    @Override\r
+//    public void getStatements(ReadGraphImpl graph, final int subject, final Procedure<DirectStatements> procedure) {\r
+//     \r
+//             procedure.exception(new DatabaseException("Not supported"));\r
+//             \r
+//    }\r
+\r
+    @Override\r
+    public void getPredicates(final ReadGraphImpl graph, final int subject, final IntProcedure procedure) {\r
+\r
+        final TIntHashSet result = new TIntHashSet(16);\r
+\r
+        Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(subject);\r
+        \r
+        if (providers != null) {\r
+\r
+            for (VirtualGraph provider : providers) {\r
+\r
+                for (int id : ((VirtualGraphImpl)provider).getPredicates(subject)) {\r
+\r
+                    if (result.add(id)) {\r
+                        procedure.execute(graph, id);\r
+                    }\r
+\r
+                }\r
+\r
+            }\r
+\r
+        }\r
+\r
+        if (subject < 0) {\r
+            procedure.finished(graph);\r
+            return;\r
+        }\r
+\r
+        ClusterI proxy = clusterTable.getClusterByResourceKey(subject);\r
+//        if(!proxy.isLoaded()) {\r
+//             \r
+//             proxy.load(callerThread, session, new Runnable() {\r
+//\r
+//                             @Override\r
+//                             public void run() {\r
+//                                     getPredicates(callerThread, subject, procedure);\r
+//                             }\r
+//                     \r
+//             });\r
+//             return;\r
+//             \r
+//        }\r
+        assert (proxy != null);\r
+\r
+        final DataContainer<Integer> got = new DataContainer<Integer>(0);\r
+        ClusterI.PredicateProcedure<Object> proc = new ClusterI.PredicateProcedure<Object>() {\r
+            @Override\r
+            public boolean execute(Object context, int predicate, int oi) {\r
+                if (result.add(predicate)) {\r
+                    procedure.execute(graph, predicate);\r
+                }\r
+                got.set(got.get() + 1);\r
+                return false; // continue looping\r
+            }\r
+        };\r
+        try {\r
+            proxy.forPredicates(subject, proc, null, clusterSupport);\r
+        } catch (DatabaseException e) {\r
+            Logger.defaultLogError(e);\r
+        }\r
+        procedure.finished(graph);\r
+\r
+    }\r
+    \r
+    \r
+\r
+//    @Override\r
+//    public void getValue(ReadGraphImpl graph, int resource, InternalProcedure<byte[]> procedure) {\r
+//\r
+//     if(resource < 0) {\r
+//     \r
+//             Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(resource);\r
+//             \r
+//             if (providers != null) {\r
+//     \r
+//                 for (VirtualGraph provider : providers) {\r
+//     \r
+//                     Object value = ((VirtualGraphImpl)provider).getValue(resource);\r
+//                     if (value != null) {\r
+//                         procedure.execute(graph, (byte[])value);\r
+//                         return;\r
+//                     }\r
+//     \r
+//                 }\r
+//     \r
+//             }\r
+//             \r
+//             return;\r
+//        \r
+//     }\r
+//     \r
+//     ClusterI cluster = clusterTable.getClusterByResourceKey(resource);\r
+//        if (cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(resource)) {\r
+//             \r
+//             Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(resource);\r
+//             \r
+//             if (providers != null) {\r
+//     \r
+//                 for (VirtualGraph provider : providers) {\r
+//     \r
+//                     Object value = ((VirtualGraphImpl)provider).getValue(resource);\r
+//                     if (value != null) {\r
+//                         procedure.execute(graph, (byte[])value);\r
+//                         return;\r
+//                     }\r
+//     \r
+//                 }\r
+//     \r
+//             }\r
+//             \r
+//             try {\r
+//                     \r
+//                     byte[] data = cluster.getValue(resource, clusterSupport);\r
+//                     if (null == data || 0 == data.length) {\r
+//                         procedure.execute(graph, null);\r
+//                     } else {\r
+//                         procedure.execute(graph, data);\r
+//                     }\r
+//                     \r
+//             } catch (DatabaseException e) {\r
+//                 Logger.defaultLogError(e);\r
+//             }\r
+//             \r
+//        } else {\r
+//\r
+//             try {\r
+//                     \r
+//                     byte[] data = cluster.getValue(resource, clusterSupport);\r
+//                     if (null == data || 0 == data.length) {\r
+//                         procedure.execute(graph, null);\r
+//                     } else {\r
+//                         procedure.execute(graph, data);\r
+//                     }\r
+//                     \r
+//             } catch (DatabaseException e) {\r
+//                 Logger.defaultLogError(e);\r
+//             }\r
+//\r
+//        }\r
+//\r
+//    }\r
+\r
+\r
+    @Override\r
+    public byte[] getValue(ReadGraphImpl graph, int resource) {\r
+\r
+       if(resource < 0) {\r
+       \r
+               Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(resource);\r
+               \r
+               if (providers != null) {\r
+       \r
+                   for (VirtualGraph provider : providers) {\r
+       \r
+                       Object value = ((VirtualGraphImpl)provider).getValue(resource);\r
+                       if (value != null) {\r
+                               return (byte[])value;\r
+                       }\r
+       \r
+                   }\r
+       \r
+               }\r
+               \r
+               return null;\r
+        \r
+       }\r
+       \r
+       ClusterI cluster = clusterTable.getClusterByResourceKey(resource);\r
+        if (cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(resource)) {\r
+               \r
+               Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(resource);\r
+               \r
+               if (providers != null) {\r
+       \r
+                   for (VirtualGraph provider : providers) {\r
+       \r
+                       Object value = ((VirtualGraphImpl)provider).getValue(resource);\r
+                       if (value != null) {\r
+                               return (byte[])value;\r
+                       }\r
+       \r
+                   }\r
+       \r
+               }\r
+               \r
+               try {\r
+                       \r
+                       byte[] data = cluster.getValue(resource, clusterSupport);\r
+                       if (null != data && 0 != data.length) {\r
+                               return data;\r
+                       }\r
+                       \r
+               } catch (DatabaseException e) {\r
+                   Logger.defaultLogError(e);\r
+               }\r
+               \r
+               return null;\r
+               \r
+        } else {\r
+\r
+               try {\r
+                       \r
+                       byte[] data = cluster.getValue(resource, clusterSupport);\r
+                       if (null != data && 0 != data.length) {\r
+                               return data;\r
+                       }\r
+                       \r
+               } catch (DatabaseException e) {\r
+                   Logger.defaultLogError(e);\r
+               }\r
+               \r
+               return null;\r
+\r
+        }\r
+\r
+    }\r
+\r
+    @Override\r
+    public InputStream getValueStream(ReadGraphImpl graph, int resource) {\r
+\r
+        if(resource < 0) {\r
+        \r
+            Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(resource);\r
+            \r
+            if (providers != null) {\r
+    \r
+                for (VirtualGraph provider : providers) {\r
+    \r
+                    Object value = ((VirtualGraphImpl)provider).getValue(resource);\r
+                    if (value != null) {\r
+                        return new ByteArrayInputStream((byte[])value);\r
+                    }\r
+    \r
+                }\r
+    \r
+            }\r
+            \r
+            return null;\r
+        \r
+        }\r
+        \r
+        ClusterI cluster = clusterTable.getClusterByResourceKey(resource);\r
+        if (cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(resource)) {\r
+            \r
+            Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(resource);\r
+            \r
+            if (providers != null) {\r
+    \r
+                for (VirtualGraph provider : providers) {\r
+    \r
+                    Object value = ((VirtualGraphImpl)provider).getValue(resource);\r
+                    if (value != null) {\r
+                        return new ByteArrayInputStream((byte[])value);\r
+                    }\r
+    \r
+                }\r
+    \r
+            }\r
+            \r
+            try {\r
+                \r
+                return cluster.getValueStream(resource, clusterSupport);\r
+                \r
+            } catch (DatabaseException e) {\r
+                Logger.defaultLogError(e);\r
+            }\r
+            \r
+            return null;\r
+            \r
+        } else {\r
+\r
+            try {\r
+                \r
+                return cluster.getValueStream(resource, clusterSupport);\r
+                \r
+            } catch (DatabaseException e) {\r
+                Logger.defaultLogError(e);\r
+            }\r
+            \r
+            return null;\r
+\r
+        }\r
+\r
+    }\r
+    \r
+    @Override\r
+    public void requestCluster(ReadGraphImpl graph, final long clusterId, final Runnable r) {\r
+\r
+        class CallbackAdapter implements Callback<DatabaseException> {\r
+               final Runnable r;\r
+               CallbackAdapter(final Runnable r) {\r
+                       this.r = r;\r
+               }\r
+               @Override\r
+               public void run(DatabaseException e) {\r
+                       if (null != e)\r
+                               e.printStackTrace();\r
+                       else\r
+                               r.run();\r
+               }\r
+               \r
+        }\r
+       \r
+        double p = clusterTable.getLoadProbability();\r
+// System.out.print("Load cluster " + clusterId + " with probability " + p +\r
+        // " -> ");\r
+        final ClusterI proxy = clusterSupport.getClusterByClusterId(clusterId);\r
+        if (!proxy.isLoaded()) {\r
+               clusterTable.gc();\r
+            if (Math.random() < p) {\r
+                proxy.load(new CallbackAdapter(r));\r
+            } else {\r
+                r.run();\r
+            }\r
+        } else {\r
+            r.run();\r
+        }\r
+\r
+    }\r
+\r
+    @Override\r
+    public int getBuiltin(String uri) {\r
+       return builtinSupport.getBuiltin(uri);\r
+    }\r
+\r
+    @Override\r
+    public void checkTasks() {\r
+        System.out.println(syncThreads.toString());\r
+    }\r
+\r
+//    @Override\r
+//    public void asyncWrite(Write request) {\r
+//        \r
+////           if(plainWrite(writer) && sameProvider(request)) {\r
+////                   writer.writeSupport.pushRequest(request);\r
+////           } else {\r
+//             asyncRequest(request);\r
+////           }\r
+//        \r
+//    }\r
+\r
+    /*\r
+     * Helpers\r
+     * \r
+     * \r
+     */\r
+    \r
+    private void doGetStatements(ReadGraphImpl graph, final ClusterI cluster, final int subject, final DirectStatementsImpl result) {\r
+\r
+        final class Proc implements ClusterI.PredicateProcedure<Object> {\r
+\r
+                       @Override\r
+                       public boolean execute(Object context, final int predicate, final int objectIndex) {\r
+                               \r
+                               doExecute(null, predicate, objectIndex);\r
+                               return false;\r
+                               \r
+                       }\r
+\r
+                       private void doExecute(Object context, final int predicate, final int objectIndex) {\r
+\r
+                               try {\r
+                                       cluster.forObjects(subject, predicate, new ClusterI.ObjectProcedure<Object>() {\r
+\r
+                                               @Override\r
+                                               public boolean execute(Object context, int object) {\r
+                                                       result.addStatement(predicate, object);\r
+                                                       return false;\r
+                                               }\r
+\r
+                                       }, null, clusterSupport);\r
+                               } catch (DatabaseException e) {\r
+                                       e.printStackTrace();\r
+                               }\r
+                               \r
+                       }\r
+               \r
+        }\r
+\r
+        try {\r
+                       cluster.forPredicates(subject, new Proc(), null, clusterSupport);\r
+               } catch (DatabaseException e) {\r
+                       e.printStackTrace();\r
+               }\r
+       \r
+    }\r
+    \r
+//     private void getDirectObjects4(final int callerThread, final ClusterI cluster, final int subject, final int predicate, final QueryProcessor processor, final ReadGraphImpl graph, final ForEachObjectProcedure procedure) {\r
+//\r
+//        if(!cluster.isLoaded()) {\r
+//\r
+//                     requestCluster(callerThread, cluster.getClusterId(), new Callback<Integer>() {\r
+//     \r
+//                             @Override\r
+//                             public void run(Integer i) {\r
+//     \r
+//                                     processor.schedule(i, new SessionTask(callerThread) {\r
+//     \r
+//                                             @Override\r
+//                                             public void run(int thread) {\r
+//                                                     \r
+//                                                     getDirectObjects4(thread, cluster, subject, predicate, processor, graph, procedure);\r
+//                                                     \r
+//                                             }\r
+//     \r
+//                                     });\r
+//     \r
+//                             }\r
+//     \r
+//                     });\r
+//                     \r
+//        } else {\r
+//\r
+//             try {\r
+//                     cluster.forObjects(graph, subject, predicate, procedure);\r
+//             } catch (DatabaseException e) {\r
+//                     e.printStackTrace();\r
+//             }\r
+//             \r
+////                   procedure.finished(graph);\r
+////                   graph.state.barrier.dec();\r
+////                   \r
+////            System.err.println("ai2=" + ai2.decrementAndGet());\r
+//             \r
+//        }\r
+//             \r
+//             \r
+//     }\r
+\r
+//     AtomicInteger ai2  =new AtomicInteger(0);\r
+       \r
+//    private boolean testCluster(int subject, ClusterI proxy) {\r
+//     \r
+//        if (proxy == null)\r
+//            System.out.println("null cluster: " + Integer.toString(subject, 16));\r
+//        \r
+//        return proxy != null;\r
+//     \r
+//    }\r
+\r
+    long getCluster(int id) {\r
+       // Virtual resource\r
+       if(id < 0) return 0;\r
+       ClusterI proxy = clusterTable.getClusterByResourceKey(id);\r
+       if(proxy == null) return 0;\r
+       else return proxy.getClusterId();\r
+    }\r
+\r
+       @Override\r
+       public int getRandomAccessReference(String id) throws ResourceNotFoundException {\r
+               \r
+               try {\r
+                       Resource res = serializationSupport.getResourceSerializer().getResource(id);\r
+                       if(res == null) return 0;\r
+                       else return ((ResourceImpl)res).id;\r
+               } catch (InvalidResourceReferenceException e) {\r
+                       //e.printStackTrace();\r
+               }\r
+               return 0;\r
+               \r
+       }\r
+       \r
+       @Override\r
+       public void ensureLoaded(final ReadGraphImpl graph, final int subject, final int predicate) {\r
+               \r
+               if(subject < 0) {\r
+                       \r
+                       SessionImplSocket.loadVirtualStatements(virtualGraphServerSupport, graph, subject, predicate, new Callback<ReadGraphImpl>() {\r
+\r
+                               @Override\r
+                               public void run(ReadGraphImpl parameter) {\r
+                               }\r
+                               \r
+                       });\r
+                       \r
+               } else {\r
+                       \r
+               final ClusterI cluster = clusterTable.checkedGetClusterByResourceKey(subject);\r
+\r
+               if(cluster.isLoaded()) {\r
+                       \r
+                       if(cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(subject) && !SessionImplSocket.areVirtualStatementsLoaded(virtualGraphServerSupport, subject, predicate)) {\r
+\r
+                                       SessionImplSocket.loadVirtualStatements(virtualGraphServerSupport, graph, subject, predicate, new Callback<ReadGraphImpl>() {\r
+\r
+                                               @Override\r
+                                               public void run(ReadGraphImpl parameter) {\r
+                                               }\r
+                                               \r
+                                       });\r
+                               \r
+                               } else {\r
+                                       \r
+                               }\r
+                       \r
+               } else {\r
+                       \r
+                               new Exception().printStackTrace();\r
+                       \r
+                       cluster.load(session.clusterTranslator, new Runnable() {\r
+\r
+                                       @Override\r
+                                       public void run() {\r
+                                               \r
+                                       if(cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(subject) && !SessionImplSocket.areVirtualStatementsLoaded(virtualGraphServerSupport, subject, predicate)) {\r
+\r
+                                                       SessionImplSocket.loadVirtualStatements(virtualGraphServerSupport, graph, subject, predicate, new Callback<ReadGraphImpl>() {\r
+\r
+                                                               @Override\r
+                                                               public void run(ReadGraphImpl parameter) {\r
+                                                               }\r
+                                                               \r
+                                                       });\r
+                                               \r
+                                               } else {\r
+                                                       \r
+                                               }\r
+                                               \r
+                                       }\r
+                               \r
+                       });\r
+                       \r
+               }\r
+               \r
+               \r
+               }\r
+               \r
+       }\r
+       \r
+       @Override\r
+       public void ensureLoaded(final ReadGraphImpl graph, final int subject) {\r
+               \r
+               if(subject < 0) {\r
+                       \r
+                       SessionImplSocket.loadVirtualStatements(virtualGraphServerSupport, graph, subject, new Callback<ReadGraphImpl>() {\r
+\r
+                               @Override\r
+                               public void run(ReadGraphImpl parameter) {\r
+                               }\r
+                               \r
+                       });\r
+                       \r
+               } else {\r
+                       \r
+               final ClusterI cluster = clusterTable.getClusterByResourceKey(subject);\r
+\r
+               if(cluster.isLoaded()) {\r
+                       \r
+                       if(cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(subject) && !SessionImplSocket.areVirtualStatementsLoaded(virtualGraphServerSupport, subject)) {\r
+\r
+                                       SessionImplSocket.loadVirtualStatements(virtualGraphServerSupport, graph, subject, new Callback<ReadGraphImpl>() {\r
+\r
+                                               @Override\r
+                                               public void run(ReadGraphImpl parameter) {\r
+                                               }\r
+                                               \r
+                                       });\r
+                               \r
+                               } else {\r
+                                       \r
+                               }\r
+                       \r
+               } else {\r
+                       \r
+//                     System.err.println("cluster not loaded " + subject);\r
+                               new Exception().printStackTrace();\r
+                       \r
+                       cluster.load(session.clusterTranslator, new Runnable() {\r
+\r
+                                       @Override\r
+                                       public void run() {\r
+                                               \r
+                                       if(cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(subject) && !SessionImplSocket.areVirtualStatementsLoaded(virtualGraphServerSupport, subject)) {\r
+\r
+                                                       SessionImplSocket.loadVirtualStatements(virtualGraphServerSupport, graph, subject, new Callback<ReadGraphImpl>() {\r
+\r
+                                                               @Override\r
+                                                               public void run(ReadGraphImpl parameter) {\r
+                                                               }\r
+                                                               \r
+                                                       });\r
+                                               \r
+                                               } else {\r
+                                                       \r
+                                               }\r
+                                               \r
+                                       }\r
+                               \r
+                       });\r
+                       \r
+               }\r
+               \r
+               \r
+               }\r
+               \r
+       }\r
+\r
+       @Override\r
+       public boolean isLoaded(int subject) {\r
+       ClusterI cluster = clusterTable.getClusterByResourceKey(subject);\r
+       return cluster.isLoaded();\r
+       }\r
+       \r
+       @Override\r
+       public void ceased(int thread) {\r
+               \r
+               session.ceased(thread);\r
+               \r
+       }\r
+\r
+    @Override\r
+    public Object getLock() {\r
+        \r
+        return session.requestManager;\r
+        \r
+    }\r
+\r
+    @Override\r
+    public VirtualGraph getProvider(int subject, int predicate, int object) {\r
+\r
+       if(subject > 0) {\r
+            ClusterImpl cluster = (ClusterImpl)clusterTable.getClusterByResourceKey(subject);\r
+               // This persistent resource does not have virtual statements => must deny in persistent graph\r
+               if(!cluster.hasVirtual() || !virtualGraphServerSupport.virtuals.contains(subject)) return null;\r
+       }\r
+       \r
+       for(TransientGraph g : virtualGraphServerSupport.providers) {\r
+               for (final int id : g.getObjects(subject, predicate)) {\r
+                       if(object == id) return g;\r
+               }\r
+       }\r
+       \r
+       // Nothing found from virtual graphs\r
+       return null;\r
+               \r
+    }\r
+\r
+    @Override\r
+    public VirtualGraph getProvider(int subject, int predicate) {\r
+\r
+       if(subject > 0) {\r
+            ClusterImpl cluster = (ClusterImpl)clusterTable.getClusterByResourceKey(subject);\r
+               // This persistent resource does not have virtual statements => must deny in persistent graph\r
+               if(!cluster.hasVirtual() || !virtualGraphServerSupport.virtuals.contains(subject)) return null;\r
+       }\r
+\r
+       TransientGraph result = null;\r
+       for(TransientGraph g : virtualGraphServerSupport.providers) {\r
+               if(g.getObjects(subject, predicate).length > 0) {\r
+                       // Found multiple, return null;\r
+                       if(result != null) return null;\r
+                       else result = g;\r
+               }\r
+       }\r
+       return result;\r
+               \r
+    }\r
+\r
+    @Override\r
+    public VirtualGraph getValueProvider(int subject) {\r
+\r
+       if(subject > 0) {\r
+            ClusterImpl cluster = (ClusterImpl)clusterTable.getClusterByResourceKey(subject);\r
+               // This persistent resource does not have virtual statements => must deny in persistent graph\r
+               if(!cluster.hasVirtual() || !virtualGraphServerSupport.virtuals.contains(subject)) return null;\r
+       }\r
+\r
+       TransientGraph result = null;\r
+       for(TransientGraph g : virtualGraphServerSupport.providers) {\r
+               if(g.getValue(subject) != null) {\r
+                       if(result != null) return null;\r
+                       else result = g;\r
+               }\r
+       }\r
+       return result;\r
+               \r
+    }\r
+    \r
+    @Override\r
+    public void exit(Throwable t) {\r
+       state.close();\r
+    }\r
+    \r
+    private void analyseProblem(ClusterI cluster) {\r
+       \r
+       if(cluster instanceof ClusterSmall)\r
+                       try {\r
+                               ((ClusterSmall)cluster).check();\r
+                       } catch (DatabaseException e) {\r
+                               e.printStackTrace();\r
+                       }\r
+       \r
+    }\r
+    \r
+}\r