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