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