]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/QuerySupportImpl.java
Generate parts of db client query code
[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 java.io.ByteArrayInputStream;
4 import java.io.InputStream;
5 import java.util.Collection;
6 import java.util.function.Consumer;
7
8 import org.simantics.db.Resource;
9 import org.simantics.db.Session;
10 import org.simantics.db.Statement;
11 import org.simantics.db.VirtualGraph;
12 import org.simantics.db.WriteGraph;
13 import org.simantics.db.common.StandardStatement;
14 import org.simantics.db.common.request.WriteRequest;
15 import org.simantics.db.common.utils.Logger;
16 import org.simantics.db.exception.DatabaseException;
17 import org.simantics.db.exception.InvalidResourceReferenceException;
18 import org.simantics.db.exception.ResourceNotFoundException;
19 import org.simantics.db.impl.ClusterI;
20 import org.simantics.db.impl.ClusterSupport;
21 import org.simantics.db.impl.ForEachObjectContextProcedure;
22 import org.simantics.db.impl.ForEachObjectProcedure;
23 import org.simantics.db.impl.ResourceImpl;
24 import org.simantics.db.impl.TransientGraph;
25 import org.simantics.db.impl.VirtualGraphImpl;
26 import org.simantics.db.impl.graph.ReadGraphImpl;
27 import org.simantics.db.impl.query.IntProcedure;
28 import org.simantics.db.impl.query.QueryProcessor;
29 import org.simantics.db.impl.query.QuerySupport;
30 import org.simantics.db.impl.support.BuiltinSupport;
31 import org.simantics.db.impl.support.ResourceSupport;
32 import org.simantics.db.procore.cluster.ClusterImpl;
33 import org.simantics.db.procore.cluster.ClusterSmall;
34 import org.simantics.db.service.SerialisationSupport;
35 import org.simantics.utils.DataContainer;
36
37 import gnu.trove.set.hash.TIntHashSet;
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 boolean getObjects(final ReadGraphImpl graph, final int subject, final int predicate, final IntProcedure procedure) throws DatabaseException {
440                 
441                 assert (subject != 0);
442                 assert (predicate != 0);
443
444                 if(subject < 0) {
445
446                         boolean found = false;
447                         
448                         for(TransientGraph g : virtualGraphServerSupport.providers) {
449                                 for (final int id : g.getObjects(subject, predicate)) {
450                                         found = true;
451                                         procedure.execute(graph, id);
452                                 }
453                         }
454                         
455                         return found;
456
457                 }
458
459                 final ClusterI cluster = clusterTable.getClusterByResourceKey(subject);
460                 assert(cluster.isLoaded());
461         
462         if (cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(subject)) {
463                 
464                 final DataContainer<Boolean> found = new DataContainer<Boolean>(Boolean.FALSE);
465                 final TIntHashSet result = new TIntHashSet(5);
466                 
467                         for(TransientGraph g : virtualGraphServerSupport.providers) {
468                                 for (final int id : g.getObjects(subject, predicate)) {
469
470                                         found.set(true);
471                                         if (result.add(id)) {
472                                                 procedure.execute(graph, id);
473                                         }
474
475                                 }
476                         }
477                         
478                         // Virtual predicates are not found from persistent clusters
479                         if(predicate < 0) return found.get();
480
481                 // wheels within wheels
482                 final ClusterI.ObjectProcedure<Object> proc = new ClusterI.ObjectProcedure<Object>() {
483
484                         @Override
485                         public boolean execute(Object context, int object) {
486
487                                 found.set(true);
488                                 if (result.add(object)) {
489                                         try {
490                                                         procedure.execute(graph, object);
491                                                 } catch (DatabaseException e) {
492                                                         Logger.defaultLogError(e);
493                                                 }
494                                 }
495
496                                 return false; // continue looping
497
498                         }
499
500                 };
501                         
502                         try {
503                 cluster.forObjects(subject, predicate, proc, null, clusterSupport);
504                         } catch (DatabaseException e) {
505                                 e.printStackTrace();
506                         }
507                         
508                         return found.get();
509                         
510                 } else {
511                         
512                         // Virtual predicates are not found from persistent clusters
513                         if(predicate < 0) return false;
514                         
515                         class A implements ClusterI.ObjectProcedure<Object> {
516
517                         boolean found = false;
518
519                         @Override
520                         public boolean execute(Object context, int object) {
521
522                                 found = true;
523                                 try {
524                                                 procedure.execute(graph, object);
525                                         } catch (DatabaseException e) {
526                                                 Logger.defaultLogError(e);
527                                         }
528                                 return false; // continue looping
529
530                         }
531
532                                 public boolean found() {
533                                         return found;
534                                 }
535
536                         }
537                         
538                 // wheels within wheels
539                 final A proc = new A();
540                 
541                         try {
542                 cluster.forObjects(subject, predicate, proc, null, clusterSupport);
543                         } catch (DatabaseException e) {
544                                 e.printStackTrace();
545                         } 
546                         // This happens if resource is bogus
547                         catch (Throwable t) {
548                                 
549                         analyseProblem(cluster);
550                         
551                         Logger.defaultLogError(t);
552                                 
553                         }
554                 
555                 return proc.found();
556                         
557                 }
558         
559     }
560
561 //      @Override
562 //    public boolean getFunctionalObject(final ReadGraphImpl graph, final int subject, final int predicate,
563 //            final IntProcedure procedure) {
564 //
565 //        assert (subject != 0);
566 //        assert (predicate != 0);
567 //
568 //        if(subject < 0) {
569 //
570 //              boolean found = false;
571 //
572 //              Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(subject);
573 //              if (providers != null) {
574 //
575 //                      for (VirtualGraph provider : providers) {
576 //
577 //                              for (int id : ((VirtualGraphImpl)provider).getObjects(subject, predicate)) {
578 //                                      found = true;
579 //                      procedure.execute(graph, id);
580 //                    }
581 //
582 //                }
583 //
584 //            }
585 //              
586 //              return found;
587 //              
588 //        }
589 //        
590 //        final ClusterI cluster = clusterTable.getClusterByResourceKey(subject);
591 //        
592 //        if (cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(subject)) {
593 //        
594 //              final DataContainer<Boolean> found = new DataContainer<Boolean>(false);
595 //              final TIntHashSet result = new TIntHashSet(5);
596 //
597 //              Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(subject);
598 //              if (providers != null) {
599 //
600 //                      for (VirtualGraph provider : providers) {
601 //
602 //                              for (int id : ((VirtualGraphImpl)provider).getObjects(subject, predicate)) {
603 //                                      found.set(true);
604 //                      procedure.execute(graph, id);
605 //                    }
606 //
607 //                }
608 //
609 //            }
610 //              
611 //            // wheels within wheels
612 //            final ClusterI.ObjectProcedure<Object> proc = new ClusterI.ObjectProcedure<Object>() {
613 //
614 //                @Override
615 //                public boolean execute(int callerThread, Object context, int object) {
616 //
617 //                    found.set(true);
618 //                    System.out.println("-found object " + object);
619 //                    if (result.add(object)) {
620 //                      procedure.execute(graph.newAsync(callerThread), object);
621 //                    }
622 //
623 //                    return false; // continue looping
624 //
625 //                }
626 //                
627 //                              @Override
628 //                              public boolean found() {
629 //                                      throw new UnsupportedOperationException();
630 //                              }
631 //                
632 //            };
633 //            
634 //            try {
635 //                cluster.forObjects(graph.callerThread, subject, predicate, proc, null, clusterSupport);
636 //            } catch (DatabaseException e) {
637 //                Logger.defaultLogError(e);
638 //                return false;
639 //            } catch (Throwable t) {
640 //                Logger.defaultLogError(t);
641 //              t.printStackTrace();
642 //            }
643 //            
644 //            return found.get();
645 //            
646 //        } else {
647 //
648 //              // wheels within wheels
649 //              final ClusterI.ObjectProcedure<Object> proc = new ClusterI.ObjectProcedure<Object>() {
650 //                  
651 //                      boolean found = false;
652 //                      
653 //                  @Override
654 //                  public boolean execute(int callerThread, Object context, int object) {
655 //      
656 //                      found = true;
657 //                      procedure.execute(graph.newAsync(callerThread), object);
658 //                      return false; // continue looping
659 //                      
660 //                  }
661 //                  
662 //                              @Override
663 //                              public boolean found() {
664 //                                      return found;
665 //                              }
666 //                  
667 //                  @Override
668 //                  public String toString() {
669 //                      return "Wheels for " + procedure;
670 //                  }
671 //                  
672 //              };
673 //              
674 //              try {
675 //                  cluster.forObjects(graph.callerThread, subject, predicate, proc, null, clusterSupport);
676 //              } catch (DatabaseException e) {
677 //                  Logger.defaultLogError(e);
678 //                  return false;
679 //              } catch (Throwable t) {
680 //                      t.printStackTrace();
681 //                  Logger.defaultLogError(t);
682 //                  return false;
683 //              }
684 //              
685 //              return proc.found();
686 //        
687 //        }
688 //        
689 //    }
690         
691         @Override
692     public int getFunctionalObject(final int subject, final int predicate) {
693
694         assert (subject != 0);
695         assert (predicate != 0);
696
697         if(subject < 0) {
698
699                 int found = 0;
700
701                 Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(subject);
702                 if (providers != null) {
703
704                         for (VirtualGraph provider : providers) {
705
706                                 for (int id : ((VirtualGraphImpl)provider).getObjects(subject, predicate)) {
707                                         if(found == 0) found = id;
708                                         else found = -1;
709                     }
710
711                 }
712
713             }
714                 
715                 return found;
716 //              if(found == -1) return 0;
717 //              else return found;
718                 
719         }
720         
721         final ClusterI cluster = clusterTable.getClusterByResourceKey(subject);
722         
723         if (cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(subject)) {
724
725                 int result = 0;
726                 Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(subject);
727                 if (providers != null) {
728
729                         for (VirtualGraph provider : providers) {
730
731                                 for (int id : ((VirtualGraphImpl)provider).getObjects(subject, predicate)) {
732                                         if(result == 0) result = id;
733                                         else result = -1;
734                     }
735
736                 }
737
738             }
739                 
740                 if(result != 0) return result; 
741             
742                 try {
743                                 return cluster.getSingleObject(subject, predicate, clusterSupport);
744                         } catch (DatabaseException e) {
745                                 return -1;
746                         }
747             
748         } else {
749
750                 try {
751                                 return cluster.getSingleObject(subject, predicate, clusterSupport);
752                         } catch (DatabaseException e) {
753                                 return -1;
754                         }
755                 // This comes if the resource is bogus
756                 catch (Throwable t) {
757                         
758                 analyseProblem(cluster);
759                 
760                 Logger.defaultLogError(t);
761                         
762                                 return -1;
763                                 
764                         }
765         
766         }
767         
768     }
769
770 //      @Override
771 //    public boolean getStatements(final ReadGraphImpl graph, final int subject, final int predicate,
772 //            final TripleIntProcedure procedure, final Statements entry) {
773 //
774 //        assert (subject != 0);
775 //        assert (predicate != 0);
776 //
777 //        final TIntHashSet result = new TIntHashSet(16);
778 //        final DataContainer<Boolean> found = new DataContainer<Boolean>(false);
779 //
780 //        Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(subject);
781 //        
782 //        if (providers != null) {
783 //
784 //            for (VirtualGraph provider : providers) {
785 //
786 //                for (int id : ((VirtualGraphImpl)provider).getObjects(subject, predicate)) {
787 //
788 //                    found.set(true);
789 //
790 //                    if (result.add(id)) {
791 //                        if (null != entry) {
792 //                            entry.addOrSet(subject, predicate, id);
793 //                            procedure.execute(graph, subject, predicate, id);
794 //                            return true; // break;
795 //                        } else {
796 //                            procedure.execute(graph, subject, predicate, id);
797 //                        }
798 //                    }
799 //
800 //                }
801 //
802 //            }
803 //
804 //        }
805 //
806 //        if (subject < 0)
807 //            return found.get();
808 //
809 //        final ClusterI cluster = clusterTable.getClusterByResourceKey(subject);
810 //        assert (cluster != null);
811 //
812 //        // wheels within wheels
813 //        final ClusterI.ObjectProcedure<Object> proc = new ClusterI.ObjectProcedure<Object>() {
814 //            @Override
815 //            public boolean execute(int callerThread, Object context, int object) {
816 //
817 //                found.set(true);
818 //
819 //                if (result.add(object)) {
820 //                    if (null != entry) {
821 //                        entry.addOrSet(subject, predicate, object);
822 //                        procedure.execute(graph.newAsync(callerThread), subject, predicate, object);
823 //                        return true; // break;
824 //                    } else {
825 //                        procedure.execute(graph.newAsync(callerThread), subject, predicate, object);
826 //                    }
827 //                }
828 //
829 //                return false; // continue looping
830 //
831 //            }
832 //            
833 //                      @Override
834 //                      public boolean found() {
835 //                              throw new UnsupportedOperationException();
836 //                      }
837 //            
838 //        };
839 //
840 //        try {
841 //            cluster.forObjects(graph.callerThread, subject, predicate, proc, null, clusterSupport);
842 //        } catch (DatabaseException e) {
843 //            Logger.defaultLogError(e);
844 //        }
845 //        return found.get();
846 //
847 //    }
848
849         @Override
850     public org.simantics.db.DirectStatements getStatements(final ReadGraphImpl graph, final int subject, final QueryProcessor processor, boolean ignoreVirtual) {
851
852         assert (subject != 0);
853
854         final DirectStatementsImpl result = new DirectStatementsImpl(resourceSupport, subject);
855
856         if (!ignoreVirtual) {
857             Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(subject);
858             if (providers != null) {
859                 for (TransientGraph provider : providers) {
860                     for (int p : provider.getPredicates(subject)) {
861                         for (int o : provider.getObjects(subject, p)) {
862                             result.addStatement(p, o);
863                         }
864                     }
865                 }
866             }
867         }
868
869         if (subject < 0) {
870                 return result;
871         } else {
872             final ClusterI cluster = clusterTable.getClusterByResourceKey(subject);
873             assert (cluster != null);
874             doGetStatements(graph, cluster, subject, result);
875         }
876         
877         return result;
878
879     }
880
881     @Override
882     public void getPredicates(final ReadGraphImpl graph, final int subject, final IntProcedure procedure) throws DatabaseException {
883
884         final TIntHashSet result = new TIntHashSet(16);
885
886         Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(subject);
887         
888         if (providers != null) {
889
890             for (VirtualGraph provider : providers) {
891
892                 for (int id : ((VirtualGraphImpl)provider).getPredicates(subject)) {
893
894                     if (result.add(id)) {
895                         procedure.execute(graph, id);
896                     }
897
898                 }
899
900             }
901
902         }
903
904         if (subject < 0) {
905             procedure.finished(graph);
906             return;
907         }
908
909         ClusterI proxy = clusterTable.getClusterByResourceKey(subject);
910         assert (proxy != null);
911
912         final DataContainer<Integer> got = new DataContainer<Integer>(0);
913         ClusterI.PredicateProcedure<Object> proc = new ClusterI.PredicateProcedure<Object>() {
914             @Override
915             public boolean execute(Object context, int predicate, int oi) {
916                 if (result.add(predicate)) {
917                     try {
918                                                 procedure.execute(graph, predicate);
919                                         } catch (DatabaseException e) {
920                                                 Logger.defaultLogError(e);
921                                         }
922                 }
923                 got.set(got.get() + 1);
924                 return false; // continue looping
925             }
926         };
927         try {
928             proxy.forPredicates(subject, proc, null, clusterSupport);
929         } catch (DatabaseException e) {
930             Logger.defaultLogError(e);
931         }
932         procedure.finished(graph);
933
934     }
935     
936     
937
938 //    @Override
939 //    public void getValue(ReadGraphImpl graph, int resource, InternalProcedure<byte[]> procedure) {
940 //
941 //      if(resource < 0) {
942 //      
943 //              Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(resource);
944 //              
945 //              if (providers != null) {
946 //      
947 //                  for (VirtualGraph provider : providers) {
948 //      
949 //                      Object value = ((VirtualGraphImpl)provider).getValue(resource);
950 //                      if (value != null) {
951 //                          procedure.execute(graph, (byte[])value);
952 //                          return;
953 //                      }
954 //      
955 //                  }
956 //      
957 //              }
958 //              
959 //              return;
960 //        
961 //      }
962 //      
963 //      ClusterI cluster = clusterTable.getClusterByResourceKey(resource);
964 //        if (cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(resource)) {
965 //              
966 //              Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(resource);
967 //              
968 //              if (providers != null) {
969 //      
970 //                  for (VirtualGraph provider : providers) {
971 //      
972 //                      Object value = ((VirtualGraphImpl)provider).getValue(resource);
973 //                      if (value != null) {
974 //                          procedure.execute(graph, (byte[])value);
975 //                          return;
976 //                      }
977 //      
978 //                  }
979 //      
980 //              }
981 //              
982 //              try {
983 //                      
984 //                      byte[] data = cluster.getValue(resource, clusterSupport);
985 //                      if (null == data || 0 == data.length) {
986 //                          procedure.execute(graph, null);
987 //                      } else {
988 //                          procedure.execute(graph, data);
989 //                      }
990 //                      
991 //              } catch (DatabaseException e) {
992 //                  Logger.defaultLogError(e);
993 //              }
994 //              
995 //        } else {
996 //
997 //              try {
998 //                      
999 //                      byte[] data = cluster.getValue(resource, clusterSupport);
1000 //                      if (null == data || 0 == data.length) {
1001 //                          procedure.execute(graph, null);
1002 //                      } else {
1003 //                          procedure.execute(graph, data);
1004 //                      }
1005 //                      
1006 //              } catch (DatabaseException e) {
1007 //                  Logger.defaultLogError(e);
1008 //              }
1009 //
1010 //        }
1011 //
1012 //    }
1013
1014
1015     @Override
1016     public byte[] getValue(ReadGraphImpl graph, int resource) {
1017
1018         if(resource < 0) {
1019         
1020                 Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(resource);
1021                 
1022                 if (providers != null) {
1023         
1024                     for (VirtualGraph provider : providers) {
1025         
1026                         Object value = ((VirtualGraphImpl)provider).getValue(resource);
1027                         if (value != null) {
1028                                 return (byte[])value;
1029                         }
1030         
1031                     }
1032         
1033                 }
1034                 
1035                 return null;
1036         
1037         }
1038         
1039         ClusterI cluster = clusterTable.getClusterByResourceKey(resource);
1040         if (cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(resource)) {
1041                 
1042                 Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(resource);
1043                 
1044                 if (providers != null) {
1045         
1046                     for (VirtualGraph provider : providers) {
1047         
1048                         Object value = ((VirtualGraphImpl)provider).getValue(resource);
1049                         if (value != null) {
1050                                 return (byte[])value;
1051                         }
1052         
1053                     }
1054         
1055                 }
1056                 
1057                 try {
1058                         
1059                         byte[] data = cluster.getValue(resource, clusterSupport);
1060                         if (null != data && 0 != data.length) {
1061                                 return data;
1062                         }
1063                         
1064                 } catch (DatabaseException e) {
1065                     Logger.defaultLogError(e);
1066                 }
1067                 
1068                 return null;
1069                 
1070         } else {
1071
1072                 try {
1073                         
1074                         byte[] data = cluster.getValue(resource, clusterSupport);
1075                         if (null != data && 0 != data.length) {
1076                                 return data;
1077                         }
1078                         
1079                 } catch (DatabaseException e) {
1080                     Logger.defaultLogError(e);
1081                 }
1082                 
1083                 return null;
1084
1085         }
1086
1087     }
1088
1089     @Override
1090     public InputStream getValueStream(ReadGraphImpl graph, int resource) {
1091
1092         if(resource < 0) {
1093         
1094             Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(resource);
1095             
1096             if (providers != null) {
1097     
1098                 for (VirtualGraph provider : providers) {
1099     
1100                     Object value = ((VirtualGraphImpl)provider).getValue(resource);
1101                     if (value != null) {
1102                         return new ByteArrayInputStream((byte[])value);
1103                     }
1104     
1105                 }
1106     
1107             }
1108             
1109             return null;
1110         
1111         }
1112         
1113         ClusterI cluster = clusterTable.getClusterByResourceKey(resource);
1114         if (cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(resource)) {
1115             
1116             Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(resource);
1117             
1118             if (providers != null) {
1119     
1120                 for (VirtualGraph provider : providers) {
1121     
1122                     Object value = ((VirtualGraphImpl)provider).getValue(resource);
1123                     if (value != null) {
1124                         return new ByteArrayInputStream((byte[])value);
1125                     }
1126     
1127                 }
1128     
1129             }
1130             
1131             try {
1132                 
1133                 return cluster.getValueStream(resource, clusterSupport);
1134                 
1135             } catch (DatabaseException e) {
1136                 Logger.defaultLogError(e);
1137             }
1138             
1139             return null;
1140             
1141         } else {
1142
1143             try {
1144                 
1145                 return cluster.getValueStream(resource, clusterSupport);
1146                 
1147             } catch (DatabaseException e) {
1148                 Logger.defaultLogError(e);
1149             }
1150             
1151             return null;
1152
1153         }
1154
1155     }
1156     
1157     @Override
1158     public void requestCluster(ReadGraphImpl graph, final long clusterId, final Runnable r) {
1159
1160         class CallbackAdapter implements Consumer<DatabaseException> {
1161                 final Runnable r;
1162                 CallbackAdapter(final Runnable r) {
1163                         this.r = r;
1164                 }
1165                 @Override
1166                 public void accept(DatabaseException e) {
1167                         if (null != e)
1168                                 e.printStackTrace();
1169                         else
1170                                 r.run();
1171                 }
1172                 
1173         }
1174         
1175         double p = clusterTable.getLoadProbability();
1176 // System.out.print("Load cluster " + clusterId + " with probability " + p +
1177         // " -> ");
1178         final ClusterI proxy = clusterSupport.getClusterByClusterId(clusterId);
1179         if (!proxy.isLoaded()) {
1180                 clusterTable.gc();
1181             if (Math.random() < p) {
1182                 proxy.load(new CallbackAdapter(r));
1183             } else {
1184                 r.run();
1185             }
1186         } else {
1187             r.run();
1188         }
1189
1190     }
1191
1192     @Override
1193     public int getBuiltin(String uri) {
1194         return builtinSupport.getBuiltin(uri);
1195     }
1196
1197     @Override
1198     public void checkTasks() {
1199         System.out.println(syncThreads.toString());
1200     }
1201
1202 //    @Override
1203 //    public void asyncWrite(Write request) {
1204 //        
1205 ////            if(plainWrite(writer) && sameProvider(request)) {
1206 ////                    writer.writeSupport.pushRequest(request);
1207 ////            } else {
1208 //              asyncRequest(request);
1209 ////            }
1210 //        
1211 //    }
1212
1213     /*
1214      * Helpers
1215      * 
1216      * 
1217      */
1218     
1219     private void doGetStatements(ReadGraphImpl graph, final ClusterI cluster, final int subject, final DirectStatementsImpl result) {
1220
1221         final class Proc implements ClusterI.PredicateProcedure<Object> {
1222
1223                         @Override
1224                         public boolean execute(Object context, final int predicate, final int objectIndex) {
1225                                 
1226                                 doExecute(null, predicate, objectIndex);
1227                                 return false;
1228                                 
1229                         }
1230
1231                         private void doExecute(Object context, final int predicate, final int objectIndex) {
1232
1233                                 try {
1234                                         cluster.forObjects(subject, predicate, new ClusterI.ObjectProcedure<Object>() {
1235
1236                                                 @Override
1237                                                 public boolean execute(Object context, int object) {
1238                                                         result.addStatement(predicate, object);
1239                                                         return false;
1240                                                 }
1241
1242                                         }, null, clusterSupport);
1243                                 } catch (DatabaseException e) {
1244                                         e.printStackTrace();
1245                                 }
1246                                 
1247                         }
1248                 
1249         }
1250
1251         try {
1252                         cluster.forPredicates(subject, new Proc(), null, clusterSupport);
1253                 } catch (DatabaseException e) {
1254                         e.printStackTrace();
1255                 }
1256         
1257     }
1258     
1259 //      private void getDirectObjects4(final int callerThread, final ClusterI cluster, final int subject, final int predicate, final QueryProcessor processor, final ReadGraphImpl graph, final ForEachObjectProcedure procedure) {
1260 //
1261 //        if(!cluster.isLoaded()) {
1262 //
1263 //                      requestCluster(callerThread, cluster.getClusterId(), new Callback<Integer>() {
1264 //      
1265 //                              @Override
1266 //                              public void run(Integer i) {
1267 //      
1268 //                                      processor.schedule(i, new SessionTask(callerThread) {
1269 //      
1270 //                                              @Override
1271 //                                              public void run(int thread) {
1272 //                                                      
1273 //                                                      getDirectObjects4(thread, cluster, subject, predicate, processor, graph, procedure);
1274 //                                                      
1275 //                                              }
1276 //      
1277 //                                      });
1278 //      
1279 //                              }
1280 //      
1281 //                      });
1282 //                      
1283 //        } else {
1284 //
1285 //              try {
1286 //                      cluster.forObjects(graph, subject, predicate, procedure);
1287 //              } catch (DatabaseException e) {
1288 //                      e.printStackTrace();
1289 //              }
1290 //              
1291 ////                    procedure.finished(graph);
1292 ////                    graph.state.barrier.dec();
1293 ////                    
1294 ////            System.err.println("ai2=" + ai2.decrementAndGet());
1295 //              
1296 //        }
1297 //              
1298 //              
1299 //      }
1300
1301 //      AtomicInteger ai2  =new AtomicInteger(0);
1302         
1303 //    private boolean testCluster(int subject, ClusterI proxy) {
1304 //      
1305 //        if (proxy == null)
1306 //            System.out.println("null cluster: " + Integer.toString(subject, 16));
1307 //        
1308 //        return proxy != null;
1309 //      
1310 //    }
1311
1312     long getCluster(int id) {
1313         // Virtual resource
1314         if(id < 0) return 0;
1315         ClusterI proxy = clusterTable.getClusterByResourceKey(id);
1316         if(proxy == null) return 0;
1317         else return proxy.getClusterId();
1318     }
1319
1320         @Override
1321         public int getRandomAccessReference(String id) throws ResourceNotFoundException {
1322                 
1323                 try {
1324                         Resource res = serializationSupport.getResourceSerializer().getResource(id);
1325                         if(res == null) return 0;
1326                         else return ((ResourceImpl)res).id;
1327                 } catch (InvalidResourceReferenceException e) {
1328                         //e.printStackTrace();
1329                 }
1330                 return 0;
1331                 
1332         }
1333         
1334         @Override
1335         public void ensureLoaded(final ReadGraphImpl graph, final int subject, final int predicate) {
1336                 
1337                 if(subject < 0) {
1338                         
1339                         SessionImplSocket.loadVirtualStatements(virtualGraphServerSupport, graph, subject, predicate, g -> {});
1340                         
1341                 } else {
1342                         
1343                 final ClusterI cluster = clusterTable.checkedGetClusterByResourceKey(subject);
1344
1345                 if(cluster.isLoaded()) {
1346                         
1347                         if(cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(subject) && !SessionImplSocket.areVirtualStatementsLoaded(virtualGraphServerSupport, subject, predicate)) {
1348
1349                                         SessionImplSocket.loadVirtualStatements(virtualGraphServerSupport, graph, subject, predicate, g -> {});
1350                                 
1351                                 } else {
1352                                         
1353                                 }
1354                         
1355                 } else {
1356                         
1357                                 new Exception().printStackTrace();
1358                         
1359                         cluster.load(session.clusterTranslator, new Runnable() {
1360
1361                                         @Override
1362                                         public void run() {
1363                                                 
1364                                         if(cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(subject) && !SessionImplSocket.areVirtualStatementsLoaded(virtualGraphServerSupport, subject, predicate)) {
1365
1366                                                         SessionImplSocket.loadVirtualStatements(virtualGraphServerSupport, graph, subject, predicate, g -> {});
1367                                                 
1368                                                 } else {
1369                                                         
1370                                                 }
1371                                                 
1372                                         }
1373                                 
1374                         });
1375                         
1376                 }
1377                 
1378                 
1379                 }
1380                 
1381         }
1382         
1383         @Override
1384         public void ensureLoaded(final ReadGraphImpl graph, final int subject) {
1385                 
1386                 if(subject < 0) {
1387                         
1388                         SessionImplSocket.loadVirtualStatements(virtualGraphServerSupport, graph, subject, g -> {});
1389                         
1390                 } else {
1391                         
1392                 final ClusterI cluster = clusterTable.getClusterByResourceKey(subject);
1393
1394                 if(cluster.isLoaded()) {
1395                         
1396                         if(cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(subject) && !SessionImplSocket.areVirtualStatementsLoaded(virtualGraphServerSupport, subject)) {
1397
1398                                         SessionImplSocket.loadVirtualStatements(virtualGraphServerSupport, graph, subject, g -> {});
1399                                 
1400                                 } else {
1401                                         
1402                                 }
1403                         
1404                 } else {
1405                         
1406 //                      System.err.println("cluster not loaded " + subject);
1407                                 new Exception().printStackTrace();
1408                         
1409                         cluster.load(session.clusterTranslator, new Runnable() {
1410
1411                                         @Override
1412                                         public void run() {
1413                                                 
1414                                         if(cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(subject) && !SessionImplSocket.areVirtualStatementsLoaded(virtualGraphServerSupport, subject)) {
1415
1416                                                         SessionImplSocket.loadVirtualStatements(virtualGraphServerSupport, graph, subject, g -> {});
1417                                                 
1418                                                 } else {
1419                                                         
1420                                                 }
1421                                                 
1422                                         }
1423                                 
1424                         });
1425                         
1426                 }
1427                 
1428                 
1429                 }
1430                 
1431         }
1432
1433         @Override
1434         public boolean isLoaded(int subject) {
1435         ClusterI cluster = clusterTable.getClusterByResourceKey(subject);
1436         return cluster.isLoaded();
1437         }
1438         
1439         @Override
1440         public void ceased(int thread) {
1441                 
1442                 session.ceased(thread);
1443                 
1444         }
1445
1446     @Override
1447     public Object getLock() {
1448         
1449         return session.requestManager;
1450         
1451     }
1452
1453     @Override
1454     public VirtualGraph getProvider(int subject, int predicate, int object) {
1455
1456         if(subject > 0) {
1457             ClusterImpl cluster = (ClusterImpl)clusterTable.getClusterByResourceKey(subject);
1458                 // This persistent resource does not have virtual statements => must deny in persistent graph
1459                 if(!cluster.hasVirtual() || !virtualGraphServerSupport.virtuals.contains(subject)) return null;
1460         }
1461         
1462         for(TransientGraph g : virtualGraphServerSupport.providers) {
1463                 for (final int id : g.getObjects(subject, predicate)) {
1464                         if(object == id) return g;
1465                 }
1466         }
1467         
1468         // Nothing found from virtual graphs
1469         return null;
1470                 
1471     }
1472
1473     @Override
1474     public VirtualGraph getProvider(int subject, int predicate) {
1475
1476         if(subject > 0) {
1477             ClusterImpl cluster = (ClusterImpl)clusterTable.getClusterByResourceKey(subject);
1478                 // This persistent resource does not have virtual statements => must deny in persistent graph
1479                 if(!cluster.hasVirtual() || !virtualGraphServerSupport.virtuals.contains(subject)) return null;
1480         }
1481
1482         TransientGraph result = null;
1483         for(TransientGraph g : virtualGraphServerSupport.providers) {
1484                 if(g.getObjects(subject, predicate).length > 0) {
1485                         // Found multiple, return null;
1486                         if(result != null) return null;
1487                         else result = g;
1488                 }
1489         }
1490         return result;
1491                 
1492     }
1493
1494     @Override
1495     public VirtualGraph getValueProvider(int subject) {
1496
1497         if(subject > 0) {
1498             ClusterImpl cluster = (ClusterImpl)clusterTable.getClusterByResourceKey(subject);
1499                 // This persistent resource does not have virtual statements => must deny in persistent graph
1500                 if(!cluster.hasVirtual() || !virtualGraphServerSupport.virtuals.contains(subject)) return null;
1501         }
1502
1503         TransientGraph result = null;
1504         for(TransientGraph g : virtualGraphServerSupport.providers) {
1505                 if(g.getValue(subject) != null) {
1506                         if(result != null) return null;
1507                         else result = g;
1508                 }
1509         }
1510         return result;
1511                 
1512     }
1513     
1514     @Override
1515     public void exit(Throwable t) {
1516         state.close();
1517     }
1518     
1519     private void analyseProblem(ClusterI cluster) {
1520         
1521         if(cluster instanceof ClusterSmall)
1522                         try {
1523                                 ((ClusterSmall)cluster).check();
1524                         } catch (DatabaseException e) {
1525                                 e.printStackTrace();
1526                         }
1527         
1528     }
1529     
1530 }