]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/QuerySupportImpl.java
Merge changes I8dcfd805,Ide5d53a1 into release/1.35.1
[simantics/platform.git] / bundles / org.simantics.db.procore / src / fi / vtt / simantics / procore / internal / QuerySupportImpl.java
1 package fi.vtt.simantics.procore.internal;
2
3 import gnu.trove.set.hash.TIntHashSet;
4
5 import java.io.ByteArrayInputStream;
6 import java.io.InputStream;
7 import java.util.Collection;
8 import java.util.function.Consumer;
9
10 import org.simantics.db.Resource;
11 import org.simantics.db.Session;
12 import org.simantics.db.Statement;
13 import org.simantics.db.VirtualGraph;
14 import org.simantics.db.WriteGraph;
15 import org.simantics.db.common.StandardStatement;
16 import org.simantics.db.common.request.WriteRequest;
17 import org.simantics.db.common.utils.Logger;
18 import org.simantics.db.exception.DatabaseException;
19 import org.simantics.db.exception.InvalidResourceReferenceException;
20 import org.simantics.db.exception.ResourceNotFoundException;
21 import org.simantics.db.impl.ClusterI;
22 import org.simantics.db.impl.ClusterSupport;
23 import org.simantics.db.impl.ForEachObjectContextProcedure;
24 import org.simantics.db.impl.ForEachObjectProcedure;
25 import org.simantics.db.impl.ResourceImpl;
26 import org.simantics.db.impl.TransientGraph;
27 import org.simantics.db.impl.VirtualGraphImpl;
28 import org.simantics.db.impl.graph.ReadGraphImpl;
29 import org.simantics.db.impl.query.IntProcedure;
30 import org.simantics.db.impl.query.QueryProcessor;
31 import org.simantics.db.impl.query.QuerySupport;
32 import org.simantics.db.impl.support.BuiltinSupport;
33 import org.simantics.db.impl.support.ResourceSupport;
34 import org.simantics.db.procore.cluster.ClusterImpl;
35 import org.simantics.db.procore.cluster.ClusterSmall;
36 import org.simantics.db.service.SerialisationSupport;
37 import org.simantics.utils.DataContainer;
38
39 public class QuerySupportImpl implements QuerySupport {
40         
41         final SessionImplSocket session;
42         final State state;
43         final ClusterTable clusterTable;
44         final BuiltinSupport builtinSupport;
45         final ClusterSupport clusterSupport;
46         final ResourceSupport resourceSupport;
47         final SerialisationSupport serializationSupport;
48         final VirtualGraphServerSupportImpl virtualGraphServerSupport;
49         final GraphSession graphSession;
50         final SessionRequestManager syncThreads;
51         final int root;
52
53     private boolean pendingPrimitives = false;
54         
55         QuerySupportImpl(SessionImplSocket session, ClusterSupport clusterSupport, SerialisationSupport serializationSupport, SessionRequestManager syncThreads) {
56                 this.session = session;
57                 this.state = session.state;
58                 this.clusterTable = session.clusterTable;
59                 this.resourceSupport = session.resourceSupport;
60                 this.virtualGraphServerSupport = session.virtualGraphServerSupport;
61                 this.graphSession = session.graphSession;
62                 this.builtinSupport = session.builtinSupport;
63                 this.clusterSupport = clusterSupport;
64                 this.serializationSupport = serializationSupport;
65                 this.syncThreads = syncThreads;
66                 this.root = getBuiltin("http:/");
67                 assert(this.session != null);
68                 assert(this.state != null);
69                 assert(this.clusterTable != null);
70                 assert(this.resourceSupport != null);
71                 assert(this.virtualGraphServerSupport != null);
72                 assert(this.graphSession != null);
73                 assert(this.builtinSupport != null);
74                 assert(this.clusterSupport != null);
75                 assert(this.serializationSupport != null);
76                 assert(this.syncThreads != null);
77         }
78
79         @Override
80         public ResourceSupport getSupport() {
81                 return resourceSupport;
82         }
83         
84     @Override
85     public Statement getStatement(int s, int p, int o) {
86         return getStatement(null, s, p, o);
87     }
88
89     @Override
90     public Statement getStatement(ReadGraphImpl graph, int s, int p, int o) {
91         Resource sr = getResource(s);
92         Resource pr = getResource(p);
93         Resource or = getResource(o);
94         return new StandardStatement(sr, pr, or);
95     }
96
97         @Override
98         public Session getSession() {
99                 return session;
100         }
101
102     @Override
103     public long getClusterId(int id) {
104         ClusterI cluster = clusterTable.getClusterByResourceKey(id);
105         if(cluster == null) return 0;
106         return cluster.getClusterId();
107     }
108     
109     @Override
110     public boolean isImmutable(int id) {
111         // Virtuals are mutable
112         if(id < 0) return false;
113         // Root library is mutable
114         if(root == id) return false;
115         // Anything goes in service mode
116         if(session.serviceMode > 0) return false;
117         return clusterTable.isImmutable(id);
118     }
119
120     @Override
121     public int getId(Resource resource) {
122         if (resource instanceof ResourceImpl)
123             return ((ResourceImpl)resource).id;
124         return 0;
125     }
126
127         @Override
128         public Resource getResource(int id) {
129                 try {
130                         return serializationSupport.getResource(id);
131                 } catch (DatabaseException e) {
132                         e.printStackTrace();
133                 }
134                 return null;
135         }
136
137         @Override
138     public boolean resume(ReadGraphImpl graph) {
139                 
140                 return syncThreads.session.queryProvider2.resume(graph);
141                 
142     }
143
144 //    @Override
145 //    final public void sync(int resumeThread, final SessionRunnable runnable) {
146 //      
147 //      syncThreads.session.queryProvider2.schedule(Integer.MIN_VALUE, new SessionTask(resumeThread) {
148 //
149 //                      @Override
150 //                      public void run(int thread) {
151 //                              runnable.run(thread);
152 //                      }
153 //              
154 //      });
155 //      
156 //    }
157
158 //    @Override
159 //    final public int nextSyncThread() {
160 //      throw new Error();
161 ////        return syncThreads.nextThread();
162 //    }
163
164         @Override
165     public void dirtyPrimitives() {
166         session.dirtyPrimitives = true;
167         if(state.getWriteCount() == 0 && !pendingPrimitives) {
168             pendingPrimitives = true;
169             session.asyncRequest(new WriteRequest() {
170
171                 @Override
172                 public void perform(WriteGraph graph) throws DatabaseException {
173                     pendingPrimitives = false;
174                 }
175                 
176             });
177         }
178     }
179
180     @Override
181     @Deprecated
182     final public void aboutToRead() {
183     }
184
185 //    @Override
186 //    public void increaseReferenceCount(int callerThread, int subject) {
187 //        if (subject < 0)
188 //            return;
189 //        ClusterI proxy = clusterTable.getClusterByResourceKey(subject);
190 //        if (null == proxy)
191 //            return;
192 //        proxy.increaseReferenceCount(callerThread, 1);
193 //    }
194 //
195 //    @Override
196 //    public void decreaseReferenceCount(int callerThread, int subject) {
197 //        if (subject < 0)
198 //            return;
199 //        ClusterProxy proxy = clusterTable.getClusterByResourceKey(subject);
200 //        if (null == proxy)
201 //            return;
202 //        proxy.decreaseReferenceCount(callerThread, 1);
203 //    }
204
205 //      @Override
206         public void getObjects4(final ReadGraphImpl graph, final int subject, final ForEachObjectProcedure procedure) {
207                 
208                 if(subject < 0) {
209                         
210                         for(TransientGraph g : virtualGraphServerSupport.providers) {
211                 for (final int id : g.getObjects(subject, procedure.predicateKey)) {
212
213 //                    int suggestSchedule = graph.processor.processor.resourceThread(id);
214 //                    if(graph.callerThread == suggestSchedule) {
215                         procedure.execute(graph, new ResourceImpl(resourceSupport, id));
216 //                    } else {
217 //                      graph.processor.processor.schedule(graph.callerThread, new SessionTask(suggestSchedule) {
218 //              
219 //                              @Override
220 //                              public void run(int thread) {
221 //                              procedure.execute(graph.newAsync(thread), new ResourceImpl(resourceSupport, id));
222 //                              }
223 //              
224 //                      });
225 //                    }
226                         
227                 }
228                         }
229                         procedure.finished(graph);
230 //              graph.dec();
231                 return;
232                 
233                 } 
234                 
235         final ClusterImpl cluster = (ClusterImpl)clusterTable.getClusterByResourceKey(subject);
236         if(!cluster.isLoaded()) {
237                 cluster.load(session.clusterTranslator, new Runnable() {
238
239                                 @Override
240                                 public void run() {
241                                         getObjects4(graph, subject, procedure);
242                                 }
243                         
244                 });
245                 return;
246         }
247                 
248                 if (cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(subject)) {
249                         
250                         for(TransientGraph g : virtualGraphServerSupport.providers) {
251                 for (final int id : g.getObjects(subject, procedure.predicateKey)) {
252 //                    int suggestSchedule = graph.processor.processor.resourceThread(id);
253 //                    if(graph.callerThread == suggestSchedule) {
254                         procedure.execute(graph, new ResourceImpl(resourceSupport, id));
255 //                    } else {
256 //                      graph.processor.processor.schedule(graph.callerThread, new SessionTask(suggestSchedule) {
257 //              
258 //                              @Override
259 //                              public void run(int thread) {
260 //                              procedure.execute(graph.newAsync(thread), new ResourceImpl(resourceSupport, id));
261 //                              }
262 //              
263 //                      });
264 //                    }
265                 }
266                         }
267                         
268                         try {
269                                 cluster.forObjects(graph, subject, procedure);
270                         } catch (DatabaseException e) {
271                                 e.printStackTrace();
272                         }
273                         
274                 } else {
275                         
276                         try {
277                                 cluster.forObjects(graph, subject, procedure);
278                         } catch (DatabaseException e) {
279                                 e.printStackTrace();
280                         }
281                         
282                 }
283                 
284         }
285
286         public <C> void getObjects4(final ReadGraphImpl graph, final int subject, final C context, final ForEachObjectContextProcedure<C> procedure) {
287                 
288                 if(subject < 0) {
289                         
290                         for(TransientGraph g : virtualGraphServerSupport.providers) {
291                 for (final int id : g.getObjects(subject, procedure.predicateKey)) {
292
293 //                    int suggestSchedule = graph.processor.processor.resourceThread(id);
294 //                    if(graph.callerThread == suggestSchedule) {
295                         procedure.execute(graph, context, new ResourceImpl(resourceSupport, id));
296 //                    } else {
297 //                      graph.processor.processor.schedule(graph.callerThread, new SessionTask(suggestSchedule) {
298 //              
299 //                              @Override
300 //                              public void run(int thread) {
301 //                              procedure.execute(graph.newAsync(thread), context, new ResourceImpl(resourceSupport, id));
302 //                              }
303 //              
304 //                      });
305 //                    }
306                         
307                 }
308                         }
309                         procedure.finished(graph, context);
310 //              graph.dec();
311                 return;
312                 
313                 } 
314                 
315         final ClusterImpl cluster = (ClusterImpl)clusterTable.getClusterByResourceKey(subject);
316         if(!cluster.isLoaded()) {
317                 cluster.load(session.clusterTranslator, new Runnable() {
318
319                                 @Override
320                                 public void run() {
321                                         getObjects4(graph, subject, context, procedure);
322                                 }
323                         
324                 });
325                 return;
326         }
327                 
328                 if (cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(subject)) {
329                         
330                         for(TransientGraph g : virtualGraphServerSupport.providers) {
331                 for (final int id : g.getObjects(subject, procedure.predicateKey)) {
332 //                    int suggestSchedule = graph.processor.processor.resourceThread(id);
333 //                    if(graph.callerThread == suggestSchedule) {
334                         procedure.execute(graph, context, new ResourceImpl(resourceSupport, id));
335 //                    } else {
336 //                      graph.processor.processor.schedule(graph.callerThread, new SessionTask(suggestSchedule) {
337 //              
338 //                              @Override
339 //                              public void run(int thread) {
340 //                              procedure.execute(graph.newAsync(thread), context, new ResourceImpl(resourceSupport, id));
341 //                              }
342 //              
343 //                      });
344 //                    }
345                 }
346                         }
347                         
348                         try {
349                                 cluster.forObjects(graph, subject, context, procedure);
350                         } catch (DatabaseException e) {
351                                 e.printStackTrace();
352                         }
353                         
354                 } else {
355                         
356                         try {
357                                 cluster.forObjects(graph, subject, context, procedure);
358                         } catch (DatabaseException e) {
359                                 e.printStackTrace();
360                         }
361                         
362                 }
363                 
364         }
365         
366         @Override
367     public int getSingleInstance(final int subject) {
368         
369         // Do not process this information for virtual resources
370         if(subject < 0) return 0;
371         
372         final ClusterI cluster = clusterTable.getClusterByResourceKey(subject);
373         if (cluster == null)
374             System.out.println("null cluster: " + Integer.toString(subject, 16));
375         assert (cluster != null);
376
377         try {
378         
379                 ClusterI.CompleteTypeEnum type = cluster.getCompleteType(subject, clusterSupport);
380                 if(ClusterI.CompleteTypeEnum.InstanceOf == type) {
381                         int result = cluster.getCompleteObjectKey(subject, clusterSupport);
382                         assert(result > 0);
383                         return result;
384                 } else {
385                         return 0;
386                 }
387         
388         } catch (DatabaseException e) {
389                 
390                 Logger.defaultLogError(e);
391                 return 0;
392                 
393         }
394         // This happens is the resource is bogus
395         catch (Throwable t) {
396                 
397                 analyseProblem(cluster);
398                 
399                 Logger.defaultLogError(t);
400                 
401                 return 0;
402                 
403         }
404         
405     }
406
407         @Override
408     public int getSingleSuperrelation(final int subject) {
409         
410         // Do not process this information for virtual resources
411         if(subject < 0) return 0;
412
413         final ClusterI cluster = clusterTable.getClusterByResourceKey(subject);
414         if (cluster == null)
415             System.out.println("null cluster: " + Integer.toString(subject, 16));
416         assert (cluster != null);
417
418         try {
419         
420                 ClusterI.CompleteTypeEnum type = cluster.getCompleteType(subject, clusterSupport);
421                 if(ClusterI.CompleteTypeEnum.SubrelationOf == type) {
422                         int result = cluster.getCompleteObjectKey(subject, clusterSupport);
423                         assert(result > 0);
424                         return result;
425                 } else {
426                         return 0;
427                 }
428         
429         } catch (DatabaseException e) {
430                 
431                 Logger.defaultLogError(e);
432                 return 0;
433                 
434         }
435         
436     }
437
438 //      @Override
439 //    public void getSingleSuperrelation(ReadGraphImpl graph, final int subject, final AsyncProcedure<Resource> procedure) {
440 //      
441 //      // Do not process this information for virtual resources
442 //      if(subject < 0) {
443 //              procedure.execute(graph, null);
444 //                      graph.state.barrier.dec();
445 //              return;
446 //      }
447 //
448 //      final ClusterI cluster = clusterTable.getClusterByResourceKey(subject);
449 //        if (cluster == null)
450 //            System.out.println("null cluster: " + Integer.toString(subject, 16));
451 //        
452 //        assert (cluster != null);
453 //
454 //        if(!cluster.isLoaded()) {
455 //            
456 //              procedure.execute(graph, null);
457 //                      graph.state.barrier.dec();
458 //              return;
459 //
460 ////            queryProvider2.requestCluster(callerThread, cluster.getClusterId(), new Callback<Integer>() {
461 ////    
462 ////                            @Override
463 ////                            public void run(Integer i) {
464 ////    
465 ////                                    queryProvider2.schedule(i, callerThread, new Runnable() {
466 ////    
467 ////                                            @Override
468 ////                                            public void run() {
469 ////                                                    
470 ////                                                    try  {
471 ////                                                    
472 ////                                                ClusterI.CompleteTypeEnum type = cluster.getCompleteType(callerThread, subject, SessionImplSocket.this);
473 ////                                                if(ClusterI.CompleteTypeEnum.SubrelationOf == type) {
474 ////                                                    int result = cluster.getCompleteObjectKey(callerThread, subject, SessionImplSocket.this);
475 ////                                                    assert(result > 0);
476 ////                                                    procedure.execute(graph, getResourceByKey(result));
477 ////                                                } else {
478 ////                                                    procedure.execute(graph, null);
479 ////                                                }
480 ////                                                            graph.state.barrier.dec();
481 ////                                                            
482 ////                                                    } catch (DatabaseException e) {
483 ////                                                            e.printStackTrace();
484 ////                                                    }
485 ////                                                    
486 ////                                            }
487 ////    
488 ////                                    });
489 ////    
490 ////                            }
491 ////    
492 ////                    });
493 //                      
494 //        } else {
495 //
496 //              try {
497 //
498 //                      ClusterI.CompleteTypeEnum type = cluster.getCompleteType(graph.callerThread, subject, clusterSupport);
499 //                      if(ClusterI.CompleteTypeEnum.SubrelationOf == type) {
500 //                              int result = cluster.getCompleteObjectKey(graph.callerThread, subject, clusterSupport);
501 //                              assert(result > 0);
502 //                              procedure.execute(graph, new ResourceImpl(resourceSupport, result));
503 //                      } else {
504 //                              procedure.execute(graph, null);
505 //                      }
506 //                      graph.state.barrier.dec();
507 //
508 //              } catch (DatabaseException e) {
509 //                      e.printStackTrace();
510 //              }
511 //                      
512 //        }
513 //        
514 //        
515 //    }
516
517 //      @Override
518 //    public void getObjects2(final int callerThread, final int subject, final int predicate, final IntProcedure procedure) {
519 //              ensureLoaded(callerThread, subject, predicate, new Runnable() {
520 //
521 //                      @Override
522 //                      public void run() {
523 //                              safeGetObjects2(callerThread, subject, predicate, procedure);
524 //                      }
525 //                      
526 //              });
527 //      }
528
529 //    public void safeGetObjects2(final ReadGraphImpl graph, final int subject, final int predicate, final IntProcedure procedure) {
530 //
531 //        assert (subject != 0);
532 //        assert (predicate != 0);
533 ////        System.out.println("getObjects2: s=" + subject + "p=" + predicate);
534 //        Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(subject);
535 //        if (providers != null) {
536 //
537 //            final TIntHashSet result = new TIntHashSet(16);
538 //
539 //            for (VirtualGraph provider : providers) {
540 //
541 //                for (int id : ((VirtualGraphImpl)provider).getObjects(subject, predicate)) {
542 //
543 //                    if (result.add(id)) {
544 //                      procedure.execute(graph, id);
545 //                    }
546 //
547 //                }
548 //
549 //            }
550 //
551 //            if (subject < 0)
552 //                return;
553 //
554 //            final ClusterI cluster = clusterTable.getClusterByResourceKey(subject);
555 //
556 //            assert (testCluster(subject, cluster));
557 //            
558 //            // wheels within wheels
559 //            final ClusterI.ObjectProcedure<Object> proc = new ClusterI.ObjectProcedure<Object>() {
560 //
561 //                @Override
562 //                public boolean execute(int callerThread, Object context, int object) {
563 //
564 //                    if (result.add(object)) {
565 //                      procedure.execute(graph.newAsync(callerThread), object);
566 //                    }
567 //
568 //                    return false; // continue looping
569 //
570 //                }
571 //                
572 //                              @Override
573 //                              public boolean found() {
574 //                                      throw new UnsupportedOperationException();
575 //                              }
576 //                
577 //            };
578 //
579 //            try {
580 //                cluster.forObjects(graph.callerThread, subject, predicate, proc, null, clusterSupport);
581 //            } catch (DatabaseException e) {
582 //                Logger.defaultLogError(e);
583 //            } catch (Throwable t) {
584 //                Logger.defaultLogError(t);
585 //              t.printStackTrace();
586 //            }
587 //            return;
588 //            
589 //        }
590 //        
591 //        assert(subject > 0);
592 //
593 //        final ClusterI cluster = clusterTable.getClusterByResourceKey(subject);
594 //
595 //        assert (testCluster(subject, cluster));
596 //        
597 //        try {
598 //            cluster.forObjects(graph.callerThread, subject, predicate, new Wheels(procedure), null, clusterSupport);
599 //        } catch (DatabaseException e) {
600 //            Logger.defaultLogError(e);
601 //        } catch (Throwable t) {
602 //              t.printStackTrace();
603 //            Logger.defaultLogError(t);
604 //        }
605 //        
606 //    }
607
608         @Override
609     public boolean getObjects(final ReadGraphImpl graph, final int subject, final int predicate, final IntProcedure procedure) {
610                 
611                 assert (subject != 0);
612                 assert (predicate != 0);
613
614                 if(subject < 0) {
615
616                         boolean found = false;
617                         
618                         for(TransientGraph g : virtualGraphServerSupport.providers) {
619                                 for (final int id : g.getObjects(subject, predicate)) {
620                                         found = true;
621                                         procedure.execute(graph, id);
622                                 }
623                         }
624                         
625                         return found;
626
627                 }
628
629                 final ClusterI cluster = clusterTable.getClusterByResourceKey(subject);
630                 assert(cluster.isLoaded());
631         
632         if (cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(subject)) {
633                 
634                 final DataContainer<Boolean> found = new DataContainer<Boolean>(Boolean.FALSE);
635                 final TIntHashSet result = new TIntHashSet(5);
636                 
637                         for(TransientGraph g : virtualGraphServerSupport.providers) {
638                                 for (final int id : g.getObjects(subject, predicate)) {
639
640                                         found.set(true);
641                                         if (result.add(id)) {
642                                                 procedure.execute(graph, id);
643                                         }
644
645                                 }
646                         }
647                         
648                         // Virtual predicates are not found from persistent clusters
649                         if(predicate < 0) return found.get();
650
651                 // wheels within wheels
652                 final ClusterI.ObjectProcedure<Object> proc = new ClusterI.ObjectProcedure<Object>() {
653
654                         @Override
655                         public boolean execute(Object context, int object) {
656
657                                 found.set(true);
658                                 if (result.add(object)) {
659                                         procedure.execute(graph, object);
660                                 }
661
662                                 return false; // continue looping
663
664                         }
665
666                 };
667                         
668                         try {
669                 cluster.forObjects(subject, predicate, proc, null, clusterSupport);
670                         } catch (DatabaseException e) {
671                                 e.printStackTrace();
672                         }
673                         
674                         return found.get();
675                         
676                 } else {
677                         
678                         // Virtual predicates are not found from persistent clusters
679                         if(predicate < 0) return false;
680                         
681                         class A implements ClusterI.ObjectProcedure<Object> {
682
683                         boolean found = false;
684
685                         @Override
686                         public boolean execute(Object context, int object) {
687
688                                 found = true;
689                                 procedure.execute(graph, object);
690
691                                 return false; // continue looping
692
693                         }
694
695                                 public boolean found() {
696                                         return found;
697                                 }
698
699                         }
700                         
701                 // wheels within wheels
702                 final A proc = new A();
703                 
704                         try {
705                 cluster.forObjects(subject, predicate, proc, null, clusterSupport);
706                         } catch (DatabaseException e) {
707                                 e.printStackTrace();
708                         } 
709                         // This happens if resource is bogus
710                         catch (Throwable t) {
711                                 
712                         analyseProblem(cluster);
713                         
714                         Logger.defaultLogError(t);
715                                 
716                         }
717                 
718                 return proc.found();
719                         
720                 }
721         
722     }
723
724 //      @Override
725 //    public boolean getFunctionalObject(final ReadGraphImpl graph, final int subject, final int predicate,
726 //            final IntProcedure procedure) {
727 //
728 //        assert (subject != 0);
729 //        assert (predicate != 0);
730 //
731 //        if(subject < 0) {
732 //
733 //              boolean found = false;
734 //
735 //              Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(subject);
736 //              if (providers != null) {
737 //
738 //                      for (VirtualGraph provider : providers) {
739 //
740 //                              for (int id : ((VirtualGraphImpl)provider).getObjects(subject, predicate)) {
741 //                                      found = true;
742 //                      procedure.execute(graph, id);
743 //                    }
744 //
745 //                }
746 //
747 //            }
748 //              
749 //              return found;
750 //              
751 //        }
752 //        
753 //        final ClusterI cluster = clusterTable.getClusterByResourceKey(subject);
754 //        
755 //        if (cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(subject)) {
756 //        
757 //              final DataContainer<Boolean> found = new DataContainer<Boolean>(false);
758 //              final TIntHashSet result = new TIntHashSet(5);
759 //
760 //              Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(subject);
761 //              if (providers != null) {
762 //
763 //                      for (VirtualGraph provider : providers) {
764 //
765 //                              for (int id : ((VirtualGraphImpl)provider).getObjects(subject, predicate)) {
766 //                                      found.set(true);
767 //                      procedure.execute(graph, id);
768 //                    }
769 //
770 //                }
771 //
772 //            }
773 //              
774 //            // wheels within wheels
775 //            final ClusterI.ObjectProcedure<Object> proc = new ClusterI.ObjectProcedure<Object>() {
776 //
777 //                @Override
778 //                public boolean execute(int callerThread, Object context, int object) {
779 //
780 //                    found.set(true);
781 //                    System.out.println("-found object " + object);
782 //                    if (result.add(object)) {
783 //                      procedure.execute(graph.newAsync(callerThread), object);
784 //                    }
785 //
786 //                    return false; // continue looping
787 //
788 //                }
789 //                
790 //                              @Override
791 //                              public boolean found() {
792 //                                      throw new UnsupportedOperationException();
793 //                              }
794 //                
795 //            };
796 //            
797 //            try {
798 //                cluster.forObjects(graph.callerThread, subject, predicate, proc, null, clusterSupport);
799 //            } catch (DatabaseException e) {
800 //                Logger.defaultLogError(e);
801 //                return false;
802 //            } catch (Throwable t) {
803 //                Logger.defaultLogError(t);
804 //              t.printStackTrace();
805 //            }
806 //            
807 //            return found.get();
808 //            
809 //        } else {
810 //
811 //              // wheels within wheels
812 //              final ClusterI.ObjectProcedure<Object> proc = new ClusterI.ObjectProcedure<Object>() {
813 //                  
814 //                      boolean found = false;
815 //                      
816 //                  @Override
817 //                  public boolean execute(int callerThread, Object context, int object) {
818 //      
819 //                      found = true;
820 //                      procedure.execute(graph.newAsync(callerThread), object);
821 //                      return false; // continue looping
822 //                      
823 //                  }
824 //                  
825 //                              @Override
826 //                              public boolean found() {
827 //                                      return found;
828 //                              }
829 //                  
830 //                  @Override
831 //                  public String toString() {
832 //                      return "Wheels for " + procedure;
833 //                  }
834 //                  
835 //              };
836 //              
837 //              try {
838 //                  cluster.forObjects(graph.callerThread, subject, predicate, proc, null, clusterSupport);
839 //              } catch (DatabaseException e) {
840 //                  Logger.defaultLogError(e);
841 //                  return false;
842 //              } catch (Throwable t) {
843 //                      t.printStackTrace();
844 //                  Logger.defaultLogError(t);
845 //                  return false;
846 //              }
847 //              
848 //              return proc.found();
849 //        
850 //        }
851 //        
852 //    }
853         
854         @Override
855     public int getFunctionalObject(final int subject, final int predicate) {
856
857         assert (subject != 0);
858         assert (predicate != 0);
859
860         if(subject < 0) {
861
862                 int found = 0;
863
864                 Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(subject);
865                 if (providers != null) {
866
867                         for (VirtualGraph provider : providers) {
868
869                                 for (int id : ((VirtualGraphImpl)provider).getObjects(subject, predicate)) {
870                                         if(found == 0) found = id;
871                                         else found = -1;
872                     }
873
874                 }
875
876             }
877                 
878                 return found;
879 //              if(found == -1) return 0;
880 //              else return found;
881                 
882         }
883         
884         final ClusterI cluster = clusterTable.getClusterByResourceKey(subject);
885         
886         if (cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(subject)) {
887
888                 int result = 0;
889                 Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(subject);
890                 if (providers != null) {
891
892                         for (VirtualGraph provider : providers) {
893
894                                 for (int id : ((VirtualGraphImpl)provider).getObjects(subject, predicate)) {
895                                         if(result == 0) result = id;
896                                         else result = -1;
897                     }
898
899                 }
900
901             }
902                 
903                 if(result != 0) return result; 
904             
905                 try {
906                                 return cluster.getSingleObject(subject, predicate, clusterSupport);
907                         } catch (DatabaseException e) {
908                                 return -1;
909                         }
910             
911         } else {
912
913                 try {
914                                 return cluster.getSingleObject(subject, predicate, clusterSupport);
915                         } catch (DatabaseException e) {
916                                 return -1;
917                         }
918                 // This comes if the resource is bogus
919                 catch (Throwable t) {
920                         
921                 analyseProblem(cluster);
922                 
923                 Logger.defaultLogError(t);
924                         
925                                 return -1;
926                                 
927                         }
928         
929         }
930         
931     }
932
933 //      @Override
934 //    public boolean getStatements(final ReadGraphImpl graph, final int subject, final int predicate,
935 //            final TripleIntProcedure procedure, final Statements entry) {
936 //
937 //        assert (subject != 0);
938 //        assert (predicate != 0);
939 //
940 //        final TIntHashSet result = new TIntHashSet(16);
941 //        final DataContainer<Boolean> found = new DataContainer<Boolean>(false);
942 //
943 //        Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(subject);
944 //        
945 //        if (providers != null) {
946 //
947 //            for (VirtualGraph provider : providers) {
948 //
949 //                for (int id : ((VirtualGraphImpl)provider).getObjects(subject, predicate)) {
950 //
951 //                    found.set(true);
952 //
953 //                    if (result.add(id)) {
954 //                        if (null != entry) {
955 //                            entry.addOrSet(subject, predicate, id);
956 //                            procedure.execute(graph, subject, predicate, id);
957 //                            return true; // break;
958 //                        } else {
959 //                            procedure.execute(graph, subject, predicate, id);
960 //                        }
961 //                    }
962 //
963 //                }
964 //
965 //            }
966 //
967 //        }
968 //
969 //        if (subject < 0)
970 //            return found.get();
971 //
972 //        final ClusterI cluster = clusterTable.getClusterByResourceKey(subject);
973 //        assert (cluster != null);
974 //
975 //        // wheels within wheels
976 //        final ClusterI.ObjectProcedure<Object> proc = new ClusterI.ObjectProcedure<Object>() {
977 //            @Override
978 //            public boolean execute(int callerThread, Object context, int object) {
979 //
980 //                found.set(true);
981 //
982 //                if (result.add(object)) {
983 //                    if (null != entry) {
984 //                        entry.addOrSet(subject, predicate, object);
985 //                        procedure.execute(graph.newAsync(callerThread), subject, predicate, object);
986 //                        return true; // break;
987 //                    } else {
988 //                        procedure.execute(graph.newAsync(callerThread), subject, predicate, object);
989 //                    }
990 //                }
991 //
992 //                return false; // continue looping
993 //
994 //            }
995 //            
996 //                      @Override
997 //                      public boolean found() {
998 //                              throw new UnsupportedOperationException();
999 //                      }
1000 //            
1001 //        };
1002 //
1003 //        try {
1004 //            cluster.forObjects(graph.callerThread, subject, predicate, proc, null, clusterSupport);
1005 //        } catch (DatabaseException e) {
1006 //            Logger.defaultLogError(e);
1007 //        }
1008 //        return found.get();
1009 //
1010 //    }
1011
1012         @Override
1013     public org.simantics.db.DirectStatements getStatements(final ReadGraphImpl graph, final int subject, final QueryProcessor processor, boolean ignoreVirtual) {
1014
1015         assert (subject != 0);
1016
1017         final DirectStatementsImpl result = new DirectStatementsImpl(resourceSupport, subject);
1018
1019         if (!ignoreVirtual) {
1020             Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(subject);
1021             if (providers != null) {
1022                 for (TransientGraph provider : providers) {
1023                     for (int p : provider.getPredicates(subject)) {
1024                         for (int o : provider.getObjects(subject, p)) {
1025                             result.addStatement(p, o);
1026                         }
1027                     }
1028                 }
1029             }
1030         }
1031
1032         if (subject < 0) {
1033                 return result;
1034         } else {
1035             final ClusterI cluster = clusterTable.getClusterByResourceKey(subject);
1036             assert (cluster != null);
1037             doGetStatements(graph, cluster, subject, result);
1038         }
1039         
1040         return result;
1041
1042     }
1043
1044 //    @Override
1045 //    public void getStatements(ReadGraphImpl graph, final int subject, final Procedure<DirectStatements> procedure) {
1046 //      
1047 //              procedure.exception(new DatabaseException("Not supported"));
1048 //              
1049 //    }
1050
1051     @Override
1052     public void getPredicates(final ReadGraphImpl graph, final int subject, final IntProcedure procedure) {
1053
1054         final TIntHashSet result = new TIntHashSet(16);
1055
1056         Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(subject);
1057         
1058         if (providers != null) {
1059
1060             for (VirtualGraph provider : providers) {
1061
1062                 for (int id : ((VirtualGraphImpl)provider).getPredicates(subject)) {
1063
1064                     if (result.add(id)) {
1065                         procedure.execute(graph, id);
1066                     }
1067
1068                 }
1069
1070             }
1071
1072         }
1073
1074         if (subject < 0) {
1075             procedure.finished(graph);
1076             return;
1077         }
1078
1079         ClusterI proxy = clusterTable.getClusterByResourceKey(subject);
1080 //        if(!proxy.isLoaded()) {
1081 //              
1082 //              proxy.load(callerThread, session, new Runnable() {
1083 //
1084 //                              @Override
1085 //                              public void run() {
1086 //                                      getPredicates(callerThread, subject, procedure);
1087 //                              }
1088 //                      
1089 //              });
1090 //              return;
1091 //              
1092 //        }
1093         assert (proxy != null);
1094
1095         final DataContainer<Integer> got = new DataContainer<Integer>(0);
1096         ClusterI.PredicateProcedure<Object> proc = new ClusterI.PredicateProcedure<Object>() {
1097             @Override
1098             public boolean execute(Object context, int predicate, int oi) {
1099                 if (result.add(predicate)) {
1100                     procedure.execute(graph, predicate);
1101                 }
1102                 got.set(got.get() + 1);
1103                 return false; // continue looping
1104             }
1105         };
1106         try {
1107             proxy.forPredicates(subject, proc, null, clusterSupport);
1108         } catch (DatabaseException e) {
1109             Logger.defaultLogError(e);
1110         }
1111         procedure.finished(graph);
1112
1113     }
1114     
1115     
1116
1117 //    @Override
1118 //    public void getValue(ReadGraphImpl graph, int resource, InternalProcedure<byte[]> procedure) {
1119 //
1120 //      if(resource < 0) {
1121 //      
1122 //              Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(resource);
1123 //              
1124 //              if (providers != null) {
1125 //      
1126 //                  for (VirtualGraph provider : providers) {
1127 //      
1128 //                      Object value = ((VirtualGraphImpl)provider).getValue(resource);
1129 //                      if (value != null) {
1130 //                          procedure.execute(graph, (byte[])value);
1131 //                          return;
1132 //                      }
1133 //      
1134 //                  }
1135 //      
1136 //              }
1137 //              
1138 //              return;
1139 //        
1140 //      }
1141 //      
1142 //      ClusterI cluster = clusterTable.getClusterByResourceKey(resource);
1143 //        if (cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(resource)) {
1144 //              
1145 //              Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(resource);
1146 //              
1147 //              if (providers != null) {
1148 //      
1149 //                  for (VirtualGraph provider : providers) {
1150 //      
1151 //                      Object value = ((VirtualGraphImpl)provider).getValue(resource);
1152 //                      if (value != null) {
1153 //                          procedure.execute(graph, (byte[])value);
1154 //                          return;
1155 //                      }
1156 //      
1157 //                  }
1158 //      
1159 //              }
1160 //              
1161 //              try {
1162 //                      
1163 //                      byte[] data = cluster.getValue(resource, clusterSupport);
1164 //                      if (null == data || 0 == data.length) {
1165 //                          procedure.execute(graph, null);
1166 //                      } else {
1167 //                          procedure.execute(graph, data);
1168 //                      }
1169 //                      
1170 //              } catch (DatabaseException e) {
1171 //                  Logger.defaultLogError(e);
1172 //              }
1173 //              
1174 //        } else {
1175 //
1176 //              try {
1177 //                      
1178 //                      byte[] data = cluster.getValue(resource, clusterSupport);
1179 //                      if (null == data || 0 == data.length) {
1180 //                          procedure.execute(graph, null);
1181 //                      } else {
1182 //                          procedure.execute(graph, data);
1183 //                      }
1184 //                      
1185 //              } catch (DatabaseException e) {
1186 //                  Logger.defaultLogError(e);
1187 //              }
1188 //
1189 //        }
1190 //
1191 //    }
1192
1193
1194     @Override
1195     public byte[] getValue(ReadGraphImpl graph, int resource) {
1196
1197         if(resource < 0) {
1198         
1199                 Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(resource);
1200                 
1201                 if (providers != null) {
1202         
1203                     for (VirtualGraph provider : providers) {
1204         
1205                         Object value = ((VirtualGraphImpl)provider).getValue(resource);
1206                         if (value != null) {
1207                                 return (byte[])value;
1208                         }
1209         
1210                     }
1211         
1212                 }
1213                 
1214                 return null;
1215         
1216         }
1217         
1218         ClusterI cluster = clusterTable.getClusterByResourceKey(resource);
1219         if (cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(resource)) {
1220                 
1221                 Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(resource);
1222                 
1223                 if (providers != null) {
1224         
1225                     for (VirtualGraph provider : providers) {
1226         
1227                         Object value = ((VirtualGraphImpl)provider).getValue(resource);
1228                         if (value != null) {
1229                                 return (byte[])value;
1230                         }
1231         
1232                     }
1233         
1234                 }
1235                 
1236                 try {
1237                         
1238                         byte[] data = cluster.getValue(resource, clusterSupport);
1239                         if (null != data && 0 != data.length) {
1240                                 return data;
1241                         }
1242                         
1243                 } catch (DatabaseException e) {
1244                     Logger.defaultLogError(e);
1245                 }
1246                 
1247                 return null;
1248                 
1249         } else {
1250
1251                 try {
1252                         
1253                         byte[] data = cluster.getValue(resource, clusterSupport);
1254                         if (null != data && 0 != data.length) {
1255                                 return data;
1256                         }
1257                         
1258                 } catch (DatabaseException e) {
1259                     Logger.defaultLogError(e);
1260                 }
1261                 
1262                 return null;
1263
1264         }
1265
1266     }
1267
1268     @Override
1269     public InputStream getValueStream(ReadGraphImpl graph, int resource) {
1270
1271         if(resource < 0) {
1272         
1273             Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(resource);
1274             
1275             if (providers != null) {
1276     
1277                 for (VirtualGraph provider : providers) {
1278     
1279                     Object value = ((VirtualGraphImpl)provider).getValue(resource);
1280                     if (value != null) {
1281                         return new ByteArrayInputStream((byte[])value);
1282                     }
1283     
1284                 }
1285     
1286             }
1287             
1288             return null;
1289         
1290         }
1291         
1292         ClusterI cluster = clusterTable.getClusterByResourceKey(resource);
1293         if (cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(resource)) {
1294             
1295             Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(resource);
1296             
1297             if (providers != null) {
1298     
1299                 for (VirtualGraph provider : providers) {
1300     
1301                     Object value = ((VirtualGraphImpl)provider).getValue(resource);
1302                     if (value != null) {
1303                         return new ByteArrayInputStream((byte[])value);
1304                     }
1305     
1306                 }
1307     
1308             }
1309             
1310             try {
1311                 
1312                 return cluster.getValueStream(resource, clusterSupport);
1313                 
1314             } catch (DatabaseException e) {
1315                 Logger.defaultLogError(e);
1316             }
1317             
1318             return null;
1319             
1320         } else {
1321
1322             try {
1323                 
1324                 return cluster.getValueStream(resource, clusterSupport);
1325                 
1326             } catch (DatabaseException e) {
1327                 Logger.defaultLogError(e);
1328             }
1329             
1330             return null;
1331
1332         }
1333
1334     }
1335     
1336     @Override
1337     public void requestCluster(ReadGraphImpl graph, final long clusterId, final Runnable r) {
1338
1339         class CallbackAdapter implements Consumer<DatabaseException> {
1340                 final Runnable r;
1341                 CallbackAdapter(final Runnable r) {
1342                         this.r = r;
1343                 }
1344                 @Override
1345                 public void accept(DatabaseException e) {
1346                         if (null != e)
1347                                 e.printStackTrace();
1348                         else
1349                                 r.run();
1350                 }
1351                 
1352         }
1353         
1354         double p = clusterTable.getLoadProbability();
1355 // System.out.print("Load cluster " + clusterId + " with probability " + p +
1356         // " -> ");
1357         final ClusterI proxy = clusterSupport.getClusterByClusterId(clusterId);
1358         if (!proxy.isLoaded()) {
1359                 clusterTable.gc();
1360             if (Math.random() < p) {
1361                 proxy.load(new CallbackAdapter(r));
1362             } else {
1363                 r.run();
1364             }
1365         } else {
1366             r.run();
1367         }
1368
1369     }
1370
1371     @Override
1372     public int getBuiltin(String uri) {
1373         return builtinSupport.getBuiltin(uri);
1374     }
1375
1376     @Override
1377     public void checkTasks() {
1378         System.out.println(syncThreads.toString());
1379     }
1380
1381 //    @Override
1382 //    public void asyncWrite(Write request) {
1383 //        
1384 ////            if(plainWrite(writer) && sameProvider(request)) {
1385 ////                    writer.writeSupport.pushRequest(request);
1386 ////            } else {
1387 //              asyncRequest(request);
1388 ////            }
1389 //        
1390 //    }
1391
1392     /*
1393      * Helpers
1394      * 
1395      * 
1396      */
1397     
1398     private void doGetStatements(ReadGraphImpl graph, final ClusterI cluster, final int subject, final DirectStatementsImpl result) {
1399
1400         final class Proc implements ClusterI.PredicateProcedure<Object> {
1401
1402                         @Override
1403                         public boolean execute(Object context, final int predicate, final int objectIndex) {
1404                                 
1405                                 doExecute(null, predicate, objectIndex);
1406                                 return false;
1407                                 
1408                         }
1409
1410                         private void doExecute(Object context, final int predicate, final int objectIndex) {
1411
1412                                 try {
1413                                         cluster.forObjects(subject, predicate, new ClusterI.ObjectProcedure<Object>() {
1414
1415                                                 @Override
1416                                                 public boolean execute(Object context, int object) {
1417                                                         result.addStatement(predicate, object);
1418                                                         return false;
1419                                                 }
1420
1421                                         }, null, clusterSupport);
1422                                 } catch (DatabaseException e) {
1423                                         e.printStackTrace();
1424                                 }
1425                                 
1426                         }
1427                 
1428         }
1429
1430         try {
1431                         cluster.forPredicates(subject, new Proc(), null, clusterSupport);
1432                 } catch (DatabaseException e) {
1433                         e.printStackTrace();
1434                 }
1435         
1436     }
1437     
1438 //      private void getDirectObjects4(final int callerThread, final ClusterI cluster, final int subject, final int predicate, final QueryProcessor processor, final ReadGraphImpl graph, final ForEachObjectProcedure procedure) {
1439 //
1440 //        if(!cluster.isLoaded()) {
1441 //
1442 //                      requestCluster(callerThread, cluster.getClusterId(), new Callback<Integer>() {
1443 //      
1444 //                              @Override
1445 //                              public void run(Integer i) {
1446 //      
1447 //                                      processor.schedule(i, new SessionTask(callerThread) {
1448 //      
1449 //                                              @Override
1450 //                                              public void run(int thread) {
1451 //                                                      
1452 //                                                      getDirectObjects4(thread, cluster, subject, predicate, processor, graph, procedure);
1453 //                                                      
1454 //                                              }
1455 //      
1456 //                                      });
1457 //      
1458 //                              }
1459 //      
1460 //                      });
1461 //                      
1462 //        } else {
1463 //
1464 //              try {
1465 //                      cluster.forObjects(graph, subject, predicate, procedure);
1466 //              } catch (DatabaseException e) {
1467 //                      e.printStackTrace();
1468 //              }
1469 //              
1470 ////                    procedure.finished(graph);
1471 ////                    graph.state.barrier.dec();
1472 ////                    
1473 ////            System.err.println("ai2=" + ai2.decrementAndGet());
1474 //              
1475 //        }
1476 //              
1477 //              
1478 //      }
1479
1480 //      AtomicInteger ai2  =new AtomicInteger(0);
1481         
1482 //    private boolean testCluster(int subject, ClusterI proxy) {
1483 //      
1484 //        if (proxy == null)
1485 //            System.out.println("null cluster: " + Integer.toString(subject, 16));
1486 //        
1487 //        return proxy != null;
1488 //      
1489 //    }
1490
1491     long getCluster(int id) {
1492         // Virtual resource
1493         if(id < 0) return 0;
1494         ClusterI proxy = clusterTable.getClusterByResourceKey(id);
1495         if(proxy == null) return 0;
1496         else return proxy.getClusterId();
1497     }
1498
1499         @Override
1500         public int getRandomAccessReference(String id) throws ResourceNotFoundException {
1501                 
1502                 try {
1503                         Resource res = serializationSupport.getResourceSerializer().getResource(id);
1504                         if(res == null) return 0;
1505                         else return ((ResourceImpl)res).id;
1506                 } catch (InvalidResourceReferenceException e) {
1507                         //e.printStackTrace();
1508                 }
1509                 return 0;
1510                 
1511         }
1512         
1513         @Override
1514         public void ensureLoaded(final ReadGraphImpl graph, final int subject, final int predicate) {
1515                 
1516                 if(subject < 0) {
1517                         
1518                         SessionImplSocket.loadVirtualStatements(virtualGraphServerSupport, graph, subject, predicate, g -> {});
1519                         
1520                 } else {
1521                         
1522                 final ClusterI cluster = clusterTable.checkedGetClusterByResourceKey(subject);
1523
1524                 if(cluster.isLoaded()) {
1525                         
1526                         if(cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(subject) && !SessionImplSocket.areVirtualStatementsLoaded(virtualGraphServerSupport, subject, predicate)) {
1527
1528                                         SessionImplSocket.loadVirtualStatements(virtualGraphServerSupport, graph, subject, predicate, g -> {});
1529                                 
1530                                 } else {
1531                                         
1532                                 }
1533                         
1534                 } else {
1535                         
1536                                 new Exception().printStackTrace();
1537                         
1538                         cluster.load(session.clusterTranslator, new Runnable() {
1539
1540                                         @Override
1541                                         public void run() {
1542                                                 
1543                                         if(cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(subject) && !SessionImplSocket.areVirtualStatementsLoaded(virtualGraphServerSupport, subject, predicate)) {
1544
1545                                                         SessionImplSocket.loadVirtualStatements(virtualGraphServerSupport, graph, subject, predicate, g -> {});
1546                                                 
1547                                                 } else {
1548                                                         
1549                                                 }
1550                                                 
1551                                         }
1552                                 
1553                         });
1554                         
1555                 }
1556                 
1557                 
1558                 }
1559                 
1560         }
1561         
1562         @Override
1563         public void ensureLoaded(final ReadGraphImpl graph, final int subject) {
1564                 
1565                 if(subject < 0) {
1566                         
1567                         SessionImplSocket.loadVirtualStatements(virtualGraphServerSupport, graph, subject, g -> {});
1568                         
1569                 } else {
1570                         
1571                 final ClusterI cluster = clusterTable.getClusterByResourceKey(subject);
1572
1573                 if(cluster.isLoaded()) {
1574                         
1575                         if(cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(subject) && !SessionImplSocket.areVirtualStatementsLoaded(virtualGraphServerSupport, subject)) {
1576
1577                                         SessionImplSocket.loadVirtualStatements(virtualGraphServerSupport, graph, subject, g -> {});
1578                                 
1579                                 } else {
1580                                         
1581                                 }
1582                         
1583                 } else {
1584                         
1585 //                      System.err.println("cluster not loaded " + subject);
1586                                 new Exception().printStackTrace();
1587                         
1588                         cluster.load(session.clusterTranslator, new Runnable() {
1589
1590                                         @Override
1591                                         public void run() {
1592                                                 
1593                                         if(cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(subject) && !SessionImplSocket.areVirtualStatementsLoaded(virtualGraphServerSupport, subject)) {
1594
1595                                                         SessionImplSocket.loadVirtualStatements(virtualGraphServerSupport, graph, subject, g -> {});
1596                                                 
1597                                                 } else {
1598                                                         
1599                                                 }
1600                                                 
1601                                         }
1602                                 
1603                         });
1604                         
1605                 }
1606                 
1607                 
1608                 }
1609                 
1610         }
1611
1612         @Override
1613         public boolean isLoaded(int subject) {
1614         ClusterI cluster = clusterTable.getClusterByResourceKey(subject);
1615         return cluster.isLoaded();
1616         }
1617         
1618         @Override
1619         public void ceased(int thread) {
1620                 
1621                 session.ceased(thread);
1622                 
1623         }
1624
1625     @Override
1626     public Object getLock() {
1627         
1628         return session.requestManager;
1629         
1630     }
1631
1632     @Override
1633     public VirtualGraph getProvider(int subject, int predicate, int object) {
1634
1635         if(subject > 0) {
1636             ClusterImpl cluster = (ClusterImpl)clusterTable.getClusterByResourceKey(subject);
1637                 // This persistent resource does not have virtual statements => must deny in persistent graph
1638                 if(!cluster.hasVirtual() || !virtualGraphServerSupport.virtuals.contains(subject)) return null;
1639         }
1640         
1641         for(TransientGraph g : virtualGraphServerSupport.providers) {
1642                 for (final int id : g.getObjects(subject, predicate)) {
1643                         if(object == id) return g;
1644                 }
1645         }
1646         
1647         // Nothing found from virtual graphs
1648         return null;
1649                 
1650     }
1651
1652     @Override
1653     public VirtualGraph getProvider(int subject, int predicate) {
1654
1655         if(subject > 0) {
1656             ClusterImpl cluster = (ClusterImpl)clusterTable.getClusterByResourceKey(subject);
1657                 // This persistent resource does not have virtual statements => must deny in persistent graph
1658                 if(!cluster.hasVirtual() || !virtualGraphServerSupport.virtuals.contains(subject)) return null;
1659         }
1660
1661         TransientGraph result = null;
1662         for(TransientGraph g : virtualGraphServerSupport.providers) {
1663                 if(g.getObjects(subject, predicate).length > 0) {
1664                         // Found multiple, return null;
1665                         if(result != null) return null;
1666                         else result = g;
1667                 }
1668         }
1669         return result;
1670                 
1671     }
1672
1673     @Override
1674     public VirtualGraph getValueProvider(int subject) {
1675
1676         if(subject > 0) {
1677             ClusterImpl cluster = (ClusterImpl)clusterTable.getClusterByResourceKey(subject);
1678                 // This persistent resource does not have virtual statements => must deny in persistent graph
1679                 if(!cluster.hasVirtual() || !virtualGraphServerSupport.virtuals.contains(subject)) return null;
1680         }
1681
1682         TransientGraph result = null;
1683         for(TransientGraph g : virtualGraphServerSupport.providers) {
1684                 if(g.getValue(subject) != null) {
1685                         if(result != null) return null;
1686                         else result = g;
1687                 }
1688         }
1689         return result;
1690                 
1691     }
1692     
1693     @Override
1694     public void exit(Throwable t) {
1695         state.close();
1696     }
1697     
1698     private void analyseProblem(ClusterI cluster) {
1699         
1700         if(cluster instanceof ClusterSmall)
1701                         try {
1702                                 ((ClusterSmall)cluster).check();
1703                         } catch (DatabaseException e) {
1704                                 e.printStackTrace();
1705                         }
1706         
1707     }
1708     
1709 }