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