]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryCacheBase.java
6abaf6b6518e7b9239dad4830aa9acadd65492c5
[simantics/platform.git] / bundles / org.simantics.db.impl / src / org / simantics / db / impl / query / QueryCacheBase.java
1 package org.simantics.db.impl.query;
2
3 import java.util.ArrayList;
4 import java.util.Collection;
5 import java.util.concurrent.Semaphore;
6 import java.util.concurrent.atomic.AtomicBoolean;
7
8 import org.simantics.db.AsyncReadGraph;
9 import org.simantics.db.ObjectResourceIdMap;
10 import org.simantics.db.ReadGraph;
11 import org.simantics.db.RelationInfo;
12 import org.simantics.db.common.utils.Logger;
13 import org.simantics.db.exception.DatabaseException;
14 import org.simantics.db.impl.DebugPolicy;
15 import org.simantics.db.impl.graph.ReadGraphImpl;
16 import org.simantics.db.impl.procedure.InternalProcedure;
17 import org.simantics.db.impl.query.QueryProcessor.SessionTask;
18 import org.simantics.db.procedure.AsyncMultiProcedure;
19 import org.simantics.db.procedure.AsyncProcedure;
20 import org.simantics.db.procedure.Listener;
21 import org.simantics.db.procedure.ListenerBase;
22 import org.simantics.db.procedure.Procedure;
23 import org.simantics.db.procedure.SyncMultiProcedure;
24 import org.simantics.db.request.AsyncMultiRead;
25 import org.simantics.db.request.AsyncRead;
26 import org.simantics.db.request.ExternalRead;
27 import org.simantics.db.request.MultiRead;
28 import org.simantics.db.request.Read;
29
30 import gnu.trove.map.hash.THashMap;
31 import gnu.trove.map.hash.TObjectIntHashMap;
32
33 public class QueryCacheBase {
34
35         // Statistics
36         final int THREADS;
37         public final int THREAD_MASK;
38         int                                             hits                  = 0;
39         int                                             misses                = 0;
40         int                                             updates               = 0;
41         public int                                              size                  = 0;
42
43         public volatile boolean dirty = false;
44         public boolean collecting = false;
45
46         protected final THashMap<String, URIToResource>                           uRIToResourceMap;
47         //protected final THashMap<String, NamespaceIndex>                          namespaceIndexMap;
48         protected final UnaryQueryHashMap<InternalProcedure<ObjectResourceIdMap<String>>> childMapMap;
49         protected final DoubleKeyQueryHashMap<IntProcedure>                       objectsMap;
50         protected final DoubleKeyQueryHashMap<TripleIntProcedure>                 assertedStatementsMap;
51         protected final DoubleKeyQueryHashMap<IntProcedure>                       directObjectsMap;
52         protected final DoubleKeyQueryHashMap<TripleIntProcedure>                 statementsMap;
53         protected final UnaryQueryHashMap<InternalProcedure<IntSet>>              typesMap;
54         protected final UnaryQueryHashMap<IntProcedure>                           principalTypesMap;
55         protected final UnaryQueryHashMap<InternalProcedure<IntSet>>              predicatesMap;
56         protected final UnaryQueryHashMap<InternalProcedure<IntSet>>              superTypesMap;
57         protected final UnaryQueryHashMap<InternalProcedure<IntSet>>              typeHierarchyMap;
58         protected final UnaryQueryHashMap<InternalProcedure<IntSet>>              superRelationsMap;
59
60         protected final UnaryQueryHashMap<IntProcedure>                           orderedSetMap;
61         protected final UnaryQueryHashMap<IntProcedure>                           assertedPredicatesMap;
62         protected final UnaryQueryHashMap<InternalProcedure<IntSet>>              directPredicatesMap;
63         protected final UnaryQueryHashMap<IntProcedure>                           directSuperRelationsMap;
64
65         protected final UnaryQueryHashMap<InternalProcedure<RelationInfo>>        relationInfoQueryMap;
66         protected final UnaryQueryHashMap<InternalProcedure<byte[]>>              valueQueryMap;
67
68         protected final StableHashMap<AsyncRead, AsyncReadEntry>                  asyncReadEntryMap; 
69         protected final StableHashMap<Read, ReadEntry>                            readEntryMap;
70         protected final StableHashMap<MultiRead, MultiReadEntry>                  multiReadEntryMap; 
71         protected final StableHashMap<AsyncMultiRead, AsyncMultiReadEntry>        asyncMultiReadEntryMap; 
72         protected final StableHashMap<ExternalRead, ExternalReadEntry>            externalReadEntryMap; 
73
74         final THashMap<CacheEntry, ArrayList<ListenerEntry>>                      listeners;
75
76         public final QuerySupport                                                 querySupport;
77
78         public QueryCacheBase(QuerySupport querySupport, int threads) {
79
80                 THREADS = threads;
81                 THREAD_MASK = threads - 1;
82
83                 this.querySupport = querySupport;
84                 directPredicatesMap = new UnaryQueryHashMap();
85                 directSuperRelationsMap = new UnaryQueryHashMap();
86                 valueQueryMap = new UnaryQueryHashMap();
87                 principalTypesMap = new UnaryQueryHashMap();
88                 uRIToResourceMap = new THashMap<String, URIToResource>();
89                 //namespaceIndexMap = new THashMap<String, NamespaceIndex>();
90                 childMapMap = new UnaryQueryHashMap<InternalProcedure<ObjectResourceIdMap<String>>>();
91                 relationInfoQueryMap = new UnaryQueryHashMap();
92                 typeHierarchyMap = new UnaryQueryHashMap();
93                 superTypesMap = new UnaryQueryHashMap();
94                 superRelationsMap = new UnaryQueryHashMap();
95                 typesMap = new UnaryQueryHashMap();
96                 objectsMap = new DoubleKeyQueryHashMap();
97                 orderedSetMap = new UnaryQueryHashMap();
98                 predicatesMap = new UnaryQueryHashMap();
99                 statementsMap = new DoubleKeyQueryHashMap();
100                 directObjectsMap = new DoubleKeyQueryHashMap();
101                 assertedPredicatesMap = new UnaryQueryHashMap();
102                 assertedStatementsMap = new DoubleKeyQueryHashMap();
103                 asyncReadEntryMap = new StableHashMap<AsyncRead, AsyncReadEntry>(); 
104                 readEntryMap = new StableHashMap<Read, ReadEntry>();
105                 asyncMultiReadEntryMap = new StableHashMap<AsyncMultiRead, AsyncMultiReadEntry>(); 
106                 multiReadEntryMap = new StableHashMap<MultiRead, MultiReadEntry>(); 
107                 externalReadEntryMap = new StableHashMap<ExternalRead, ExternalReadEntry>(); 
108                 listeners = new THashMap<CacheEntry, ArrayList<ListenerEntry>>(10, 0.75f);
109         }
110
111 //      public <T> Object performQuery(ReadGraphImpl parentGraph, final AsyncRead<T> query, final CacheEntryBase entry_, AsyncProcedure procedure_) throws DatabaseException {
112 //
113 //              AsyncReadEntry<T> entry = (AsyncReadEntry<T>)entry_;
114 //              AsyncProcedure<T> procedure = (AsyncProcedure<T>)procedure_;
115 //
116 //              ReadGraphImpl queryGraph = parentGraph.withParent(entry_);
117 //
118 //              try {
119 //                      
120 //                      query.perform(queryGraph, new AsyncProcedure<T>() {
121 //
122 //                              @Override
123 //                              public void execute(AsyncReadGraph returnGraph, T result) {
124 //                                      ReadGraphImpl impl = (ReadGraphImpl)returnGraph;
125 //                                      entry.addOrSet(parentGraph, result);
126 //                                      try {
127 //                                              procedure.execute(parentGraph, result);
128 //                                      } catch (Throwable t) {
129 //                                              t.printStackTrace();
130 //                                      }
131 ////                                    parentBarrier.dec(query);
132 //                              }
133 //
134 //                              @Override
135 //                              public void exception(AsyncReadGraph returnGraph, Throwable t) {
136 //                                      ReadGraphImpl impl = (ReadGraphImpl)returnGraph;
137 ////                                    AsyncReadGraph resumeGraph = finalParentGraph.newAsync();
138 //                                      entry.except(parentGraph, t);
139 //                                      try {
140 //                                              procedure.exception(parentGraph, t);
141 //                                      } catch (Throwable t2) {
142 //                                              t2.printStackTrace();
143 //                                      }
144 ////                                    parentBarrier.dec(query);
145 //                              }
146 //
147 //                              @Override
148 //                              public String toString() {
149 //                                      return procedure.toString();
150 //                              }
151 //
152 //                      });
153 //
154 //              } catch (Throwable t) {
155 //
156 //                      entry.except(t);
157 //                      try {
158 //                              procedure.exception(parentGraph, t);
159 //                      } catch (Throwable t2) {
160 //                              t2.printStackTrace();
161 //                      }
162 ////                    parentBarrier.dec(query);
163 //
164 //              }
165 //              
166 //              return null;
167 //              
168 //      }
169
170 //      public <T> Object performQuery(ReadGraphImpl parentGraph, final Read<T> query, final CacheEntryBase entry_, AsyncProcedure procedure_) throws DatabaseException {
171 //
172 //              ReadGraphImpl queryGraph = parentGraph.withParent(entry_);
173 //
174 //              ReadEntry entry = (ReadEntry)entry_;
175 //
176 //              try {
177 //
178 //                      T result = (T)query.perform(queryGraph);
179 //                      entry.addOrSet(queryGraph, result);
180 //
181 //                      return (T)entry.get(parentGraph, procedure_);
182 //
183 //              }  catch (Throwable t) {
184 //
185 //                      entry.except(t);
186 //                      return (T)entry.get(parentGraph, procedure_);
187 //
188 //              }
189 //              
190 //      }
191
192
193         public <T> Object performQuery(ReadGraphImpl parentGraph, final AsyncMultiRead<T> query, final CacheEntryBase entry_, Object procedure_) throws DatabaseException {
194
195                 ReadGraphImpl queryGraph = parentGraph.withParent(entry_);
196
197                 AsyncMultiReadEntry entry = (AsyncMultiReadEntry)entry_;
198                 AsyncMultiProcedure<T> procedure = (AsyncMultiProcedure<T>)procedure_;
199
200                 try {
201
202                         query.perform(queryGraph, new AsyncMultiProcedure<T>() {
203
204                                 @Override
205                                 public void execute(AsyncReadGraph graph, T result) {
206                                         ReadGraphImpl impl = (ReadGraphImpl)graph;
207                                         entry.addOrSet(result);
208                                         try {
209                                                 procedure.execute(parentGraph, result);
210                                         } catch (Throwable t) {
211                                                 t.printStackTrace();
212                                         }
213                                 }
214
215                                 @Override
216                                 public void finished(AsyncReadGraph graph) {
217                                         ReadGraphImpl impl = (ReadGraphImpl)graph;
218                                         entry.finish(parentGraph);
219                                         try {
220                                                 procedure.finished(parentGraph);
221                                         } catch (Throwable t) {
222                                                 t.printStackTrace();
223                                         }
224                                 }
225
226                                 @Override
227                                 public void exception(AsyncReadGraph graph, Throwable t) {
228                                         ReadGraphImpl impl = (ReadGraphImpl)graph;
229                                         entry.except(parentGraph, t);
230                                         try {
231                                                 procedure.exception(parentGraph, t);
232                                         } catch (Throwable t2) {
233                                                 t2.printStackTrace();
234                                         }
235                                 }
236
237                         });
238
239                         return entry.getResult();
240
241                 } catch (Throwable t) {
242
243                         entry.except(t);
244                         try {
245                                 procedure.exception(parentGraph, t);
246                         } catch (Throwable t2) {
247                                 t2.printStackTrace();
248                         }
249
250                         return entry.getResult();
251
252                 }
253
254         }
255
256         public <T> Object performQuery(ReadGraphImpl parentGraph, final MultiRead<T> query, final CacheEntryBase entry_, Object procedure_) throws DatabaseException {
257
258                 ReadGraphImpl queryGraph = parentGraph.withParent(entry_);
259
260                 MultiReadEntry entry = (MultiReadEntry)entry_;
261                 SyncMultiProcedure<T> procedure = (SyncMultiProcedure<T>)procedure_;
262
263                 try {
264
265                         query.perform(queryGraph, new SyncMultiProcedure<T>() {
266
267                                 @Override
268                                 public void execute(ReadGraph graph, T result) {
269                                         ReadGraphImpl impl = (ReadGraphImpl)graph;
270                                         entry.addOrSet(result);
271                                         try {
272                                                 procedure.execute(parentGraph, result);
273                                         } catch (Throwable t) {
274                                                 t.printStackTrace();
275                                         }
276                                 }
277
278                                 @Override
279                                 public void finished(ReadGraph graph) {
280                                         ReadGraphImpl impl = (ReadGraphImpl)graph;
281                                         entry.finish(parentGraph);
282                                         try {
283                                                 procedure.finished(parentGraph);
284                                         } catch (Throwable t) {
285                                                 t.printStackTrace();
286                                         }
287                                 }
288
289                                 @Override
290                                 public void exception(ReadGraph graph, Throwable t) {
291                                         ReadGraphImpl impl = (ReadGraphImpl)graph;
292                                         entry.except((DatabaseException)t);
293                                         try {
294                                                 procedure.exception(parentGraph, t);
295                                         } catch (Throwable t2) {
296                                                 t2.printStackTrace();
297                                         }
298                                 }
299
300                         });
301
302                         return entry.getResult();
303
304                 } catch (Throwable t) {
305
306                         entry.except(t);
307                         try {
308                                 procedure.exception(parentGraph, t);
309                         } catch (Throwable t2) {
310                                 t2.printStackTrace();
311                         }
312
313                         return entry.getResult();
314
315                 }
316                 
317         }
318         
319         public ListenerEntry registerDependencies(ReadGraphImpl graph, CacheEntry child, CacheEntry parent, ListenerBase listener, Object procedure, boolean inferred) {
320
321                 if (parent != null && !inferred) {
322                         try {
323                                 if(!child.isImmutable(graph)) {
324                                         synchronized(child) {
325                                                 child.addParent(parent);
326                                         }
327                                 }
328                         } catch (DatabaseException e) {
329                                 Logger.defaultLogError(e);
330                         }
331                         if(DebugPolicy.DEPENDENCIES) System.out.println(child + " -> " + parent);
332                 }
333
334                 if (listener != null) {
335                         return registerListener(child, listener, procedure);
336                 } else {
337                         return null;
338                 }
339
340         }
341         
342         public synchronized ListenerEntry registerListener(final CacheEntry entry, final ListenerBase base, final Object procedure) {
343
344                 assert (entry != null);
345
346                 if (base.isDisposed())
347                         return null;
348
349                 return addListener(entry, base, procedure);
350
351         }
352
353         protected void primeListenerEntry(final ListenerEntry entry, final Object result) {
354                 entry.setLastKnown(result);
355         }
356
357         private ListenerEntry addListener(CacheEntry entry, ListenerBase base, Object procedure) {
358
359                 assert (entry != null);
360                 assert (procedure != null);
361
362                 ArrayList<ListenerEntry> list = listeners.get(entry);
363                 if (list == null) {
364                         list = new ArrayList<ListenerEntry>(1);
365                         listeners.put(entry, list);
366                 }
367
368                 ListenerEntry result = new ListenerEntry(entry, base, procedure);
369                 int currentIndex = list.indexOf(result);
370                 // There was already a listener
371                 if(currentIndex > -1) {
372                         ListenerEntry current = list.get(currentIndex);
373                         if(!current.base.isDisposed()) return null;
374                         list.set(currentIndex, result);
375                 } else {
376                         list.add(result);
377                 }
378
379                 if(DebugPolicy.LISTENER) {
380                         new Exception().printStackTrace();
381                         System.out.println("addListener -> " + list.size() + " " + entry + " " + base + " " + procedure);
382                 }
383
384                 return result;
385
386         }
387         
388         
389         public Collection<CacheEntry> getRootList() {
390
391                 ArrayList<CacheEntry> result = new ArrayList<CacheEntry>();
392
393                 for (Object e : valueQueryMap.values()) {
394                         result.add((CacheEntry) e);
395                 }
396                 for (Object e : directPredicatesMap.values()) {
397                         result.add((CacheEntry) e);
398                 }
399                 for (Object e : directSuperRelationsMap.values()) {
400                         result.add((CacheEntry) e);
401                 }
402                 for (Object e : objectsMap.values()) {
403                         result.add((CacheEntry) e);
404                 }
405                 for (Object e : directObjectsMap.values()) {
406                         result.add((CacheEntry) e);
407                 }
408                 for (Object e : principalTypesMap.values()) {
409                         result.add((CacheEntry) e);
410                 }
411                 for (Object e : superRelationsMap.values()) {
412                         result.add((CacheEntry) e);
413                 }
414                 for (Object e : superTypesMap.values()) {
415                         result.add((CacheEntry) e);
416                 }
417                 for (Object e : typesMap.values()) {
418                         result.add((CacheEntry) e);
419                 }
420                 for (Object e : objectsMap.values()) {
421                         result.add((CacheEntry) e);
422                 }
423                 for (Object e : assertedStatementsMap.values()) {
424                         result.add((CacheEntry) e);
425                 }
426                 for (Object e : readEntryMap.values()) {
427                         if(e instanceof CacheEntry) {
428                                 result.add((CacheEntry) e);
429                         } else {
430                                 System.err.println("e=" + e);
431                         }
432                 }
433                 for (Object e : asyncReadEntryMap.values()) {
434                         if(e instanceof CacheEntry) {
435                                 result.add((CacheEntry) e);
436                         } else {
437                                 System.err.println("e=" + e);
438                         }
439                 }
440                 for (Object e : externalReadEntryMap.values()) {
441                         result.add((CacheEntry) e);
442                 }
443                 for (Object e : orderedSetMap.values()) {
444                         result.add((CacheEntry) e);
445                 }
446
447                 return result;
448
449         }
450
451         public int calculateCurrentSize() {
452
453                 int realSize = 0;
454
455                 realSize += directPredicatesMap.size();
456                 realSize += directSuperRelationsMap.size();
457                 realSize += principalTypesMap.size();
458                 realSize += uRIToResourceMap.size();
459                 //realSize += namespaceIndexMap.size();
460                 realSize += childMapMap.size();
461
462                 realSize += relationInfoQueryMap.size();
463                 realSize += superTypesMap.size();
464                 realSize += typeHierarchyMap.size();
465                 realSize += superRelationsMap.size();
466                 realSize += typesMap.size();
467
468                 realSize += valueQueryMap.size();
469                 realSize += directObjectsMap.size();
470                 realSize += objectsMap.size();
471                 realSize += orderedSetMap.size();
472                 realSize += predicatesMap.size();
473
474                 realSize += statementsMap.size();
475                 realSize += assertedPredicatesMap.size();
476                 realSize += assertedStatementsMap.size();
477                 realSize += externalReadEntryMap.size();
478                 realSize += asyncReadEntryMap.size();
479
480                 realSize += readEntryMap.size();
481                 realSize += asyncMultiReadEntryMap.size();
482                 realSize += multiReadEntryMap.size();
483
484                 return realSize;
485
486         }
487
488         CacheCollectionResult allCaches(CacheCollectionResult result) {
489
490                 int level = Integer.MAX_VALUE;
491                 directPredicatesMap.values(level, result);
492                 directSuperRelationsMap.values(level, result);
493                 principalTypesMap.values(level, result);
494                 for(CacheEntryBase e : uRIToResourceMap.values())
495                         if(e.getLevel() <= level)
496                                 result.add(e);
497 //              for(CacheEntryBase e : namespaceIndexMap.values())
498 //                      if(e.getLevel() <= level)
499 //                              result.add(e);
500
501                 childMapMap.values(level, result);
502
503                 relationInfoQueryMap.values(level, result);
504                 superTypesMap.values(level, result);
505                 typeHierarchyMap.values(level, result);
506                 superRelationsMap.values(level, result);
507                 typesMap.values(level, result);
508
509                 valueQueryMap.values(level, result);
510                 directObjectsMap.values(level, result);
511                 objectsMap.values(level, result);
512                 orderedSetMap.values(level, result);
513                 predicatesMap.values(level, result);
514
515                 statementsMap.values(level, result);
516                 assertedPredicatesMap.values(level, result);
517                 assertedStatementsMap.values(level, result);
518                 externalReadEntryMap.values(level, result);
519                 asyncReadEntryMap.values(level, result);
520
521                 readEntryMap.values(level, result);
522                 asyncMultiReadEntryMap.values(level, result);
523                 multiReadEntryMap.values(level, result);
524
525                 return result;
526
527         }
528
529         public void scanPending() {
530
531                 ArrayList<CacheEntry> entries = new ArrayList<CacheEntry>();
532
533                 entries.addAll(directPredicatesMap.values());
534                 entries.addAll(directSuperRelationsMap.values());
535                 entries.addAll(principalTypesMap.values());
536                 entries.addAll(uRIToResourceMap.values());
537                 //entries.addAll(namespaceIndexMap.values());
538                 entries.addAll(childMapMap.values());
539                 entries.addAll(relationInfoQueryMap.values());
540                 entries.addAll(superTypesMap.values());
541                 entries.addAll(superRelationsMap.values());
542                 entries.addAll(typesMap.values());
543                 entries.addAll(valueQueryMap.values());
544                 entries.addAll(directObjectsMap.values());
545                 entries.addAll(objectsMap.values());
546                 entries.addAll(orderedSetMap.values());
547                 entries.addAll(predicatesMap.values());
548                 entries.addAll(orderedSetMap.values());
549                 entries.addAll(statementsMap.values());
550                 //                      entries.addAll(assertedObjectsMap.values());
551                 entries.addAll(assertedPredicatesMap.values());
552                 entries.addAll(assertedStatementsMap.values());
553                 entries.addAll(externalReadEntryMap.values());
554                 entries.addAll(asyncReadEntryMap.values());
555                 entries.addAll(externalReadEntryMap.values());
556                 entries.addAll(readEntryMap.values());
557                 entries.addAll(asyncMultiReadEntryMap.values());
558                 entries.addAll(multiReadEntryMap.values());
559                 entries.addAll(readEntryMap.values());
560                 System.out.println(entries.size() + " entries.");
561                 for(Object e : entries) {
562                         if(e instanceof CacheEntry) {
563                                 CacheEntry en = (CacheEntry)e;
564                                 if(en.isPending()) System.out.println("pending " + e);
565                                 if(en.isExcepted()) System.out.println("excepted " + e);
566                                 if(en.isDiscarded()) System.out.println("discarded " + e);
567                                 if(en.isRefuted()) System.out.println("refuted " + e);
568                                 if(en.isFresh()) System.out.println("fresh " + e);
569                         } else {
570                                 //System.out.println("Unknown object " + e);
571                         }
572                 }
573         }
574
575         public static void waitPending(ReadGraphImpl graph, CacheEntry entry) throws DatabaseException {
576
577                 int counter = 0;
578                 while(entry.isPending()) {
579                         try {
580                             boolean performed = graph.performPending();
581                             if(!performed) {
582                                         Thread.sleep(1);
583                                         counter++;
584                                         if(counter > 30000) {
585                                                 CacheEntryBase base = ((CacheEntryBase)entry);
586 //                                              if(base.created != null) {
587 //                                                      System.err.println("created:");
588 //                                                      base.created.printStackTrace();
589 //                                              }
590 //                                              if(base.performed != null) {
591 //                                                      System.err.println("performed:");
592 //                                                      base.performed.printStackTrace();
593 //                                              }
594 //                                              if(base.ready != null) {
595 //                                                      System.err.println("ready:");
596 //                                                      base.ready.printStackTrace();
597 //                                              }
598                                                 new Exception("Timeout waiting for request to complete: " + entry.getOriginalRequest()).printStackTrace();
599                                                 throw new DatabaseException("Timeout waiting for request to complete." +  entry.getOriginalRequest());
600                                                 //System.err.println("asd");
601                                                 //base.getQuery().recompute(null, null, entry);
602                                         }
603                                 }
604                         } catch (InterruptedException e) {
605                         }
606                 }
607
608         }
609
610         //////////////////////////////////////
611
612         public static Collection<Objects> entriesObjects(QueryProcessor processor, int r1) {
613                 synchronized(processor.cache.objectsMap) {
614                         return processor.cache.objectsMap.values(r1);
615                 }
616         }
617
618         public static Collection<Objects> entriesObjects(QueryProcessor processor) {
619                 synchronized(processor.cache.objectsMap) {
620                         return processor.cache.objectsMap.values();
621                 }
622         }
623
624         public static Collection<CacheEntry> entriesDirectPredicates(QueryProcessor processor) {
625                 synchronized(processor.cache.directPredicatesMap) {
626                         return processor.cache.directPredicatesMap.values();
627                 }
628         }
629
630         static final Collection<DirectObjects> entriesDirectObjects(final QueryProcessor processor, final int r1) {
631                 DoubleKeyQueryHashMap<IntProcedure> hash = processor.cache.directObjectsMap;
632                 return hash.values(r1);
633         }
634
635         static final Collection<Statements> entriesStatements(final QueryProcessor processor, final int r1) {
636                 return processor.cache.statementsMap.values(r1);
637         }
638
639         static final Types entryTypes(final QueryProcessor processor, final int r) {
640                 return (Types)processor.cache.typesMap.get(r);
641         }
642
643         static final PrincipalTypes entryPrincipalTypes(final QueryProcessor processor, final int r) {
644                 return (PrincipalTypes)processor.cache.principalTypesMap.get(r);
645         }
646
647         static final OrderedSet entryOrderedSet(final QueryProcessor processor, final int r) {
648                 return (OrderedSet)processor.cache.orderedSetMap.get(r);
649         }
650
651         static final ValueQuery entryValueQuery(final QueryProcessor processor, final int r) {
652                 return (ValueQuery)processor.cache.valueQueryMap.get(r);
653         }
654
655         static final DirectPredicates entryDirectPredicates(final QueryProcessor processor, final int r) {
656                 return (DirectPredicates)processor.cache.directPredicatesMap.get(r);
657         }
658
659         public static final ReadEntry entryRead(final QueryProcessor processor, final Read request) {
660                 return (ReadEntry)processor.cache.readEntryMap.get(request);
661         }
662
663         public static final MultiReadEntry entryMultiRead(final QueryProcessor processor, final MultiRead request) {
664                 return (MultiReadEntry)processor.cache.multiReadEntryMap.get(request);
665         }
666
667         public static final AsyncReadEntry entryAsyncRead(final QueryProcessor processor, final AsyncRead request) {
668                 return (AsyncReadEntry)processor.cache.asyncReadEntryMap.get(request);
669         }
670
671         public static final AsyncMultiReadEntry entryAsyncMultiRead(final QueryProcessor processor, final AsyncMultiRead request) {
672                 return (AsyncMultiReadEntry)processor.cache.asyncMultiReadEntryMap.get(request);
673         }
674
675         protected static final long keyR2(long r1, long r2) {
676                 long result = (r1<<32) | (r2 & 0xffffffffL); 
677                 return result;
678         }
679
680         protected static final <T> T id(T o) {
681                 return o;
682         }
683
684         protected static final int keyR(int r) {
685                 return r;
686         }
687
688         protected static final String keyID(String id) {
689                 return id;
690         }
691
692         protected static InternalProcedure<IntSet> emptyIntSetProcedure = new InternalProcedure<IntSet>() {
693
694                 @Override
695                 public void execute(ReadGraphImpl graph, IntSet result) {
696                 }
697
698                 @Override
699                 public void exception(ReadGraphImpl graph, Throwable throwable) {
700                 }
701
702         }; 
703
704         protected static InternalProcedure<byte[]> emptyBytesProcedure = new InternalProcedure<byte[]>() {
705
706                 @Override
707                 public void execute(ReadGraphImpl graph, byte[] bytes) {
708                 }
709
710                 @Override
711                 public void exception(ReadGraphImpl graph, Throwable throwable) {
712                 }
713
714         }; 
715
716         protected static InternalProcedure<Integer> emptyIntegerProcedure = new InternalProcedure<Integer>() {
717
718                 @Override
719                 public void execute(ReadGraphImpl graph, Integer i) {
720                 }
721
722                 @Override
723                 public void exception(ReadGraphImpl graph, Throwable throwable) {
724                 }
725
726         }; 
727
728
729         protected static InternalProcedure<TObjectIntHashMap<String>> emptyNamespaceProcedure = new InternalProcedure<TObjectIntHashMap<String>>() {
730
731                 @Override
732                 public void execute(ReadGraphImpl graph, TObjectIntHashMap<String> i) {
733                 }
734
735                 @Override
736                 public void exception(ReadGraphImpl graph, Throwable throwable) {
737                 }
738
739         }; 
740
741
742         protected static InternalProcedure<RelationInfo> emptyRelationInfoProcedure = new InternalProcedure<RelationInfo>() {
743
744                 @Override
745                 public void execute(ReadGraphImpl graph, RelationInfo i) {
746                 }
747
748                 @Override
749                 public void exception(ReadGraphImpl graph, Throwable throwable) {
750                 }
751
752         };
753
754         protected static InternalProcedure<ObjectResourceIdMap<String>> emptyChildMapProcedure = new InternalProcedure<ObjectResourceIdMap<String>>() {
755
756                 @Override
757                 public void execute(ReadGraphImpl graph, ObjectResourceIdMap<String> i) {
758                 }
759
760                 @Override
761                 public void exception(ReadGraphImpl graph, Throwable throwable) {
762                 }
763
764         };
765
766         protected static IntProcedure emptyIntProcedure = new IntProcedure() {
767
768                 @Override
769                 public void finished(ReadGraphImpl graph) {
770                 }
771
772                 @Override
773                 public void execute(ReadGraphImpl graph, int i) {
774                 }
775
776                 @Override
777                 public void exception(ReadGraphImpl graph, Throwable throwable) {
778                 }
779         };
780
781         protected static TripleIntProcedure emptyTripleIntProcedure = new TripleIntProcedure() {
782
783                 @Override
784                 public void execute(ReadGraphImpl graph, int s, int p, int o) {
785                 }
786
787                 @Override
788                 public void finished(ReadGraphImpl graph) {
789                 }
790
791                 @Override
792                 public void exception(ReadGraphImpl graph, Throwable throwable) {
793                 }
794
795         }; 
796
797         protected static AsyncProcedure<Object> emptyAsyncProcedure = new AsyncProcedure<Object>() {
798
799                 @Override
800                 public void execute(AsyncReadGraph graph, Object result) {
801                 }
802
803                 @Override
804                 public void exception(AsyncReadGraph graph, Throwable throwable) {
805                 }
806
807         };
808
809         protected static AsyncMultiProcedure<Object> emptyAsyncMultiProcedure = new AsyncMultiProcedure<Object>() {
810
811                 @Override
812                 public void execute(AsyncReadGraph graph, Object result) {
813                 }
814
815                 @Override
816                 public void finished(AsyncReadGraph graph) {
817                 }
818
819                 @Override
820                 public void exception(AsyncReadGraph graph, Throwable throwable) {
821                 }
822
823         }; 
824
825         protected static SyncMultiProcedure<Object> emptySyncMultiProcedure = new SyncMultiProcedure<Object>() {
826
827                 @Override
828                 public void execute(ReadGraph graph, Object result) {
829                 }
830
831                 @Override
832                 public void finished(ReadGraph graph) {
833                 }
834
835                 @Override
836                 public void exception(ReadGraph graph, Throwable throwable) {
837                 }
838
839         };
840
841         protected static InternalProcedure<IntSet> emptyProcedureTypes = emptyIntSetProcedure;
842         protected static InternalProcedure<IntSet> emptyProcedureSuperTypes = emptyIntSetProcedure;
843         protected static InternalProcedure<IntSet> emptyProcedureTypeHierarchy = emptyIntSetProcedure;
844         protected static InternalProcedure<IntSet> emptyProcedureSuperRelations = emptyIntSetProcedure;
845         protected static InternalProcedure<IntSet> emptyProcedurePredicates = emptyIntSetProcedure;
846         protected static InternalProcedure<IntSet> emptyProcedureDirectPredicates = emptyIntSetProcedure;
847
848         protected static IntProcedure emptyProcedureObjects = emptyIntProcedure;
849         protected static IntProcedure emptyProcedureDirectObjects = emptyIntProcedure;
850         protected static IntProcedure emptyProcedurePrincipalTypes = emptyIntProcedure;
851         protected static IntProcedure emptyProcedureDirectSuperRelations = emptyIntProcedure;
852         protected static IntProcedure emptyProcedureAssertedPredicates = emptyIntProcedure;
853         protected static IntProcedure emptyProcedureOrderedSet = emptyIntProcedure;
854
855         protected static TripleIntProcedure emptyProcedureStatements = emptyTripleIntProcedure;
856         protected static TripleIntProcedure emptyProcedureAssertedStatements = emptyTripleIntProcedure;
857
858         protected static InternalProcedure<byte[]> emptyProcedureValueQuery = emptyBytesProcedure;
859
860         protected static InternalProcedure<Integer> emptyProcedureURIToResource = emptyIntegerProcedure;
861         protected static InternalProcedure<TObjectIntHashMap<String>> emptyProcedureNamespaceIndex = emptyNamespaceProcedure;
862         protected static InternalProcedure<ObjectResourceIdMap<String>> emptyProcedureChildMap = emptyChildMapProcedure;
863         protected static InternalProcedure<RelationInfo> emptyProcedureRelationInfoQuery = emptyRelationInfoProcedure;
864
865         protected static AsyncProcedure emptyProcedureReadEntry = emptyAsyncProcedure;
866         protected static AsyncProcedure emptyProcedureAsyncReadEntry = emptyAsyncProcedure;
867         protected static SyncMultiProcedure emptyProcedureMultiReadEntry = emptySyncMultiProcedure;
868         protected static AsyncMultiProcedure emptyProcedureAsyncMultiReadEntry = emptyAsyncMultiProcedure;
869         protected static AsyncProcedure emptyProcedureExternalReadEntry = emptyAsyncProcedure;
870
871         static class AsyncProcedureWrapper<T> implements AsyncProcedure<T> {
872
873                 private AsyncProcedure<T> procedure;
874                 private T result = null;
875                 private Throwable throwable = null;
876                 private Semaphore s = new Semaphore(0);
877
878                 AsyncProcedureWrapper(AsyncProcedure<T> procedure) {
879                         this.procedure = procedure;
880                 }
881
882                 @Override
883                 public void execute(AsyncReadGraph graph, T result) {
884                         if(procedure != null) procedure.execute(graph, result);
885                         this.result = result;
886                         s.release();
887                 }
888
889                 @Override
890                 public void exception(AsyncReadGraph graph, Throwable throwable) {
891                         if(procedure != null) procedure.exception(graph, throwable);
892                         this.throwable = throwable;
893                         s.release();
894                 }
895
896                 public T get() throws DatabaseException {
897                         try {
898                                 s.acquire();
899                         } catch (InterruptedException e) {
900                                 e.printStackTrace();
901                         }
902                         if(throwable != null) {
903                                 if(throwable instanceof DatabaseException) throw (DatabaseException)throwable;
904                                 else throw new DatabaseException(throwable);
905                         } else {
906                                 return result;
907                         }
908                 }
909                 
910         }
911
912         static class ExternalProcedureWrapper<T> implements AsyncProcedure<T> {
913
914                 private Procedure<T> procedure;
915                 private T result = null;
916                 private Throwable throwable = null;
917
918                 ExternalProcedureWrapper(Procedure<T> procedure) {
919                         this.procedure = procedure;
920                 }
921
922                 @Override
923                 public void execute(AsyncReadGraph graph, T result) {
924                         if(procedure != null) procedure.execute(result);
925                         this.result = result;
926                 }
927
928                 @Override
929                 public void exception(AsyncReadGraph graph, Throwable throwable) {
930                         if(procedure != null) procedure.exception(throwable);
931                         this.throwable = throwable;
932                 }
933
934                 public T get() throws DatabaseException {
935                         if(throwable != null) {
936                                 if(throwable instanceof DatabaseException) throw (DatabaseException)throwable;
937                                 else throw new DatabaseException(throwable);
938                         } else {
939                                 return result;
940                         }
941                 }
942
943         }
944
945
946         static class InternalProcedureWrapper<T> implements InternalProcedure<T> {
947
948                 private InternalProcedure<T> procedure;
949                 private T result = null;
950                 private Throwable throwable = null;
951
952                 InternalProcedureWrapper(InternalProcedure<T> procedure) {
953                         this.procedure = procedure;
954                 }
955
956                 @Override
957                 public void execute(ReadGraphImpl graph, T result) throws DatabaseException {
958                         if(procedure != null) procedure.execute(graph, result);
959                         this.result = result;
960                 }
961
962                 @Override
963                 public void exception(ReadGraphImpl graph, Throwable throwable) throws DatabaseException {
964                         if(procedure != null) procedure.exception(graph, throwable);
965                         this.throwable = throwable;
966                 }
967
968                 public T get() throws DatabaseException {
969                         if(throwable != null) {
970                                 if(throwable instanceof DatabaseException) throw (DatabaseException)throwable;
971                                 else throw new DatabaseException(throwable);
972                         } else {
973                                 return result;
974                         }
975                 }
976
977         }
978
979         static class IntSetWrapper implements IntProcedure {
980
981                 private IntProcedure procedure;
982                 private final IntSet result;
983                 private Throwable throwable = null;
984
985                 IntSetWrapper(ReadGraphImpl graph, IntProcedure procedure) {
986                         this.procedure = procedure;
987                         result = new IntSet(graph.processor.querySupport);
988                 }
989
990                 @Override
991                 public void execute(ReadGraphImpl graph, int i) throws DatabaseException {
992                         if(procedure != null) procedure.execute(graph, i);
993                         result.add(i);
994                 }
995
996                 @Override
997                 public void exception(ReadGraphImpl graph, Throwable throwable) throws DatabaseException {
998                         if(procedure != null) procedure.exception(graph, throwable);
999                         this.throwable = throwable;
1000                 }
1001
1002                 @Override
1003                 public void finished(ReadGraphImpl graph) throws DatabaseException {
1004                         if(procedure != null) procedure.finished(graph);
1005                 }
1006
1007                 public IntSet get() throws DatabaseException {
1008                         if(throwable != null) {
1009                                 if(throwable instanceof DatabaseException) throw (DatabaseException)throwable;
1010                                 else throw new DatabaseException(throwable);
1011                         } else {
1012                                 return result;
1013                         }
1014                 }
1015
1016         }
1017
1018         static class TripleIntProcedureWrapper implements TripleIntProcedure {
1019
1020                 private TripleIntProcedure procedure;
1021                 private IntArray result = new IntArray();
1022                 private Throwable throwable = null;
1023
1024                 TripleIntProcedureWrapper(TripleIntProcedure procedure) {
1025                         this.procedure = procedure;
1026                 }
1027
1028                 @Override
1029                 public void execute(ReadGraphImpl graph, int i1, int i2, int i3) throws DatabaseException {
1030                         if(procedure != null) procedure.execute(graph, i1, i2, i3);
1031                         result.add(i1);
1032                         result.add(i2);
1033                         result.add(i3);
1034                 }
1035
1036                 @Override
1037                 public void exception(ReadGraphImpl graph, Throwable throwable) throws DatabaseException {
1038                         if(procedure != null) procedure.exception(graph, throwable);
1039                         this.throwable = throwable;
1040                 }
1041
1042                 @Override
1043                 public void finished(ReadGraphImpl graph) throws DatabaseException {
1044                         if(procedure != null) procedure.finished(graph);
1045                 }
1046
1047                 public IntArray get() throws DatabaseException {
1048                         if(throwable != null) {
1049                                 if(throwable instanceof DatabaseException) throw (DatabaseException)throwable;
1050                                 else throw new DatabaseException(throwable);
1051                         } else {
1052                                 return result;
1053                         }
1054                 }
1055
1056         }
1057
1058         public static <T> T resultExternalReadEntry(ReadGraphImpl graph, ExternalRead r, CacheEntry parent, ListenerBase listener, Procedure<T> procedure) throws DatabaseException {
1059                 ExternalProcedureWrapper<T> wrap = new ExternalProcedureWrapper<>(procedure);
1060                 QueryCache.runnerExternalReadEntry(graph, r, parent, listener, wrap);
1061                 return wrap.get();
1062         }
1063
1064         public static <T> T resultReadEntry(ReadGraphImpl graph, Read r, CacheEntry parent, ListenerBase listener, AsyncProcedure<T> procedure) throws DatabaseException {
1065                 return (T)QueryCache.runnerReadEntry(graph, r, parent, listener, procedure, true);
1066         }
1067
1068         public static <T> T resultAsyncReadEntry(ReadGraphImpl graph, AsyncRead r, CacheEntry parent, ListenerBase listener, AsyncProcedure<T> procedure) throws DatabaseException {
1069                 return (T)QueryCache.runnerAsyncReadEntry(graph, r, parent, listener, procedure, true);
1070         }
1071
1072         public static byte[] resultValueQuery(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener) throws DatabaseException {
1073                 InternalProcedureWrapper<byte[]> wrap = new InternalProcedureWrapper<>(null);
1074                 QueryCache.runnerValueQuery(graph, r, parent, listener, wrap);
1075                 return wrap.get();
1076         }
1077
1078         public static RelationInfo resultRelationInfoQuery(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener) throws DatabaseException {
1079                 InternalProcedureWrapper<RelationInfo> wrap = new InternalProcedureWrapper<>(null);
1080                 QueryCache.runnerRelationInfoQuery(graph, r, parent, listener, wrap);
1081                 return wrap.get();
1082         }
1083
1084         public static IntSet resultSuperRelations(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener) throws DatabaseException {
1085                 InternalProcedureWrapper<IntSet> wrap = new InternalProcedureWrapper<>(null);
1086                 QueryCache.runnerSuperRelations(graph, r, parent, listener, wrap);
1087                 return wrap.get();
1088         }
1089
1090         public static IntSet resultSuperTypes(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener) throws DatabaseException {
1091                 InternalProcedureWrapper<IntSet> wrap = new InternalProcedureWrapper<>(null);
1092                 QueryCache.runnerSuperTypes(graph, r, parent, listener, wrap);
1093                 return wrap.get();
1094         }
1095
1096         public static IntSet resultTypes(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener) throws DatabaseException {
1097                 InternalProcedureWrapper<IntSet> wrap = new InternalProcedureWrapper<>(null);
1098                 QueryCache.runnerTypes(graph, r, parent, listener, wrap);
1099                 return wrap.get();
1100         }
1101
1102         public static IntSet resultPredicates(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener) throws DatabaseException {
1103                 InternalProcedureWrapper<IntSet> wrap = new InternalProcedureWrapper<>(null);
1104                 QueryCache.runnerPredicates(graph, r, parent, listener, wrap);
1105                 return wrap.get();
1106         }
1107
1108         public static IntSet resultDirectPredicates(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener) throws DatabaseException {
1109                 InternalProcedureWrapper<IntSet> wrap = new InternalProcedureWrapper<>(null);
1110                 QueryCache.runnerDirectPredicates(graph, r, parent, listener, wrap);
1111                 return wrap.get();
1112         }
1113
1114         public static IntArray resultAssertedStatements(ReadGraphImpl graph, int r1, int r2, CacheEntry parent, ListenerBase listener) throws DatabaseException {
1115                 TripleIntProcedureWrapper wrap = new TripleIntProcedureWrapper(null);
1116                 QueryCache.runnerAssertedStatements(graph, r1, r2, parent, listener, wrap);
1117                 return wrap.get();
1118         }
1119
1120         public static Integer resultURIToResource(ReadGraphImpl graph, String id, CacheEntry parent, ListenerBase listener) throws DatabaseException {
1121                 InternalProcedureWrapper<Integer> wrap = new InternalProcedureWrapper<Integer>(null);
1122                 QueryCache.runnerURIToResource(graph, id, parent, listener, wrap);
1123                 return wrap.get();
1124         }
1125
1126         public static ObjectResourceIdMap<String> resultChildMap(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener) throws DatabaseException {
1127                 InternalProcedureWrapper<ObjectResourceIdMap<String>> wrap = new InternalProcedureWrapper<ObjectResourceIdMap<String>>(null);
1128                 QueryCache.runnerChildMap(graph, r, parent, listener, wrap);
1129                 return wrap.get();
1130         }
1131
1132         static boolean shouldCache(QueryProcessor processor, int r) {
1133                 return processor.isImmutable(r);
1134         }
1135
1136         static boolean shouldCache(QueryProcessor processor, int r, int r2) {
1137                 return processor.isImmutable(r);
1138         }
1139
1140         static boolean shouldCache(QueryProcessor processor, Object o) {
1141                 return false;
1142         }
1143
1144 }