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