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