1 /*******************************************************************************
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.db.impl.query;
14 import java.io.BufferedOutputStream;
16 import java.io.FileOutputStream;
17 import java.io.IOException;
18 import java.io.PrintStream;
19 import java.util.ArrayList;
20 import java.util.Arrays;
21 import java.util.Collection;
22 import java.util.Collections;
23 import java.util.HashMap;
24 import java.util.HashSet;
25 import java.util.IdentityHashMap;
26 import java.util.Iterator;
27 import java.util.LinkedList;
28 import java.util.List;
31 import java.util.concurrent.Semaphore;
32 import java.util.concurrent.atomic.AtomicBoolean;
33 import java.util.concurrent.atomic.AtomicInteger;
35 import org.simantics.databoard.Bindings;
36 import org.simantics.db.AsyncReadGraph;
37 import org.simantics.db.DevelopmentKeys;
38 import org.simantics.db.DirectStatements;
39 import org.simantics.db.ReadGraph;
40 import org.simantics.db.RelationInfo;
41 import org.simantics.db.Resource;
42 import org.simantics.db.Session;
43 import org.simantics.db.Statement;
44 import org.simantics.db.VirtualGraph;
45 import org.simantics.db.common.procedure.adapter.AsyncMultiProcedureAdapter;
46 import org.simantics.db.common.utils.Logger;
47 import org.simantics.db.exception.DatabaseException;
48 import org.simantics.db.exception.ManyObjectsForFunctionalRelationException;
49 import org.simantics.db.exception.NoInverseException;
50 import org.simantics.db.exception.ResourceNotFoundException;
51 import org.simantics.db.impl.ResourceImpl;
52 import org.simantics.db.impl.graph.BarrierTracing;
53 import org.simantics.db.impl.graph.ReadGraphImpl;
54 import org.simantics.db.impl.graph.ReadGraphSupport;
55 import org.simantics.db.impl.procedure.IntProcedureAdapter;
56 import org.simantics.db.impl.procedure.InternalProcedure;
57 import org.simantics.db.impl.procedure.TripleIntProcedureAdapter;
58 import org.simantics.db.impl.support.ResourceSupport;
59 import org.simantics.db.procedure.AsyncMultiListener;
60 import org.simantics.db.procedure.AsyncMultiProcedure;
61 import org.simantics.db.procedure.AsyncProcedure;
62 import org.simantics.db.procedure.AsyncSetListener;
63 import org.simantics.db.procedure.ListenerBase;
64 import org.simantics.db.procedure.MultiProcedure;
65 import org.simantics.db.procedure.StatementProcedure;
66 import org.simantics.db.procedure.SyncMultiProcedure;
67 import org.simantics.db.request.AsyncMultiRead;
68 import org.simantics.db.request.ExternalRead;
69 import org.simantics.db.request.MultiRead;
70 import org.simantics.db.request.RequestFlags;
71 import org.simantics.layer0.Layer0;
72 import org.simantics.utils.DataContainer;
73 import org.simantics.utils.Development;
74 import org.simantics.utils.datastructures.Pair;
75 import org.simantics.utils.datastructures.collections.CollectionUtils;
76 import org.simantics.utils.datastructures.disposable.AbstractDisposable;
78 import gnu.trove.procedure.TIntProcedure;
79 import gnu.trove.procedure.TLongProcedure;
80 import gnu.trove.procedure.TObjectProcedure;
81 import gnu.trove.set.hash.THashSet;
82 import gnu.trove.set.hash.TIntHashSet;
84 @SuppressWarnings({"rawtypes", "unchecked"})
85 final public class QueryProcessor extends AbstractDisposable implements ReadGraphSupport {
87 public static int indent = 0;
92 public int boundQueries = 0;
95 final private int functionalRelation;
97 final private int superrelationOf;
99 final private int instanceOf;
101 final private int inverseOf;
103 final private int asserts;
105 final private int hasPredicate;
107 final private int hasPredicateInverse;
109 final private int hasObject;
111 final private int inherits;
113 final private int subrelationOf;
115 final private int rootLibrary;
118 * A cache for the root library resource. Initialized in
119 * {@link #getRootLibraryResource()}.
121 private volatile ResourceImpl rootLibraryResource;
123 final private int library;
125 final private int consistsOf;
127 final private int hasName;
129 AtomicInteger sleepers = new AtomicInteger(0);
131 boolean updating = false;
134 final public QueryCache cache;
135 final public QuerySupport querySupport;
136 final public Session session;
137 final public ResourceSupport resourceSupport;
139 final public Semaphore requests = new Semaphore(1);
141 final public QueryListening listening = new QueryListening(this);
143 QueryThread[] executors;
147 INIT, RUN, SLEEP, DISPOSED
151 final Scheduling scheduling;
153 public ThreadState[] threadStates;
155 final Object querySupportLock;
157 public Long modificationCounter = 0L;
159 public void close() {
164 * We are running errands while waiting for requests to complete.
165 * We can only run work that is part of the current root request to avoid any deadlocks
167 public boolean performPending(ReadGraphImpl under) {
168 SessionTask task = scheduling.getSubTask(under);
170 task.run(thread.get());
176 final public void scheduleNow(SessionTask request) {
177 SessionTask toExecute = scheduleOrReturnForExecution(request);
178 if(toExecute != null)
179 toExecute.run(thread.get());
182 final public SessionTask scheduleOrReturnForExecution(SessionTask request) {
184 return scheduling.scheduleOrReturnForExecution(request);
190 final public int THREAD_MASK;
192 final public static ThreadGroup QueryThreadGroup = new ThreadGroup("Query Thread Group");
194 public static abstract class SessionTask {
196 final protected ReadGraphImpl rootGraph;
197 private int counter = 0;
198 protected int position = 1;
199 private Exception trace;
201 public SessionTask() {
205 public SessionTask(ReadGraphImpl rootGraph) {
206 this.rootGraph = rootGraph;
209 public boolean isSubtask(ReadGraphImpl graph) {
210 return graph.isParent(rootGraph);
213 public abstract void run0(int thread);
215 public final void run(int thread) {
217 if(BarrierTracing.BOOKKEEPING) {
218 trace.printStackTrace();
219 new Exception().printStackTrace();
221 throw new IllegalStateException("Multiple invocations of SessionTask!");
223 if(BarrierTracing.BOOKKEEPING) {
224 trace = new Exception();
229 public boolean maybeReady() {
234 public String toString() {
235 if(rootGraph == null)
236 return "SessionTask[no graph]";
238 return "SessionTask[" + rootGraph.parent + "]";
243 public static abstract class SessionRead extends SessionTask {
245 final public Semaphore notify;
246 final public DataContainer<Throwable> throwable;
248 public SessionRead(DataContainer<Throwable> throwable, Semaphore notify) {
250 this.throwable = throwable;
251 this.notify = notify;
256 public boolean resume(ReadGraphImpl graph) {
257 return executors[0].runSynchronized();
260 public QueryProcessor(final int threads, QuerySupport core, Set<Thread> threadSet)
261 throws DatabaseException {
264 THREAD_MASK = threads - 1;
266 scheduling = new Scheduling(requests);
269 cache = new QueryCache(core, threads);
270 session = querySupport.getSession();
271 resourceSupport = querySupport.getSupport();
272 querySupportLock = core.getLock();
274 executors = new QueryThread[THREADS];
275 threadStates = new ThreadState[THREADS];
277 for (int i = 0; i < THREADS; i++) {
278 threadStates[i] = ThreadState.INIT;
281 for (int i = 0; i < THREADS; i++) {
285 executors[i] = new QueryThread(session, this, index, "Query Thread " + index);
287 threadSet.add(executors[i]);
292 for (int i = 0; i < THREADS; i++) {
293 executors[i].start();
296 // Make sure that query threads are up and running
297 while(sleepers.get() != THREADS) {
300 } catch (InterruptedException e) {
305 rootLibrary = core.getBuiltin("http:/");
306 boolean builtinsInstalled = rootLibrary != 0;
308 if (builtinsInstalled) {
309 functionalRelation = core.getBuiltin(Layer0.URIs.FunctionalRelation);
310 assert (functionalRelation != 0);
312 functionalRelation = 0;
314 if (builtinsInstalled) {
315 instanceOf = core.getBuiltin(Layer0.URIs.InstanceOf);
316 assert (instanceOf != 0);
320 if (builtinsInstalled) {
321 inverseOf = core.getBuiltin(Layer0.URIs.InverseOf);
322 assert (inverseOf != 0);
327 if (builtinsInstalled) {
328 inherits = core.getBuiltin(Layer0.URIs.Inherits);
329 assert (inherits != 0);
333 if (builtinsInstalled) {
334 asserts = core.getBuiltin(Layer0.URIs.Asserts);
335 assert (asserts != 0);
339 if (builtinsInstalled) {
340 hasPredicate = core.getBuiltin(Layer0.URIs.HasPredicate);
341 assert (hasPredicate != 0);
345 if (builtinsInstalled) {
346 hasPredicateInverse = core.getBuiltin(Layer0.URIs.HasPredicateInverse);
347 assert (hasPredicateInverse != 0);
349 hasPredicateInverse = 0;
351 if (builtinsInstalled) {
352 hasObject = core.getBuiltin(Layer0.URIs.HasObject);
353 assert (hasObject != 0);
357 if (builtinsInstalled) {
358 subrelationOf = core.getBuiltin(Layer0.URIs.SubrelationOf);
359 assert (subrelationOf != 0);
363 if (builtinsInstalled) {
364 superrelationOf = core.getBuiltin(Layer0.URIs.SuperrelationOf);
365 assert (superrelationOf != 0);
369 if (builtinsInstalled) {
370 library = core.getBuiltin(Layer0.URIs.Library);
371 assert (library != 0);
375 if (builtinsInstalled) {
376 consistsOf = core.getBuiltin(Layer0.URIs.ConsistsOf);
377 assert (consistsOf != 0);
381 if (builtinsInstalled) {
382 hasName = core.getBuiltin(Layer0.URIs.HasName);
383 assert (hasName != 0);
389 final public void releaseWrite(ReadGraphImpl graph) {
390 propagateChangesInQueryCache(graph);
391 modificationCounter++;
394 final public int getId(final Resource r) {
395 return querySupport.getId(r);
398 public QuerySupport getCore() {
402 public int getFunctionalRelation() {
403 return functionalRelation;
406 public int getInherits() {
410 public int getInstanceOf() {
414 public int getInverseOf() {
418 public int getSubrelationOf() {
419 return subrelationOf;
422 public int getSuperrelationOf() {
423 return superrelationOf;
426 public int getAsserts() {
430 public int getHasPredicate() {
434 public int getHasPredicateInverse() {
435 return hasPredicateInverse;
438 public int getHasObject() {
442 public int getRootLibrary() {
446 public Resource getRootLibraryResource() {
447 if (rootLibraryResource == null) {
448 // Synchronization is not needed here, it doesn't matter if multiple
449 // threads simultaneously set rootLibraryResource once.
450 int root = getRootLibrary();
452 throw new UnsupportedOperationException("database is not initialized, cannot get root library resource");
453 this.rootLibraryResource = new ResourceImpl(querySupport.getSupport(), root);
455 return rootLibraryResource;
458 public int getLibrary() {
462 public int getConsistsOf() {
466 public int getHasName() {
470 public void forResource(ReadGraphImpl graph, final String id, CacheEntry parent, final InternalProcedure<Integer> procedure) {
474 QueryCache.runnerURIToResource(graph, id, parent, null, new InternalProcedure<Integer>() {
477 public void execute(ReadGraphImpl graph, Integer result) throws DatabaseException {
479 if (result != null && result != 0) {
480 procedure.execute(graph, result);
484 // Fall back to using the fixed builtins.
485 // result = querySupport.getBuiltin(id);
486 // if (result != 0) {
487 // procedure.execute(graph, result);
492 // result = querySupport.getRandomAccessReference(id);
493 // } catch (ResourceNotFoundException e) {
494 // procedure.exception(graph, e);
499 procedure.execute(graph, result);
501 procedure.exception(graph, new ResourceNotFoundException(id));
507 public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
508 procedure.exception(graph, t);
512 } catch (DatabaseException e) {
516 procedure.exception(graph, e);
518 } catch (DatabaseException e1) {
520 Logger.defaultLogError(e1);
528 public void forBuiltin(ReadGraphImpl graph, final String id, CacheEntry parent, final InternalProcedure<Integer> procedure) throws DatabaseException {
530 Integer result = querySupport.getBuiltin(id);
532 procedure.execute(graph, result);
534 procedure.exception(graph, new ResourceNotFoundException(id));
539 final <T> void runMultiRead(final ReadGraphImpl graph, MultiReadEntry cached, final MultiRead<T> query, final CacheEntry parent, final QueryProcessor provider, final ListenerBase listener, final SyncMultiProcedure<T> procedure) {
542 QueryCache.runnerMultiReadEntry(graph, query, parent, listener, procedure);
543 } catch (DatabaseException e) {
544 throw new IllegalStateException(e);
549 public final <T> void runAsyncMultiRead(final ReadGraphImpl graph, final AsyncMultiRead<T> query, final CacheEntry parent, final ListenerBase listener, final AsyncMultiProcedure<T> procedure) {
553 QueryCache.runnerAsyncMultiReadEntry(graph, query, parent, listener, procedure);
554 } catch (DatabaseException e) {
555 throw new IllegalStateException(e);
560 final <T> void runPrimitiveRead(ReadGraphImpl graph, ExternalReadEntry cached, final ExternalRead<T> query, final CacheEntry parent, final QueryProcessor provider, final ListenerBase listener, final AsyncProcedure<T> procedure) throws DatabaseException {
561 QueryCache.runnerExternalReadEntry(graph, query, parent, listener, procedure);
565 // public <T> T query(final ReadGraphImpl graph, final Read<T> query, final CacheEntry parent, final AsyncProcedure<T> procedure, final ListenerBase listener) throws DatabaseException {
567 // return QueryCache.resultReadEntry(graph, query, parent, listener, procedure);
571 public <T> void queryMultiRead(final ReadGraphImpl graph, final MultiRead<T> query, final CacheEntry parent, final ListenerBase listener, final SyncMultiProcedure<T> procedure) throws DatabaseException {
573 QueryCache.runnerMultiReadEntry(graph, query, parent, listener, procedure);
577 public <T> void queryPrimitiveRead(final ReadGraphImpl graph, final ExternalRead<T> query, final CacheEntry parent, final ListenerBase listener, final AsyncProcedure<T> procedure) throws DatabaseException {
579 QueryCache.runnerExternalReadEntry(graph, query, parent, listener, procedure);
583 boolean isBound(ExternalReadEntry<?> entry) {
584 if(entry.hasParents()) return true;
585 else if(listening.hasListener(entry)) return true;
589 static class Dummy implements InternalProcedure<Object>, IntProcedure {
592 public void execute(ReadGraphImpl graph, int i) {
596 public void finished(ReadGraphImpl graph) {
600 public void execute(ReadGraphImpl graph, Object result) {
604 public void exception(ReadGraphImpl graph, Throwable throwable) {
609 private static final Dummy dummy = new Dummy();
612 public <Procedure> Object performForEach2(ReadGraphImpl graph, UnaryQuery<Procedure> query, CacheEntry parent, ListenerBase listener, Procedure procedure) throws Throwable {
614 if (DebugPolicy.PERFORM)
615 System.out.println("PE[ " + (query.hashCode() & THREAD_MASK) + "] " + query);
618 assert (!collecting);
620 assert(query.assertNotDiscarded());
622 registerDependencies(graph, query, parent, listener, procedure, false);
624 // FRESH, REFUTED, EXCEPTED go here
625 if (!query.isReady()) {
630 query.computeForEach(graph, this, (Procedure)dummy, true);
631 return query.get(graph, this, null);
637 return query.get(graph, this, procedure);
645 interface QueryCollectorSupport {
646 public CacheCollectionResult allCaches();
647 public Collection<CacheEntry> getRootList();
648 public int getCurrentSize();
649 public int calculateCurrentSize();
650 public CacheEntryBase iterate(int level);
651 public void remove();
652 public void setLevel(CacheEntryBase entry, int level);
653 public boolean start(boolean flush);
656 interface QueryCollector {
658 public void collect(int youngTarget, int allowedTimeInMs);
662 class QueryCollectorSupportImpl implements QueryCollectorSupport {
664 private static final boolean DEBUG = false;
665 private static final double ITERATION_RATIO = 0.2;
667 private CacheCollectionResult iteration = new CacheCollectionResult();
668 private boolean fresh = true;
669 private boolean needDataInStart = true;
671 QueryCollectorSupportImpl() {
675 public CacheCollectionResult allCaches() {
676 CacheCollectionResult result = new CacheCollectionResult();
677 QueryProcessor.this.allCaches(result);
682 public boolean start(boolean flush) {
683 // We need new data from query maps
685 if(needDataInStart || flush) {
686 // Last run ended after processing all queries => refresh data
687 restart(flush ? 0.0 : ITERATION_RATIO);
689 // continue with previous big data
691 // Notify caller about iteration situation
692 return iteration.isAtStart();
695 private void restart(double targetRatio) {
697 needDataInStart = true;
699 long start = System.nanoTime();
702 // We need new data from query maps
704 int iterationSize = iteration.size()+1;
705 int diff = calculateCurrentSize()-iterationSize;
707 double ratio = (double)diff / (double)iterationSize;
708 boolean dirty = Math.abs(ratio) >= targetRatio;
711 iteration = allCaches();
713 System.err.print("iterate: allCaches in " + 1e-9*(System.nanoTime()-start) + "s. (" + iteration.size() + ") ");
714 for(int i=0;i<CacheCollectionResult.LEVELS;i++)
715 System.err.print(" " + iteration.levels[i].size());
716 System.err.println("");
723 needDataInStart = false;
725 // We are returning here within the same GC round - reuse the cache table
734 public CacheEntryBase iterate(int level) {
736 CacheEntryBase entry = iteration.next(level);
738 restart(ITERATION_RATIO);
742 while(entry != null && entry.isDiscarded()) {
743 entry = iteration.next(level);
751 public void remove() {
756 public void setLevel(CacheEntryBase entry, int level) {
757 iteration.setLevel(entry, level);
760 public Collection<CacheEntry> getRootList() {
761 return cache.getRootList();
765 public int calculateCurrentSize() {
766 return cache.calculateCurrentSize();
770 public int getCurrentSize() {
775 // final private static int MINIMUM_SIZE = (int)(Runtime.getRuntime().maxMemory() / 600);
777 private QueryCollectorSupport collectorSupport = new QueryCollectorSupportImpl();
778 private QueryCollector collector = new QueryCollectorImpl(this, collectorSupport);
780 public int querySize() {
784 public void gc(int youngTarget, int allowedTimeInMs) {
786 collector.collect(youngTarget, allowedTimeInMs);
791 void processParentReport(CacheEntry entry, Map<CacheEntry, Set<CacheEntry>> workarea) {
793 if(entry.isDiscarded()) return;
794 if(workarea.containsKey(entry)) return;
796 Iterable<CacheEntry> parents = entry.getParents(this);
797 HashSet<CacheEntry> ps = new HashSet<CacheEntry>();
798 for(CacheEntry e : parents) {
799 if(e.isDiscarded()) continue;
801 processParentReport(e, workarea);
803 workarea.put(entry, ps);
807 public synchronized String reportQueryActivity(File file) throws IOException {
809 System.err.println("reportQueries " + file.getAbsolutePath());
814 PrintStream b = new PrintStream(new BufferedOutputStream(new FileOutputStream(file)));
816 List<Pair<String,Integer>> entries = CollectionUtils.valueSortedEntries(Development.histogram);
817 Collections.reverse(entries);
819 for(Pair<String,Integer> entry : entries) {
820 b.println(entry.first + ": " + entry.second);
825 Development.histogram.clear();
831 public synchronized String reportQueries(File file) throws IOException {
833 System.err.println("reportQueries " + file.getAbsolutePath());
838 PrintStream b = new PrintStream(new BufferedOutputStream(new FileOutputStream(file)));
840 long start = System.nanoTime();
842 // ArrayList<CacheEntry> all = ;
844 Map<CacheEntry, Set<CacheEntry>> workarea = new HashMap<CacheEntry, Set<CacheEntry>>();
845 Collection<CacheEntryBase> caches = allCaches(new CacheCollectionResult()).toCollection();
846 for(CacheEntryBase entry : caches) {
847 processParentReport(entry, workarea);
850 // for(CacheEntry e : all) System.err.println("entry: " + e);
852 long duration = System.nanoTime() - start;
853 System.err.println("Query root set in " + 1e-9*duration + "s.");
855 start = System.nanoTime();
857 HashMap<CacheEntry, Integer> flagMap = new HashMap<CacheEntry, Integer>();
861 for(CacheEntry entry : workarea.keySet()) {
862 boolean listener = listening.hasListenerAfterDisposing(entry);
863 boolean hasParents = entry.getParents(this).iterator().hasNext();
866 flagMap.put(entry, 0);
867 } else if (!hasParents) {
869 flagMap.put(entry, 1);
872 flagMap.put(entry, 2);
885 long start2 = System.nanoTime();
887 int boundCounter = 0;
888 int unboundCounter = 0;
889 int unknownCounter = 0;
891 for(CacheEntry<?> entry : workarea.keySet()) {
893 //System.err.println("process " + entry);
895 int flags = flagMap.get(entry);
896 int bindStatus = flags & 3;
898 if(bindStatus == 0) boundCounter++;
899 else if(bindStatus == 1) unboundCounter++;
900 else if(bindStatus == 2) unknownCounter++;
902 if(bindStatus < 2) continue;
905 for(CacheEntry parent : entry.getParents(this)) {
907 if(parent.isDiscarded()) flagMap.put(parent, 1);
909 int flags2 = flagMap.get(parent);
910 int bindStatus2 = flags2 & 3;
911 // Parent is bound => child is bound
912 if(bindStatus2 == 0) {
916 // Parent is unknown => child is unknown
917 else if (bindStatus2 == 2) {
924 flagMap.put(entry, newStatus);
928 duration = System.nanoTime() - start2;
929 System.err.println("Query analysis pass (" + boundCounter + "/" + unboundCounter + "/" + unknownCounter + ") in "+ 1e-9*duration + "s.");
930 b.println("Query analysis pass (" + boundCounter + "/" + unboundCounter + "/" + unknownCounter + ") in "+ 1e-9*duration + "s.");
932 } while(!done && loops++ < 20);
936 for(CacheEntry entry : workarea.keySet()) {
938 int bindStatus = flagMap.get(entry);
939 if(bindStatus == 2) System.err.println("Undefined bind status for " + entry);
945 duration = System.nanoTime() - start;
946 System.err.println("Query analysis in " + 1e-9*duration + "s.");
948 Map<Class<?>, Integer> counts = new HashMap<Class<?>, Integer>();
950 for(CacheEntry entry : workarea.keySet()) {
951 Class<?> clazz = entry.getClass();
952 if(entry instanceof ReadEntry) clazz = ((ReadEntry)entry).id.getClass();
953 else if(entry instanceof MultiReadEntry) clazz = ((MultiReadEntry)entry).id.getClass();
954 else if(entry instanceof AsyncReadEntry) clazz = ((AsyncReadEntry)entry).id.getClass();
955 else if(entry instanceof AsyncMultiReadEntry) clazz = ((AsyncMultiReadEntry)entry).id.getClass();
956 else if(entry instanceof ExternalReadEntry) clazz = ((ExternalReadEntry)entry).id.getClass();
957 Integer c = counts.get(clazz);
958 if(c == null) counts.put(clazz, -1);
959 else counts.put(clazz, c-1);
962 b.print("// Simantics DB client query report file\n");
963 b.print("// This file contains the following information\n");
964 b.print("// -The amount of cached query instances per query class\n");
965 b.print("// -The sizes of retained child sets\n");
966 b.print("// -List of parents for each query (search for 'P <query name>')\n");
967 b.print("// -Followed by status, where\n");
968 b.print("// -0=bound\n");
969 b.print("// -1=free\n");
970 b.print("// -2=unknown\n");
971 b.print("// -L=has listener\n");
972 b.print("// -List of children for each query (search for 'C <query name>')\n");
974 b.print("----------------------------------------\n");
976 b.print("// Queries by class\n");
977 for(Pair<Class<?>, Integer> p : CollectionUtils.valueSortedEntries(counts)) {
978 b.print(-p.second + " " + p.first.getName() + "\n");
981 Map<CacheEntry, Integer> hist = new HashMap<CacheEntry, Integer>();
982 for(CacheEntry e : workarea.keySet())
985 boolean changed = true;
987 while(changed && iter++<50) {
991 Map<CacheEntry, Integer> newHist = new HashMap<CacheEntry, Integer>();
992 for(CacheEntry e : workarea.keySet())
995 for(Map.Entry<CacheEntry, Set<CacheEntry>> e : workarea.entrySet()) {
996 Integer c = hist.get(e.getKey());
997 for(CacheEntry p : e.getValue()) {
998 Integer i = newHist.get(p);
1002 for(CacheEntry e : workarea.keySet()) {
1003 Integer value = newHist.get(e);
1004 Integer old = hist.get(e);
1005 if(!value.equals(old)) {
1007 // System.err.println("hist " + e + ": " + old + " => " + value);
1012 System.err.println("Retained set iteration " + iter);
1016 b.print("// Queries by retained set\n");
1017 for(Pair<CacheEntry, Integer> p : CollectionUtils.valueSortedEntries(hist)) {
1018 b.print("" + -p.second + " " + p.first + "\n");
1021 HashMap<CacheEntry, Collection<CacheEntry>> inverse = new HashMap<CacheEntry, Collection<CacheEntry>>();
1023 b.print("// Entry parent listing\n");
1024 for(CacheEntry entry : workarea.keySet()) {
1025 int status = flagMap.get(entry);
1026 boolean hasListener = listening.hasListenerAfterDisposing(entry);
1027 b.print("Q " + entry.toString());
1029 b.print(" (L" + status + ")");
1032 b.print(" (" + status + ")");
1035 for(CacheEntry parent : workarea.get(entry)) {
1036 Collection<CacheEntry> inv = inverse.get(parent);
1038 inv = new ArrayList<CacheEntry>();
1039 inverse.put(parent, inv);
1042 b.print(" " + parent.toString());
1047 b.print("// Entry child listing\n");
1048 for(Map.Entry<CacheEntry, Collection<CacheEntry>> entry : inverse.entrySet()) {
1049 b.print("C " + entry.getKey().toString());
1051 for(CacheEntry child : entry.getValue()) {
1052 Integer h = hist.get(child);
1056 b.print(" <no children>");
1058 b.print(" " + child.toString());
1063 b.print("#queries: " + workarea.keySet().size() + "\n");
1064 b.print("#listeners: " + listeners + "\n");
1068 return "Dumped " + workarea.keySet().size() + " queries.";
1072 boolean removeQuery(CacheEntry entry) {
1074 // This entry has been removed before. No need to do anything here.
1075 if(entry.isDiscarded()) return false;
1077 assert (!entry.isDiscarded());
1079 Query query = entry.getQuery();
1081 query.removeEntry(this);
1086 if((entry.getGCStatus() & CacheEntry.HAS_BEEN_BOUND) != 0)
1097 * @return true if this entry is being listened
1099 private boolean updateQuery(UpdateEntry e, LinkedList<UpdateEntry> todo, IdentityHashMap<CacheEntry, CacheEntry> immediates) throws DatabaseException {
1103 CacheEntry entry = e.entry;
1106 * If the dependency graph forms a DAG, some entries are inserted in the
1107 * todo list many times. They only need to be processed once though.
1109 if (entry.isDiscarded()) {
1110 if (Development.DEVELOPMENT) {
1111 if(Development.<Boolean>getProperty(DevelopmentKeys.QUERYPROCESSOR_UPDATE, Bindings.BOOLEAN)) {
1112 System.err.print("D");
1113 for (int i = 0; i < e.indent; i++)
1114 System.err.print(" ");
1115 System.err.println(entry.getQuery());
1118 // System.err.println(" => DISCARDED");
1122 // if (entry.isRefuted()) {
1123 // if (Development.DEVELOPMENT) {
1124 // if(Development.<Boolean>getProperty(DevelopmentKeys.QUERYPROCESSOR_UPDATE, Bindings.BOOLEAN)) {
1125 // System.err.print("R");
1126 // for (int i = 0; i < e.indent; i++)
1127 // System.err.print(" ");
1128 // System.err.println(entry.getQuery());
1134 if (entry.isExcepted()) {
1135 if (Development.DEVELOPMENT) {
1136 if(Development.<Boolean>getProperty(DevelopmentKeys.QUERYPROCESSOR_UPDATE, Bindings.BOOLEAN)) {
1137 System.err.print("E");
1142 if (entry.isPending()) {
1143 if (Development.DEVELOPMENT) {
1144 if(Development.<Boolean>getProperty(DevelopmentKeys.QUERYPROCESSOR_UPDATE, Bindings.BOOLEAN)) {
1145 System.err.print("P");
1152 if (Development.DEVELOPMENT) {
1153 if(Development.<Boolean>getProperty(DevelopmentKeys.QUERYPROCESSOR_UPDATE, Bindings.BOOLEAN)) {
1154 System.err.print("U ");
1155 for (int i = 0; i < e.indent; i++)
1156 System.err.print(" ");
1157 System.err.print(entry.getQuery());
1161 Query query = entry.getQuery();
1162 int type = query.type();
1164 boolean hasListener = listening.hasListener(entry);
1166 if (Development.DEVELOPMENT) {
1167 if(Development.<Boolean>getProperty(DevelopmentKeys.QUERYPROCESSOR_UPDATE, Bindings.BOOLEAN)) {
1168 if(listening.hasListener(entry)) {
1169 System.err.println(" (L)");
1171 System.err.println("");
1176 if(entry.isPending() || entry.isExcepted()) {
1179 if ((type & RequestFlags.UPDATE_MASK) == RequestFlags.IMMEDIATE_UPDATE) {
1181 immediates.put(entry, entry);
1196 if ((type & RequestFlags.UPDATE_MASK) == RequestFlags.IMMEDIATE_UPDATE) {
1198 immediates.put(entry, entry);
1212 // System.err.println(" => FOO " + type);
1215 ArrayList<ListenerEntry> entries = listening.listeners.get(entry);
1216 if(entries != null) {
1217 for (ListenerEntry le : entries) {
1218 listening.scheduleListener(le);
1223 // If invalid, update parents
1224 if (type == RequestFlags.INVALIDATE) {
1225 listening.updateParents(e.indent, entry, todo);
1233 * @param av1 an array (guaranteed)
1234 * @param av2 any object
1235 * @return <code>true</code> if the two arrays are equal
1237 private final boolean arrayEquals(Object av1, Object av2) {
1240 Class<?> c1 = av1.getClass().getComponentType();
1241 Class<?> c2 = av2.getClass().getComponentType();
1242 if (c2 == null || !c1.equals(c2))
1244 boolean p1 = c1.isPrimitive();
1245 boolean p2 = c2.isPrimitive();
1249 return Arrays.equals((Object[]) av1, (Object[]) av2);
1250 if (boolean.class.equals(c1))
1251 return Arrays.equals((boolean[]) av1, (boolean[]) av2);
1252 else if (byte.class.equals(c1))
1253 return Arrays.equals((byte[]) av1, (byte[]) av2);
1254 else if (int.class.equals(c1))
1255 return Arrays.equals((int[]) av1, (int[]) av2);
1256 else if (long.class.equals(c1))
1257 return Arrays.equals((long[]) av1, (long[]) av2);
1258 else if (float.class.equals(c1))
1259 return Arrays.equals((float[]) av1, (float[]) av2);
1260 else if (double.class.equals(c1))
1261 return Arrays.equals((double[]) av1, (double[]) av2);
1262 throw new RuntimeException("??? Contact application querySupport.");
1267 final Object compareTo(ReadGraphImpl graph, final CacheEntry entry, final Object oldValue) {
1271 Query query = entry.getQuery();
1273 if (Development.DEVELOPMENT) {
1274 if(Development.<Boolean>getProperty(DevelopmentKeys.QUERYPROCESSOR_RECOMPUTE, Bindings.BOOLEAN)) {
1275 System.err.println("R " + query);
1279 entry.prepareRecompute(querySupport);
1281 ReadGraphImpl parentGraph = graph.forRecompute(entry);
1282 parentGraph.asyncBarrier.inc();
1283 query.recompute(parentGraph);
1284 parentGraph.asyncBarrier.dec();
1286 if(entry.isExcepted()) return ListenerEntry.NO_VALUE;
1288 Object newValue = entry.getResult();
1290 if (ListenerEntry.NO_VALUE == oldValue) {
1291 if (Development.DEVELOPMENT) {
1292 if(Development.<Boolean>getProperty(DevelopmentKeys.QUERYPROCESSOR_CHANGES, Bindings.BOOLEAN)) {
1293 System.out.println("C " + query);
1294 System.out.println("- " + oldValue);
1295 System.out.println("- " + newValue);
1301 boolean changed = false;
1303 if (newValue != null) {
1304 if (newValue.getClass().isArray()) {
1305 changed = !arrayEquals(newValue, oldValue);
1307 changed = !newValue.equals(oldValue);
1310 changed = (oldValue != null);
1312 if (Development.DEVELOPMENT) {
1313 if(Development.<Boolean>getProperty(DevelopmentKeys.QUERYPROCESSOR_CHANGES, Bindings.BOOLEAN)) {
1314 System.err.println("C " + query);
1315 System.err.println("- " + oldValue);
1316 System.err.println("- " + newValue);
1320 return changed ? newValue : ListenerEntry.NOT_CHANGED;
1322 } catch (Throwable t) {
1324 Logger.defaultLogError(t);
1326 return ListenerEntry.NO_VALUE;
1335 * @return true if this entry still has listeners
1337 public boolean update(final ReadGraphImpl graph, final CacheEntry entry) {
1339 assert (!cache.collecting);
1343 boolean hadListeners = false;
1344 boolean listenersUnknown = false;
1348 assert(entry != null);
1349 LinkedList<UpdateEntry> todo = new LinkedList<UpdateEntry>();
1350 IdentityHashMap<CacheEntry, CacheEntry> immediates = new IdentityHashMap<CacheEntry, CacheEntry>();
1351 todo.add(new UpdateEntry(null, entry, 0));
1355 // Walk the tree and collect immediate updates
1356 while (!todo.isEmpty()) {
1357 UpdateEntry e = todo.pop();
1358 hadListeners |= updateQuery(e, todo, immediates);
1361 if(immediates.isEmpty()) break;
1363 // Evaluate all immediate updates and collect parents to update
1364 for(CacheEntry immediate : immediates.values()) {
1366 if(immediate.isDiscarded()) {
1370 if(immediate.isExcepted()) {
1372 Object newValue = compareTo(graph, immediate, ListenerEntry.NO_VALUE);
1373 if (newValue != ListenerEntry.NOT_CHANGED)
1374 listening.updateParents(0, immediate, todo);
1378 Object oldValue = immediate.getResult();
1379 Object newValue = compareTo(graph, immediate, oldValue);
1381 if (newValue != ListenerEntry.NOT_CHANGED) {
1382 listening.updateParents(0, immediate, todo);
1384 // If not changed, keep the old value
1385 immediate.setResult(oldValue);
1386 immediate.setReady();
1387 listenersUnknown = true;
1397 } catch (Throwable t) {
1398 Logger.defaultLogError(t);
1404 return hadListeners | listenersUnknown;
1408 private ObjectUpdateSet scheduledObjectUpdates = new ObjectUpdateSet();
1409 private ValueUpdateSet scheduledValueUpdates = new ValueUpdateSet();
1410 private ValueUpdateSet scheduledInvalidates = new ValueUpdateSet();
1411 // Maybe use a mutex from util.concurrent?
1412 private Object primitiveUpdateLock = new Object();
1413 private THashSet scheduledPrimitiveUpdates = new THashSet();
1415 private ArrayList<CacheEntry> refutations = new ArrayList<>();
1417 private void markForUpdate(ReadGraphImpl graph, CacheEntry e) {
1422 private void updateRefutations(ReadGraphImpl graph) {
1424 for(CacheEntry e : refutations)
1427 refutations.clear();
1431 public void propagateChangesInQueryCache(final ReadGraphImpl graph) {
1433 ReadGraphImpl syncGraph = graph.forSyncExecute();
1434 syncGraph.asyncBarrier.inc();
1435 propagateChangesInQueryCache_(syncGraph);
1436 syncGraph.asyncBarrier.dec();
1437 syncGraph.asyncBarrier.waitBarrier(this, syncGraph);
1442 public void propagateChangesInQueryCache_(final ReadGraphImpl graph) {
1444 // Make sure that listening has performed its work
1447 cache.dirty = false;
1450 if (Development.DEVELOPMENT) {
1451 if(Development.<Boolean>getProperty(DevelopmentKeys.QUERYPROCESSOR_UPDATE, Bindings.BOOLEAN)) {
1452 System.err.println("== Query update ==");
1456 // Special case - one statement
1457 if(scheduledObjectUpdates.size() == 1 && scheduledValueUpdates.size() == 0 && scheduledPrimitiveUpdates.size() == 0 && scheduledInvalidates.size() == 0) {
1459 long arg0 = scheduledObjectUpdates.getFirst();
1461 final int subject = (int)(arg0 >>> 32);
1462 final int predicate = (int)(arg0 & 0xffffffff);
1464 for(Objects o : QueryCache.entriesObjects(QueryProcessor.this, subject)) markForUpdate(graph, o);
1465 for(DirectObjects o : QueryCache.entriesDirectObjects(QueryProcessor.this, subject)) markForUpdate(graph, o);
1466 for(Statements o : QueryCache.entriesStatements(QueryProcessor.this, subject)) markForUpdate(graph, o);
1468 if(predicate == instanceOf || predicate == inherits || predicate == subrelationOf) {
1469 PrincipalTypes principalTypes = QueryCache.entryPrincipalTypes(QueryProcessor.this, subject);
1470 if(principalTypes != null) markForUpdate(graph, principalTypes);
1471 Types types = QueryCache.entryTypes(QueryProcessor.this, subject);
1472 if(types != null) markForUpdate(graph, types);
1475 if(predicate == subrelationOf) {
1476 SuperRelations superRelations = SuperRelations.entry(QueryProcessor.this, subject);
1477 if(superRelations != null) markForUpdate(graph, superRelations);
1480 DirectPredicates dp = QueryCache.entryDirectPredicates(QueryProcessor.this, subject);
1481 if(dp != null) markForUpdate(graph, dp);
1482 OrderedSet os = QueryCache.entryOrderedSet(QueryProcessor.this, predicate);
1483 if(os != null) markForUpdate(graph, os);
1485 updateRefutations(graph);
1487 scheduledObjectUpdates.clear();
1489 if (Development.DEVELOPMENT) {
1490 if(Development.<Boolean>getProperty(DevelopmentKeys.QUERYPROCESSOR_UPDATE, Bindings.BOOLEAN)) {
1491 System.err.println("== Query update ends ==");
1499 // Special case - one value
1500 if(scheduledObjectUpdates.size() == 0 && scheduledValueUpdates.size() == 1 && scheduledPrimitiveUpdates.size() == 0 && scheduledInvalidates.size() == 0) {
1502 int arg0 = scheduledValueUpdates.getFirst();
1504 ValueQuery valueQuery = QueryCache.entryValueQuery(QueryProcessor.this, arg0);
1505 if(valueQuery != null) markForUpdate(graph, valueQuery);
1507 updateRefutations(graph);
1509 scheduledValueUpdates.clear();
1511 if (Development.DEVELOPMENT) {
1512 if(Development.<Boolean>getProperty(DevelopmentKeys.QUERYPROCESSOR_UPDATE, Bindings.BOOLEAN)) {
1513 System.err.println("== Query update ends ==");
1521 final TIntHashSet predicates = new TIntHashSet();
1522 final TIntHashSet orderedSets = new TIntHashSet();
1524 THashSet primitiveUpdates;
1525 synchronized (primitiveUpdateLock) {
1526 primitiveUpdates = scheduledPrimitiveUpdates;
1527 scheduledPrimitiveUpdates = new THashSet();
1530 scheduledValueUpdates.forEach(new TIntProcedure() {
1533 public boolean execute(int arg0) {
1534 ValueQuery valueQuery = QueryCache.entryValueQuery(QueryProcessor.this, arg0);
1535 if(valueQuery != null) markForUpdate(graph, valueQuery);
1541 scheduledInvalidates.forEach(new TIntProcedure() {
1544 public boolean execute(int resource) {
1546 ValueQuery valueQuery = QueryCache.entryValueQuery(QueryProcessor.this, resource);
1547 if(valueQuery != null) markForUpdate(graph, valueQuery);
1549 PrincipalTypes principalTypes = QueryCache.entryPrincipalTypes(QueryProcessor.this, resource);
1550 if(principalTypes != null) markForUpdate(graph, principalTypes);
1551 Types types = QueryCache.entryTypes(QueryProcessor.this, resource);
1552 if(types != null) markForUpdate(graph, types);
1554 SuperRelations superRelations = SuperRelations.entry(QueryProcessor.this, resource);
1555 if(superRelations != null) markForUpdate(graph, superRelations);
1557 predicates.add(resource);
1564 scheduledObjectUpdates.forEach(new TLongProcedure() {
1567 public boolean execute(long arg0) {
1569 final int subject = (int)(arg0 >>> 32);
1570 final int predicate = (int)(arg0 & 0xffffffff);
1572 if(predicate == instanceOf || predicate == inherits || predicate == subrelationOf) {
1573 PrincipalTypes principalTypes = QueryCache.entryPrincipalTypes(QueryProcessor.this, subject);
1574 if(principalTypes != null) markForUpdate(graph, principalTypes);
1575 Types types = QueryCache.entryTypes(QueryProcessor.this, subject);
1576 if(types != null) markForUpdate(graph, types);
1579 if(predicate == subrelationOf) {
1580 SuperRelations superRelations = SuperRelations.entry(QueryProcessor.this, subject);
1581 if(superRelations != null) markForUpdate(graph, superRelations);
1584 predicates.add(subject);
1585 orderedSets.add(predicate);
1593 predicates.forEach(new TIntProcedure() {
1596 public boolean execute(final int subject) {
1598 for(Objects o : QueryCache.entriesObjects(QueryProcessor.this, subject)) markForUpdate(graph, o);
1599 for(DirectObjects o : QueryCache.entriesDirectObjects(QueryProcessor.this, subject)) markForUpdate(graph, o);
1600 for(Statements o : QueryCache.entriesStatements(QueryProcessor.this, subject)) markForUpdate(graph, o);
1602 DirectPredicates entry = QueryCache.entryDirectPredicates(QueryProcessor.this, subject);
1603 if(entry != null) markForUpdate(graph, entry);
1611 orderedSets.forEach(new TIntProcedure() {
1614 public boolean execute(int orderedSet) {
1616 OrderedSet entry = QueryCache.entryOrderedSet(QueryProcessor.this, orderedSet);
1617 if(entry != null) markForUpdate(graph, entry);
1625 updateRefutations(graph);
1627 primitiveUpdates.forEach(new TObjectProcedure() {
1630 public boolean execute(Object arg0) {
1632 ExternalReadEntry query = (ExternalReadEntry)cache.externalReadEntryMap.get(arg0);
1633 if (query != null) {
1634 boolean listening = update(graph, query);
1635 if (!listening && !query.hasParents()) {
1636 cache.externalReadEntryMap.remove(arg0);
1645 scheduledValueUpdates.clear();
1646 scheduledObjectUpdates.clear();
1647 scheduledInvalidates.clear();
1649 if (Development.DEVELOPMENT) {
1650 if(Development.<Boolean>getProperty(DevelopmentKeys.QUERYPROCESSOR_UPDATE, Bindings.BOOLEAN)) {
1651 System.err.println("== Query update ends ==");
1657 public void updateValue(final int resource) {
1658 scheduledValueUpdates.add(resource);
1662 public void updateStatements(final int resource, final int predicate) {
1663 scheduledObjectUpdates.add((((long)resource) << 32) + predicate);
1667 private int lastInvalidate = 0;
1669 public void invalidateResource(final int resource) {
1670 if(lastInvalidate == resource) return;
1671 //scheduledValueUpdates.add(resource);
1672 scheduledInvalidates.add(resource);
1673 lastInvalidate = resource;
1677 public void updatePrimitive(final ExternalRead primitive) {
1679 // External reads may be updated from arbitrary threads.
1680 // Synchronize to prevent race-conditions.
1681 synchronized (primitiveUpdateLock) {
1682 scheduledPrimitiveUpdates.add(primitive);
1684 querySupport.dirtyPrimitives();
1689 public synchronized String toString() {
1690 return "QueryProvider [size = " + cache.size + ", hits = " + cache.hits + " misses = " + cache.misses + ", updates = " + cache.updates + "]";
1694 protected void doDispose() {
1696 requests.release(Integer.MAX_VALUE / 2);
1698 for(int index = 0; index < THREADS; index++) {
1699 executors[index].dispose();
1703 for(int i=0;i<100;i++) {
1705 boolean alive = false;
1706 for(int index = 0; index < THREADS; index++) {
1707 alive |= executors[index].isAlive();
1712 } catch (InterruptedException e) {
1713 Logger.defaultLogError(e);
1718 // Then start interrupting
1719 for(int i=0;i<100;i++) {
1721 boolean alive = false;
1722 for(int index = 0; index < THREADS; index++) {
1723 alive |= executors[index].isAlive();
1726 for(int index = 0; index < THREADS; index++) {
1727 executors[index].interrupt();
1731 // // Then just destroy
1732 // for(int index = 0; index < THREADS; index++) {
1733 // executors[index].destroy();
1736 for(int index = 0; index < THREADS; index++) {
1738 executors[index].join(5000);
1739 } catch (InterruptedException e) {
1740 Logger.defaultLogError("QueryThread " + index + " will not die.", e);
1742 executors[index] = null;
1747 public int getHits() {
1751 public int getMisses() {
1752 return cache.misses;
1755 public int getSize() {
1759 public Set<Long> getReferencedClusters() {
1760 HashSet<Long> result = new HashSet<Long>();
1761 for (CacheEntry entry : QueryCache.entriesObjects(this)) {
1762 Objects query = (Objects) entry.getQuery();
1763 result.add(querySupport.getClusterId(query.r1()));
1765 for (CacheEntry entry : QueryCache.entriesDirectPredicates(this)) {
1766 DirectPredicates query = (DirectPredicates) entry.getQuery();
1767 result.add(querySupport.getClusterId(query.id));
1769 for (CacheEntry entry : cache.valueQueryMap.values()) {
1770 ValueQuery query = (ValueQuery) entry.getQuery();
1771 result.add(querySupport.getClusterId(query.id));
1776 public void assertDone() {
1779 CacheCollectionResult allCaches(CacheCollectionResult result) {
1781 return cache.allCaches(result);
1785 public void printDiagnostics() {
1788 public void requestCluster(ReadGraphImpl graph, long clusterId, Runnable runnable) {
1789 querySupport.requestCluster(graph, clusterId, runnable);
1792 public int clean() {
1793 collector.collect(0, Integer.MAX_VALUE);
1797 public void clean(final Collection<ExternalRead<?>> requests) {
1798 QueryCollectorSupport collectorSupport = new QueryCollectorSupport() {
1799 Iterator<ExternalRead<?>> iterator = requests.iterator();
1801 public CacheCollectionResult allCaches() {
1802 throw new UnsupportedOperationException();
1805 public CacheEntryBase iterate(int level) {
1806 if(iterator.hasNext()) {
1807 ExternalRead<?> request = iterator.next();
1808 ExternalReadEntry entry = cache.externalReadEntryMap.get(request);
1809 if (entry != null) return entry;
1810 else return iterate(level);
1812 iterator = requests.iterator();
1817 public void remove() {
1818 throw new UnsupportedOperationException();
1821 public void setLevel(CacheEntryBase entry, int level) {
1822 throw new UnsupportedOperationException();
1825 public Collection<CacheEntry> getRootList() {
1826 ArrayList<CacheEntry> result = new ArrayList<CacheEntry>(requests.size());
1827 for (ExternalRead<?> request : requests) {
1828 ExternalReadEntry entry = cache.externalReadEntryMap.get(request);
1835 public int getCurrentSize() {
1839 public int calculateCurrentSize() {
1840 // This tells the collector to attempt collecting everything.
1841 return Integer.MAX_VALUE;
1844 public boolean start(boolean flush) {
1848 new QueryCollectorImpl2(this, collectorSupport).collect(0, Integer.MAX_VALUE);
1851 public void scanPending() {
1853 cache.scanPending();
1857 public ReadGraphImpl graphForVirtualRequest() {
1858 return ReadGraphImpl.createAsync(this);
1862 private HashMap<Resource, Class<?>> builtinValues;
1864 public Class<?> getBuiltinValue(Resource r) {
1865 if(builtinValues == null) initBuiltinValues();
1866 return builtinValues.get(r);
1869 Exception callerException = null;
1871 public interface AsyncBarrier {
1874 public void waitBarrier(Object request, ReadGraphImpl impl);
1875 public boolean isBlocking();
1878 // final public QueryProcessor processor;
1879 // final public QuerySupport support;
1881 // boolean disposed = false;
1883 private void initBuiltinValues() {
1885 Layer0 b = getSession().peekService(Layer0.class);
1886 if(b == null) return;
1888 builtinValues = new HashMap<Resource, Class<?>>();
1890 builtinValues.put(b.String, String.class);
1891 builtinValues.put(b.Double, Double.class);
1892 builtinValues.put(b.Float, Float.class);
1893 builtinValues.put(b.Long, Long.class);
1894 builtinValues.put(b.Integer, Integer.class);
1895 builtinValues.put(b.Byte, Byte.class);
1896 builtinValues.put(b.Boolean, Boolean.class);
1898 builtinValues.put(b.StringArray, String[].class);
1899 builtinValues.put(b.DoubleArray, double[].class);
1900 builtinValues.put(b.FloatArray, float[].class);
1901 builtinValues.put(b.LongArray, long[].class);
1902 builtinValues.put(b.IntegerArray, int[].class);
1903 builtinValues.put(b.ByteArray, byte[].class);
1904 builtinValues.put(b.BooleanArray, boolean[].class);
1908 // public ReadGraphSupportImpl(final QueryProcessor provider2) {
1910 // if (null == provider2) {
1911 // this.processor = null;
1915 // this.processor = provider2;
1916 // support = provider2.getCore();
1917 // initBuiltinValues();
1921 // final static public ReadGraphSupportImpl basedOn(ReadGraphSupportImpl impl) {
1922 // return new ReadGraphSupportImpl(impl.processor);
1926 final public Session getSession() {
1930 final public ResourceSupport getResourceSupport() {
1931 return resourceSupport;
1935 final public void forEachPredicate(final ReadGraphImpl impl, final Resource subject, final AsyncMultiProcedure<Resource> procedure) {
1939 for(Resource predicate : getPredicates(impl, subject))
1940 procedure.execute(impl, predicate);
1942 procedure.finished(impl);
1944 } catch (Throwable e) {
1945 procedure.exception(impl, e);
1951 final public void forEachPredicate(final ReadGraphImpl impl, final Resource subject, final MultiProcedure<Resource> procedure) {
1953 throw new UnsupportedOperationException();
1955 // assert(subject != null);
1956 // assert(procedure != null);
1958 // final ListenerBase listener = getListenerBase(procedure);
1961 // QueryCache.runnerPredicates(impl, querySupport.getId(subject), impl.parent, listener, new IntProcedure() {
1964 // public void execute(ReadGraphImpl graph, int i) {
1966 // procedure.execute(querySupport.getResource(i));
1967 // } catch (Throwable t2) {
1968 // Logger.defaultLogError(t2);
1973 // public void finished(ReadGraphImpl graph) {
1975 // procedure.finished();
1976 // } catch (Throwable t2) {
1977 // Logger.defaultLogError(t2);
1979 //// impl.state.barrier.dec();
1983 // public void exception(ReadGraphImpl graph, Throwable t) {
1985 // procedure.exception(t);
1986 // } catch (Throwable t2) {
1987 // Logger.defaultLogError(t2);
1989 //// impl.state.barrier.dec();
1993 // } catch (DatabaseException e) {
1994 // Logger.defaultLogError(e);
2000 final public IntSet getPredicates(final ReadGraphImpl impl, final Resource subject) throws Throwable {
2001 return QueryCacheBase.resultPredicates(impl, querySupport.getId(subject), impl.parent, null);
2005 final public void forEachStatement(final ReadGraphImpl impl, final Resource subject,
2006 final Resource predicate, final MultiProcedure<Statement> procedure) {
2008 assert(subject != null);
2009 assert(predicate != null);
2010 assert(procedure != null);
2012 final ListenerBase listener = getListenerBase(procedure);
2014 // impl.state.barrier.inc();
2017 Statements.queryEach(impl, querySupport.getId(subject), querySupport.getId(predicate), this, impl.parent, listener, new TripleIntProcedureAdapter() {
2020 public void execute(ReadGraphImpl graph, int s, int p, int o) {
2022 procedure.execute(querySupport.getStatement(s, p, o));
2023 } catch (Throwable t2) {
2024 Logger.defaultLogError(t2);
2029 public void finished(ReadGraphImpl graph) {
2031 procedure.finished();
2032 } catch (Throwable t2) {
2033 Logger.defaultLogError(t2);
2035 // impl.state.barrier.dec();
2039 public void exception(ReadGraphImpl graph, Throwable t) {
2041 procedure.exception(t);
2042 } catch (Throwable t2) {
2043 Logger.defaultLogError(t2);
2045 // impl.state.barrier.dec();
2049 } catch (DatabaseException e) {
2050 Logger.defaultLogError(e);
2056 final public void forEachStatement(final ReadGraphImpl impl, final Resource subject,
2057 final Resource predicate, final AsyncMultiProcedure<Statement> procedure) {
2059 assert(subject != null);
2060 assert(predicate != null);
2061 assert(procedure != null);
2063 final ListenerBase listener = getListenerBase(procedure);
2065 TripleIntProcedureAdapter proc = new TripleIntProcedureAdapter() {
2067 boolean first = true;
2070 public void execute(ReadGraphImpl graph, int s, int p, int o) {
2073 procedure.execute(graph, querySupport.getStatement(s, p, o));
2075 procedure.execute(impl.newRestart(graph), querySupport.getStatement(s, p, o));
2077 } catch (Throwable t2) {
2078 Logger.defaultLogError(t2);
2083 public void finished(ReadGraphImpl graph) {
2088 procedure.finished(graph);
2089 // impl.state.barrier.dec(this);
2091 procedure.finished(impl.newRestart(graph));
2093 } catch (Throwable t2) {
2094 Logger.defaultLogError(t2);
2100 public void exception(ReadGraphImpl graph, Throwable t) {
2105 procedure.exception(graph, t);
2106 // impl.state.barrier.dec(this);
2108 procedure.exception(impl.newRestart(graph), t);
2110 } catch (Throwable t2) {
2111 Logger.defaultLogError(t2);
2118 int sId = querySupport.getId(subject);
2119 int pId = querySupport.getId(predicate);
2121 // if(AsyncBarrierImpl.BOOKKEEPING) impl.state.barrier.inc(proc, "#Statements" + sId + "#" + pId);
2122 // else impl.state.barrier.inc(null, null);
2125 Statements.queryEach(impl, sId, pId, this, impl.parent, listener, proc);
2126 } catch (DatabaseException e) {
2127 Logger.defaultLogError(e);
2133 final public void forEachStatement(final ReadGraphImpl impl, final Resource subject,
2134 final Resource predicate, final StatementProcedure procedure) {
2136 assert(subject != null);
2137 assert(predicate != null);
2138 assert(procedure != null);
2140 final ListenerBase listener = getListenerBase(procedure);
2142 TripleIntProcedureAdapter proc = new TripleIntProcedureAdapter() {
2144 boolean first = true;
2147 public void execute(ReadGraphImpl graph, int s, int p, int o) {
2150 procedure.execute(graph, s, p, o);
2152 procedure.execute(impl.newRestart(graph), s, p, o);
2154 } catch (Throwable t2) {
2155 Logger.defaultLogError(t2);
2160 public void finished(ReadGraphImpl graph) {
2165 procedure.finished(graph);
2166 // impl.state.barrier.dec(this);
2168 procedure.finished(impl.newRestart(graph));
2170 } catch (Throwable t2) {
2171 Logger.defaultLogError(t2);
2177 public void exception(ReadGraphImpl graph, Throwable t) {
2182 procedure.exception(graph, t);
2183 // impl.state.barrier.dec(this);
2185 procedure.exception(impl.newRestart(graph), t);
2187 } catch (Throwable t2) {
2188 Logger.defaultLogError(t2);
2195 int sId = querySupport.getId(subject);
2196 int pId = querySupport.getId(predicate);
2198 // if(AsyncBarrierImpl.BOOKKEEPING) impl.state.barrier.inc(proc, "#Statements" + sId + "#" + pId);
2199 // else impl.state.barrier.inc(null, null);
2202 Statements.queryEach(impl, sId, pId, this, impl.parent, listener, proc);
2203 } catch (DatabaseException e) {
2204 Logger.defaultLogError(e);
2210 final public void forStatementSet(final ReadGraphImpl impl, final Resource subject, final Resource predicate, final AsyncSetListener<Statement> procedure) {
2212 assert(subject != null);
2213 assert(predicate != null);
2214 assert(procedure != null);
2216 forEachStatement(impl, subject, predicate, new AsyncMultiListener<Statement>() {
2218 private Set<Statement> current = null;
2219 private Set<Statement> run = new HashSet<Statement>();
2222 public void execute(AsyncReadGraph graph, Statement result) {
2224 boolean found = false;
2226 if(current != null) {
2228 found = current.remove(result);
2232 if(!found) procedure.add(graph, result);
2239 public void finished(AsyncReadGraph graph) {
2241 if(current != null) {
2242 for(Statement r : current) procedure.remove(graph, r);
2247 run = new HashSet<Statement>();
2252 public void exception(AsyncReadGraph graph, Throwable t) {
2253 procedure.exception(graph, t);
2257 public boolean isDisposed() {
2258 return procedure.isDisposed();
2266 final public void forEachAssertedStatement(final ReadGraphImpl impl, final Resource subject,
2267 final Resource predicate, final AsyncMultiProcedure<Statement> procedure) {
2269 assert(subject != null);
2270 assert(predicate != null);
2271 assert(procedure != null);
2273 final ListenerBase listener = getListenerBase(procedure);
2275 // impl.state.barrier.inc();
2278 QueryCache.runnerAssertedStatements(impl, querySupport.getId(subject), querySupport.getId(predicate), impl.parent, listener, new TripleIntProcedureAdapter() {
2281 public void execute(ReadGraphImpl graph, int s, int p, int o) {
2283 procedure.execute(graph, querySupport.getStatement(s, p, o));
2284 } catch (Throwable t2) {
2285 Logger.defaultLogError(t2);
2290 public void finished(ReadGraphImpl graph) {
2292 procedure.finished(graph);
2293 } catch (Throwable t2) {
2294 Logger.defaultLogError(t2);
2296 // impl.state.barrier.dec();
2300 public void exception(ReadGraphImpl graph, Throwable t) {
2302 procedure.exception(graph, t);
2303 } catch (Throwable t2) {
2304 Logger.defaultLogError(t2);
2306 // impl.state.barrier.dec();
2310 } catch (DatabaseException e) {
2311 Logger.defaultLogError(e);
2316 private static ListenerBase getListenerBase(Object procedure) {
2317 if(procedure instanceof ListenerBase) return (ListenerBase)procedure;
2322 final public void forEachObject(final ReadGraphImpl impl, final Resource subject, final Resource predicate, final MultiProcedure<Resource> procedure) {
2324 assert(subject != null);
2325 assert(predicate != null);
2326 assert(procedure != null);
2328 final ListenerBase listener = getListenerBase(procedure);
2330 // impl.state.barrier.inc();
2333 QueryCache.runnerObjects(impl, querySupport.getId(subject), querySupport.getId(predicate), impl.parent, listener, new IntProcedure() {
2336 public void execute(ReadGraphImpl graph, int i) {
2338 procedure.execute(querySupport.getResource(i));
2339 } catch (Throwable t2) {
2340 Logger.defaultLogError(t2);
2345 public void finished(ReadGraphImpl graph) {
2347 procedure.finished();
2348 } catch (Throwable t2) {
2349 Logger.defaultLogError(t2);
2351 // impl.state.barrier.dec();
2355 public void exception(ReadGraphImpl graph, Throwable t) {
2356 System.out.println("forEachObject exception " + t);
2358 procedure.exception(t);
2359 } catch (Throwable t2) {
2360 Logger.defaultLogError(t2);
2362 // impl.state.barrier.dec();
2366 } catch (DatabaseException e) {
2367 Logger.defaultLogError(e);
2373 final public void forEachDirectPredicate(final ReadGraphImpl impl, final Resource subject, final AsyncProcedure<Set<Resource>> procedure) {
2375 assert(subject != null);
2376 assert(procedure != null);
2378 final ListenerBase listener = getListenerBase(procedure);
2380 int sId = querySupport.getId(subject);
2383 QueryCache.runnerDirectPredicates(impl, sId, impl.parent, listener, new InternalProcedure<IntSet>() {
2386 public void execute(ReadGraphImpl graph, IntSet result) throws DatabaseException {
2387 procedure.execute(graph, result);
2391 public void exception(ReadGraphImpl graph, Throwable throwable) throws DatabaseException {
2392 procedure.exception(graph, throwable);
2396 } catch (DatabaseException e) {
2397 Logger.defaultLogError(e);
2402 final public DirectStatements getDirectStatements(final ReadGraphImpl impl, final Resource subject, final boolean ignoreVirtual) {
2404 // assert(subject != null);
2405 // assert(procedure != null);
2407 // final ListenerBase listener = getListenerBase(procedure);
2409 // org.simantics.db.impl.query.DirectStatements.queryEach(impl, querySupport.getId(subject), this, impl.parent, listener, procedure);
2411 return querySupport.getStatements(impl, querySupport.getId(subject), this, ignoreVirtual);
2416 // final public void forEachDirectStatement(final ReadGraphImpl impl, final Resource subject, final SyncProcedure<DirectStatements> procedure, boolean ignoreVirtual) {
2418 // assert(subject != null);
2419 // assert(procedure != null);
2421 // final ListenerBase listener = getListenerBase(procedure);
2423 // org.simantics.db.impl.query.DirectStatements.queryEach(impl, querySupport.getId(subject), this, impl.parent, listener, procedure, ignoreVirtual);
2427 private static final Resource INVALID_RESOURCE = new ResourceImpl(null, Integer.MIN_VALUE);
2430 final public void forPossibleObject(final ReadGraphImpl impl, final Resource subject, final Resource predicate, final AsyncProcedure<Resource> procedure) {
2432 forEachObject(impl, subject, predicate, new AsyncMultiProcedure<Resource>() {
2434 private Resource single = null;
2437 public synchronized void execute(AsyncReadGraph graph, Resource result) {
2438 if(single == null) {
2441 single = INVALID_RESOURCE;
2446 public synchronized void finished(AsyncReadGraph graph) {
2447 if(single == null || single == INVALID_RESOURCE) procedure.execute(graph, null);
2448 else procedure.execute(graph, single);
2452 public synchronized void exception(AsyncReadGraph graph, Throwable throwable) {
2453 procedure.exception(graph, throwable);
2460 final public void forEachObject(final ReadGraphImpl impl, final Resource subject, final Resource predicate, final ListenerBase listener, final IntProcedure procedure) {
2462 final int sId = querySupport.getId(subject);
2463 final int pId = querySupport.getId(predicate);
2466 QueryCache.runnerObjects(impl, sId, pId, impl.parent, listener, procedure);
2467 } catch (DatabaseException e) {
2468 Logger.defaultLogError(e);
2473 static class Runner2Procedure implements IntProcedure {
2475 public int single = 0;
2476 public Throwable t = null;
2478 public void clear() {
2484 public void execute(ReadGraphImpl graph, int i) {
2485 if(single == 0) single = i;
2490 public void finished(ReadGraphImpl graph) {
2491 if(single == -1) single = 0;
2495 public void exception(ReadGraphImpl graph, Throwable throwable) {
2500 public int get() throws DatabaseException {
2502 if(t instanceof DatabaseException) throw (DatabaseException)t;
2503 else throw new DatabaseException(t);
2510 final public int getSingleObject(final ReadGraphImpl impl, final Resource subject, final Resource predicate) throws DatabaseException {
2512 final int sId = querySupport.getId(subject);
2513 final int pId = querySupport.getId(predicate);
2515 Runner2Procedure proc = new Runner2Procedure();
2516 QueryCache.runnerObjects(impl, sId, pId, impl.parent, null, proc);
2521 final public void forEachObject(final ReadGraphImpl impl, final Resource subject, final Resource predicate, final AsyncMultiProcedure<Resource> procedure) {
2523 assert(subject != null);
2524 assert(predicate != null);
2526 final ListenerBase listener = getListenerBase(procedure);
2528 if(impl.parent != null || listener != null) {
2530 IntProcedure ip = new IntProcedure() {
2532 AtomicBoolean first = new AtomicBoolean(true);
2535 public void execute(ReadGraphImpl graph, int i) {
2538 procedure.execute(impl, querySupport.getResource(i));
2540 procedure.execute(impl.newRestart(graph), querySupport.getResource(i));
2542 } catch (Throwable t2) {
2543 Logger.defaultLogError(t2);
2549 public void finished(ReadGraphImpl graph) {
2551 if(first.compareAndSet(true, false)) {
2552 procedure.finished(impl);
2553 // impl.state.barrier.dec(this);
2555 procedure.finished(impl.newRestart(graph));
2557 } catch (Throwable t2) {
2558 Logger.defaultLogError(t2);
2563 public void exception(ReadGraphImpl graph, Throwable t) {
2565 procedure.exception(graph, t);
2566 } catch (Throwable t2) {
2567 Logger.defaultLogError(t2);
2569 // impl.state.barrier.dec(this);
2573 public String toString() {
2574 return "forEachObject with " + procedure;
2579 // if(AsyncBarrierImpl.BOOKKEEPING) impl.state.barrier.inc(ip, "#Objects" + subject + "#" + predicate);
2580 // else impl.state.barrier.inc(null, null);
2582 forEachObject(impl, subject, predicate, listener, ip);
2586 IntProcedure ip = new IntProcedure() {
2589 public void execute(ReadGraphImpl graph, int i) {
2590 procedure.execute(graph, querySupport.getResource(i));
2594 public void finished(ReadGraphImpl graph) {
2595 procedure.finished(graph);
2599 public void exception(ReadGraphImpl graph, Throwable t) {
2600 procedure.exception(graph, t);
2604 public String toString() {
2605 return "forEachObject with " + procedure;
2610 forEachObject(impl, subject, predicate, listener, ip);
2617 final public void forObjectSet(final ReadGraphImpl impl, final Resource subject, final Resource predicate, final AsyncSetListener<Resource> procedure) {
2619 assert(subject != null);
2620 assert(predicate != null);
2621 assert(procedure != null);
2623 forEachObject(impl, subject, predicate, new AsyncMultiListener<Resource>() {
2625 private Set<Resource> current = null;
2626 private Set<Resource> run = new HashSet<Resource>();
2629 public void execute(AsyncReadGraph graph, Resource result) {
2631 boolean found = false;
2633 if(current != null) {
2635 found = current.remove(result);
2639 if(!found) procedure.add(graph, result);
2646 public void finished(AsyncReadGraph graph) {
2648 if(current != null) {
2649 for(Resource r : current) procedure.remove(graph, r);
2654 run = new HashSet<Resource>();
2659 public boolean isDisposed() {
2660 return procedure.isDisposed();
2664 public void exception(AsyncReadGraph graph, Throwable t) {
2665 procedure.exception(graph, t);
2669 public String toString() {
2670 return "forObjectSet " + procedure;
2678 final public void forPredicateSet(final ReadGraphImpl impl, final Resource subject, final AsyncSetListener<Resource> procedure) {
2680 assert(subject != null);
2681 assert(procedure != null);
2683 forEachPredicate(impl, subject, new AsyncMultiListener<Resource>() {
2685 private Set<Resource> current = null;
2686 private Set<Resource> run = new HashSet<Resource>();
2689 public void execute(AsyncReadGraph graph, Resource result) {
2691 boolean found = false;
2693 if(current != null) {
2695 found = current.remove(result);
2699 if(!found) procedure.add(graph, result);
2706 public void finished(AsyncReadGraph graph) {
2708 if(current != null) {
2709 for(Resource r : current) procedure.remove(graph, r);
2714 run = new HashSet<Resource>();
2719 public boolean isDisposed() {
2720 return procedure.isDisposed();
2724 public void exception(AsyncReadGraph graph, Throwable t) {
2725 procedure.exception(graph, t);
2729 public String toString() {
2730 return "forPredicateSet " + procedure;
2738 final public void forPrincipalTypeSet(final ReadGraphImpl impl, final Resource subject, final AsyncSetListener<Resource> procedure) {
2740 assert(subject != null);
2741 assert(procedure != null);
2743 forEachPrincipalType(impl, subject, new AsyncMultiListener<Resource>() {
2745 private Set<Resource> current = null;
2746 private Set<Resource> run = new HashSet<Resource>();
2749 public void execute(AsyncReadGraph graph, Resource result) {
2751 boolean found = false;
2753 if(current != null) {
2755 found = current.remove(result);
2759 if(!found) procedure.add(graph, result);
2766 public void finished(AsyncReadGraph graph) {
2768 if(current != null) {
2769 for(Resource r : current) procedure.remove(graph, r);
2774 run = new HashSet<Resource>();
2779 public boolean isDisposed() {
2780 return procedure.isDisposed();
2784 public void exception(AsyncReadGraph graph, Throwable t) {
2785 procedure.exception(graph, t);
2789 public String toString() {
2790 return "forPrincipalTypeSet " + procedure;
2798 final public void forAssertedObjectSet(final ReadGraphImpl impl, final Resource subject, final Resource predicate, final AsyncSetListener<Resource> procedure) {
2800 assert(subject != null);
2801 assert(predicate != null);
2802 assert(procedure != null);
2804 forEachAssertedObject(impl, subject, predicate, new AsyncMultiListener<Resource>() {
2806 private Set<Resource> current = null;
2807 private Set<Resource> run = new HashSet<Resource>();
2810 public void execute(AsyncReadGraph graph, Resource result) {
2812 boolean found = false;
2814 if(current != null) {
2816 found = current.remove(result);
2820 if(!found) procedure.add(graph, result);
2827 public void finished(AsyncReadGraph graph) {
2829 if(current != null) {
2830 for(Resource r : current) procedure.remove(graph, r);
2835 run = new HashSet<Resource>();
2840 public boolean isDisposed() {
2841 return procedure.isDisposed();
2845 public void exception(AsyncReadGraph graph, Throwable t) {
2846 procedure.exception(graph, t);
2850 public String toString() {
2851 return "forObjectSet " + procedure;
2859 final public void forAssertedStatementSet(final ReadGraphImpl impl, final Resource subject, final Resource predicate, final AsyncSetListener<Statement> procedure) {
2861 assert(subject != null);
2862 assert(predicate != null);
2863 assert(procedure != null);
2865 forEachAssertedStatement(impl, subject, predicate, new AsyncMultiListener<Statement>() {
2867 private Set<Statement> current = null;
2868 private Set<Statement> run = new HashSet<Statement>();
2871 public void execute(AsyncReadGraph graph, Statement result) {
2873 boolean found = false;
2875 if(current != null) {
2877 found = current.remove(result);
2881 if(!found) procedure.add(graph, result);
2888 public void finished(AsyncReadGraph graph) {
2890 if(current != null) {
2891 for(Statement s : current) procedure.remove(graph, s);
2896 run = new HashSet<Statement>();
2901 public boolean isDisposed() {
2902 return procedure.isDisposed();
2906 public void exception(AsyncReadGraph graph, Throwable t) {
2907 procedure.exception(graph, t);
2911 public String toString() {
2912 return "forStatementSet " + procedure;
2920 final public void forEachAssertedObject(final ReadGraphImpl impl, final Resource subject,
2921 final Resource predicate, final AsyncMultiProcedure<Resource> procedure) {
2923 assert(subject != null);
2924 assert(predicate != null);
2925 assert(procedure != null);
2927 final ListenerBase listener = getListenerBase(procedure);
2930 QueryCache.runnerAssertedStatements(impl, querySupport.getId(subject), querySupport.getId(predicate), impl.parent, listener, new TripleIntProcedure() {
2933 public void execute(ReadGraphImpl graph, int s, int p, int o) {
2935 procedure.execute(graph, querySupport.getResource(o));
2936 } catch (Throwable t2) {
2937 Logger.defaultLogError(t2);
2942 public void finished(ReadGraphImpl graph) {
2944 procedure.finished(graph);
2945 } catch (Throwable t2) {
2946 Logger.defaultLogError(t2);
2948 // impl.state.barrier.dec();
2952 public void exception(ReadGraphImpl graph, Throwable t) {
2954 procedure.exception(graph, t);
2955 } catch (Throwable t2) {
2956 Logger.defaultLogError(t2);
2958 // impl.state.barrier.dec();
2962 } catch (DatabaseException e) {
2963 Logger.defaultLogError(e);
2969 final public void forEachPrincipalType(final ReadGraphImpl impl, final Resource subject, final AsyncMultiProcedure<Resource> procedure) {
2971 assert(subject != null);
2972 assert(procedure != null);
2974 final ListenerBase listener = getListenerBase(procedure);
2976 IntProcedure ip = new IntProcedure() {
2979 public void execute(ReadGraphImpl graph, int i) {
2981 procedure.execute(graph, querySupport.getResource(i));
2982 } catch (Throwable t2) {
2983 Logger.defaultLogError(t2);
2988 public void finished(ReadGraphImpl graph) {
2990 procedure.finished(graph);
2991 } catch (Throwable t2) {
2992 Logger.defaultLogError(t2);
2994 // impl.state.barrier.dec(this);
2998 public void exception(ReadGraphImpl graph, Throwable t) {
3000 procedure.exception(graph, t);
3001 } catch (Throwable t2) {
3002 Logger.defaultLogError(t2);
3004 // impl.state.barrier.dec(this);
3009 int sId = querySupport.getId(subject);
3011 // if(AsyncBarrierImpl.BOOKKEEPING) impl.state.barrier.inc(ip, "#PrincipalTypes#" + sId);
3012 // else impl.state.barrier.inc(null, null);
3015 QueryCache.runnerPrincipalTypes(impl, sId, impl.parent, listener, ip);
3016 } catch (DatabaseException e) {
3017 Logger.defaultLogError(e);
3023 final public void forEachPrincipalType(final ReadGraphImpl impl, final Resource subject, final MultiProcedure<Resource> procedure) {
3025 assert(subject != null);
3026 assert(procedure != null);
3028 final ListenerBase listener = getListenerBase(procedure);
3030 // impl.state.barrier.inc();
3033 QueryCache.runnerPrincipalTypes(impl, querySupport.getId(subject), impl.parent, listener, new IntProcedure() {
3036 public void execute(ReadGraphImpl graph, int i) {
3038 procedure.execute(querySupport.getResource(i));
3039 } catch (Throwable t2) {
3040 Logger.defaultLogError(t2);
3045 public void finished(ReadGraphImpl graph) {
3047 procedure.finished();
3048 } catch (Throwable t2) {
3049 Logger.defaultLogError(t2);
3051 // impl.state.barrier.dec();
3055 public void exception(ReadGraphImpl graph, Throwable t) {
3057 procedure.exception(t);
3058 } catch (Throwable t2) {
3059 Logger.defaultLogError(t2);
3061 // impl.state.barrier.dec();
3065 } catch (DatabaseException e) {
3066 Logger.defaultLogError(e);
3070 final public void forTypes(final ReadGraphImpl impl, final Resource subject, final AsyncProcedure<Set<Resource>> procedure) {
3072 assert(subject != null);
3073 assert(procedure != null);
3075 final ListenerBase listener = getListenerBase(procedure);
3076 assert(listener == null);
3078 InternalProcedure<IntSet> ip = new InternalProcedure<IntSet>() {
3081 public void execute(final ReadGraphImpl graph, IntSet set) {
3082 procedure.execute(graph, set);
3086 public void exception(ReadGraphImpl graph, Throwable t) {
3087 procedure.exception(graph, t);
3092 int sId = querySupport.getId(subject);
3095 QueryCache.runnerTypes(impl, sId, impl.parent, listener, ip);
3096 } catch (DatabaseException e) {
3097 Logger.defaultLogError(e);
3103 final public IntSet getTypes(final ReadGraphImpl impl, final Resource subject) throws Throwable {
3105 assert(subject != null);
3107 return QueryCacheBase.resultTypes(impl, querySupport.getId(subject), impl.parent, null);
3112 final public RelationInfo getRelationInfo(final ReadGraphImpl impl, final Resource subject) throws DatabaseException {
3114 assert(subject != null);
3116 return QueryCache.resultRelationInfoQuery(impl, querySupport.getId(subject), impl.parent, null);
3121 final public void forSupertypes(final ReadGraphImpl impl, final Resource subject, final AsyncProcedure<Set<Resource>> procedure) {
3123 assert(subject != null);
3124 assert(procedure != null);
3126 final ListenerBase listener = getListenerBase(procedure);
3129 QueryCache.runnerSuperTypes(impl, querySupport.getId(subject), impl.parent, listener, new InternalProcedure<IntSet>() {
3131 AtomicBoolean first = new AtomicBoolean(true);
3134 public void execute(final ReadGraphImpl graph, IntSet set) {
3135 // final HashSet<Resource> result = new HashSet<Resource>();
3136 // set.forEach(new TIntProcedure() {
3139 // public boolean execute(int type) {
3140 // result.add(querySupport.getResource(type));
3146 if(first.compareAndSet(true, false)) {
3147 procedure.execute(graph, set);
3148 // impl.state.barrier.dec();
3150 procedure.execute(impl.newRestart(graph), set);
3152 } catch (Throwable t2) {
3153 Logger.defaultLogError(t2);
3158 public void exception(ReadGraphImpl graph, Throwable t) {
3160 if(first.compareAndSet(true, false)) {
3161 procedure.exception(graph, t);
3162 // impl.state.barrier.dec();
3164 procedure.exception(impl.newRestart(graph), t);
3166 } catch (Throwable t2) {
3167 Logger.defaultLogError(t2);
3172 } catch (DatabaseException e) {
3173 Logger.defaultLogError(e);
3179 final public void forDirectSuperrelations(final ReadGraphImpl impl, final Resource subject, final AsyncMultiProcedure<Resource> procedure) {
3181 assert(subject != null);
3182 assert(procedure != null);
3184 final ListenerBase listener = getListenerBase(procedure);
3186 IntProcedure ip = new IntProcedureAdapter() {
3189 public void execute(final ReadGraphImpl graph, int superRelation) {
3191 procedure.execute(graph, querySupport.getResource(superRelation));
3192 } catch (Throwable t2) {
3193 Logger.defaultLogError(t2);
3198 public void finished(final ReadGraphImpl graph) {
3200 procedure.finished(graph);
3201 } catch (Throwable t2) {
3202 Logger.defaultLogError(t2);
3204 // impl.state.barrier.dec(this);
3209 public void exception(ReadGraphImpl graph, Throwable t) {
3211 procedure.exception(graph, t);
3212 } catch (Throwable t2) {
3213 Logger.defaultLogError(t2);
3215 // impl.state.barrier.dec(this);
3220 int sId = querySupport.getId(subject);
3222 // if(AsyncBarrierImpl.BOOKKEEPING) impl.state.barrier.inc(ip, "#DirectSuperRelations#" + sId);
3223 // else impl.state.barrier.inc(null, null);
3226 QueryCache.runnerDirectSuperRelations(impl, sId, impl.parent, listener, ip);
3227 } catch (DatabaseException e) {
3228 Logger.defaultLogError(e);
3231 // DirectSuperRelations.queryEach(impl, sId, this, impl.parent, listener, ip);
3236 final public void forPossibleSuperrelation(final ReadGraphImpl impl, final Resource subject, final AsyncProcedure<Resource> procedure) {
3238 assert(subject != null);
3239 assert(procedure != null);
3241 final ListenerBase listener = getListenerBase(procedure);
3243 // impl.state.barrier.inc();
3245 PossibleSuperRelation.queryEach(impl, querySupport.getId(subject), this, impl.parent, listener, procedure);
3250 final public void forSuperrelations(final ReadGraphImpl impl, final Resource subject, final AsyncProcedure<Set<Resource>> procedure) {
3252 assert(subject != null);
3253 assert(procedure != null);
3255 final ListenerBase listener = getListenerBase(procedure);
3257 InternalProcedure<IntSet> ip = new InternalProcedure<IntSet>() {
3260 public void execute(final ReadGraphImpl graph, IntSet set) {
3261 // final HashSet<Resource> result = new HashSet<Resource>();
3262 // set.forEach(new TIntProcedure() {
3265 // public boolean execute(int type) {
3266 // result.add(querySupport.getResource(type));
3272 procedure.execute(graph, set);
3273 } catch (Throwable t2) {
3274 Logger.defaultLogError(t2);
3276 // impl.state.barrier.dec(this);
3280 public void exception(ReadGraphImpl graph, Throwable t) {
3282 procedure.exception(graph, t);
3283 } catch (Throwable t2) {
3284 Logger.defaultLogError(t2);
3286 // impl.state.barrier.dec(this);
3291 int sId = querySupport.getId(subject);
3293 // if(AsyncBarrierImpl.BOOKKEEPING) impl.state.barrier.inc(ip, "#SuperRelations#" + sId);
3294 // else impl.state.barrier.inc(null, null);
3297 QueryCache.runnerSuperRelations(impl, sId, impl.parent, listener, ip);
3298 } catch (DatabaseException e) {
3299 Logger.defaultLogError(e);
3304 final public byte[] getValue(final ReadGraphImpl impl, final Resource subject) throws DatabaseException {
3305 return getValue(impl, querySupport.getId(subject));
3308 final public byte[] getValue(final ReadGraphImpl impl, final int subject) throws DatabaseException {
3309 return QueryCache.resultValueQuery(impl, subject, impl.parent, null);
3313 final public void forValue(final ReadGraphImpl impl, final Resource subject, final AsyncProcedure<byte[]> procedure) {
3315 assert(subject != null);
3316 assert(procedure != null);
3318 int sId = querySupport.getId(subject);
3320 // if(procedure != null) {
3322 final ListenerBase listener = getListenerBase(procedure);
3324 InternalProcedure<byte[]> ip = new InternalProcedure<byte[]>() {
3326 AtomicBoolean first = new AtomicBoolean(true);
3329 public void execute(ReadGraphImpl graph, byte[] result) {
3331 if(first.compareAndSet(true, false)) {
3332 procedure.execute(graph, result);
3333 // impl.state.barrier.dec(this);
3335 procedure.execute(impl.newRestart(graph), result);
3337 } catch (Throwable t2) {
3338 Logger.defaultLogError(t2);
3343 public void exception(ReadGraphImpl graph, Throwable t) {
3345 if(first.compareAndSet(true, false)) {
3346 procedure.exception(graph, t);
3347 // impl.state.barrier.dec(this);
3349 procedure.exception(impl.newRestart(graph), t);
3351 } catch (Throwable t2) {
3352 Logger.defaultLogError(t2);
3358 // if(AsyncBarrierImpl.BOOKKEEPING) impl.state.barrier.inc(ip, "#Value" + sId);
3359 // else impl.state.barrier.inc(null, null);
3362 QueryCache.runnerValueQuery(impl, sId, impl.parent, listener, ip);
3363 } catch (DatabaseException e) {
3364 throw new IllegalStateException("Internal error");
3369 // return QueryCacheBase.runnerValueQuery(impl, sId, impl.parent, null, null);
3373 // throw new IllegalStateException("Internal error");
3378 final public void forPossibleValue(final ReadGraphImpl impl, final Resource subject, final AsyncProcedure<byte[]> procedure) {
3380 assert(subject != null);
3381 assert(procedure != null);
3383 final ListenerBase listener = getListenerBase(procedure);
3385 if(impl.parent != null || listener != null) {
3387 InternalProcedure<byte[]> ip = new InternalProcedure<byte[]>() {
3389 AtomicBoolean first = new AtomicBoolean(true);
3392 public void execute(ReadGraphImpl graph, byte[] result) {
3394 if(first.compareAndSet(true, false)) {
3395 procedure.execute(graph, result);
3396 // impl.state.barrier.dec(this);
3398 procedure.execute(impl.newRestart(graph), result);
3400 } catch (Throwable t2) {
3401 Logger.defaultLogError(t2);
3406 public void exception(ReadGraphImpl graph, Throwable t) {
3408 if(first.compareAndSet(true, false)) {
3409 procedure.exception(graph, t);
3410 // impl.state.barrier.dec(this);
3412 procedure.exception(impl.newRestart(graph), t);
3414 } catch (Throwable t2) {
3415 Logger.defaultLogError(t2);
3421 int sId = querySupport.getId(subject);
3423 // if(AsyncBarrierImpl.BOOKKEEPING) impl.state.barrier.inc(ip, "#Value" + sId);
3424 // else impl.state.barrier.inc(null, null);
3427 QueryCache.runnerValueQuery(impl, sId, impl.parent, listener, ip);
3428 } catch (DatabaseException e) {
3429 Logger.defaultLogError(e);
3434 InternalProcedure<byte[]> ip = new InternalProcedure<byte[]>() {
3437 public void execute(ReadGraphImpl graph, byte[] result) {
3439 procedure.execute(graph, result);
3444 public void exception(ReadGraphImpl graph, Throwable t) {
3446 procedure.exception(graph, t);
3452 int sId = querySupport.getId(subject);
3455 QueryCache.runnerValueQuery(impl, sId, impl.parent, listener, ip);
3456 } catch (DatabaseException e) {
3457 Logger.defaultLogError(e);
3465 final public void forInverse(final ReadGraphImpl impl, final Resource relation, final AsyncProcedure<Resource> procedure) {
3467 assert(relation != null);
3468 assert(procedure != null);
3470 final ListenerBase listener = getListenerBase(procedure);
3472 IntProcedure ip = new IntProcedure() {
3474 private int result = 0;
3476 final AtomicBoolean found = new AtomicBoolean(false);
3477 final AtomicBoolean done = new AtomicBoolean(false);
3480 public void finished(ReadGraphImpl graph) {
3482 // Shall fire exactly once!
3483 if(done.compareAndSet(false, true)) {
3486 procedure.exception(graph, new NoInverseException(""));
3487 // impl.state.barrier.dec(this);
3489 procedure.execute(graph, querySupport.getResource(result));
3490 // impl.state.barrier.dec(this);
3492 } catch (Throwable t) {
3493 Logger.defaultLogError(t);
3500 public void execute(ReadGraphImpl graph, int i) {
3502 if(found.compareAndSet(false, true)) {
3505 // Shall fire exactly once!
3506 if(done.compareAndSet(false, true)) {
3508 procedure.exception(graph, new ManyObjectsForFunctionalRelationException("Multiple items e.g. " + this.result + " and " + result));
3509 // impl.state.barrier.dec(this);
3510 } catch (Throwable t) {
3511 Logger.defaultLogError(t);
3519 public void exception(ReadGraphImpl graph, Throwable t) {
3520 // Shall fire exactly once!
3521 if(done.compareAndSet(false, true)) {
3523 procedure.exception(graph, t);
3524 // impl.state.barrier.dec(this);
3525 } catch (Throwable t2) {
3526 Logger.defaultLogError(t2);
3533 int sId = querySupport.getId(relation);
3535 // if(AsyncBarrierImpl.BOOKKEEPING) impl.state.barrier.inc(ip, "#DirectObjects#" + sId);
3536 // else impl.state.barrier.inc(null, null);
3539 QueryCache.runnerObjects(impl, sId, getInverseOf(), impl.parent, listener, ip);
3540 } catch (DatabaseException e) {
3541 Logger.defaultLogError(e);
3547 final public void forResource(final ReadGraphImpl impl, final String id, final AsyncProcedure<Resource> procedure) {
3550 assert(procedure != null);
3552 InternalProcedure<Integer> ip = new InternalProcedure<Integer>() {
3555 public void execute(ReadGraphImpl graph, Integer result) {
3557 procedure.execute(graph, querySupport.getResource(result));
3558 } catch (Throwable t2) {
3559 Logger.defaultLogError(t2);
3561 // impl.state.barrier.dec(this);
3565 public void exception(ReadGraphImpl graph, Throwable t) {
3568 procedure.exception(graph, t);
3569 } catch (Throwable t2) {
3570 Logger.defaultLogError(t2);
3572 // impl.state.barrier.dec(this);
3577 // if(AsyncBarrierImpl.BOOKKEEPING) impl.state.barrier.inc(ip, "Resource");
3578 // else impl.state.barrier.inc(null, null);
3580 forResource(impl, id, impl.parent, ip);
3585 final public void forBuiltin(final ReadGraphImpl impl, final String id, final AsyncProcedure<Resource> procedure) {
3588 assert(procedure != null);
3590 // impl.state.barrier.inc();
3593 forBuiltin(impl, id, impl.parent, new InternalProcedure<Integer>() {
3596 public void execute(ReadGraphImpl graph, Integer result) {
3598 procedure.execute(graph, querySupport.getResource(result));
3599 } catch (Throwable t2) {
3600 Logger.defaultLogError(t2);
3602 // impl.state.barrier.dec();
3606 public void exception(ReadGraphImpl graph, Throwable t) {
3608 procedure.exception(graph, t);
3609 } catch (Throwable t2) {
3610 Logger.defaultLogError(t2);
3612 // impl.state.barrier.dec();
3616 } catch (DatabaseException e) {
3617 Logger.defaultLogError(e);
3623 final public void forHasStatement(final ReadGraphImpl impl, final Resource subject, final AsyncProcedure<Boolean> procedure) {
3625 assert(subject != null);
3626 assert(procedure != null);
3628 final ListenerBase listener = getListenerBase(procedure);
3631 IntSet result = QueryCache.resultDirectPredicates(impl, querySupport.getId(subject), impl.parent, listener);
3632 procedure.execute(impl, !result.isEmpty());
3633 } catch (DatabaseException e) {
3634 procedure.exception(impl, e);
3640 final public void forHasStatement(final ReadGraphImpl impl, final Resource subject, final Resource predicate, final AsyncProcedure<Boolean> procedure) {
3642 assert(subject != null);
3643 assert(predicate != null);
3644 assert(procedure != null);
3646 AsyncMultiProcedure<Resource> ip = new AsyncMultiProcedureAdapter<Resource>() {
3648 boolean found = false;
3651 synchronized public void execute(AsyncReadGraph graph, Resource resource) {
3656 synchronized public void finished(AsyncReadGraph graph) {
3658 procedure.execute(graph, found);
3659 } catch (Throwable t2) {
3660 Logger.defaultLogError(t2);
3662 // impl.state.barrier.dec(this);
3666 public void exception(AsyncReadGraph graph, Throwable t) {
3668 procedure.exception(graph, t);
3669 } catch (Throwable t2) {
3670 Logger.defaultLogError(t2);
3672 // impl.state.barrier.dec(this);
3677 // if(AsyncBarrierImpl.BOOKKEEPING) impl.state.barrier.inc(ip, "#ForEachObject#" + subject + "#" + predicate);
3678 // else impl.state.barrier.inc(null, null);
3680 forEachObject(impl, subject, predicate, ip);
3685 final public void forHasStatement(final ReadGraphImpl impl, final Resource subject, final Resource predicate, final Resource object, final AsyncProcedure<Boolean> procedure) {
3687 assert(subject != null);
3688 assert(predicate != null);
3689 assert(procedure != null);
3691 // impl.state.barrier.inc();
3693 forEachObject(impl, subject, predicate, new AsyncMultiProcedureAdapter<Resource>() {
3695 boolean found = false;
3698 synchronized public void execute(AsyncReadGraph graph, Resource resource) {
3699 if(resource.equals(object)) found = true;
3703 synchronized public void finished(AsyncReadGraph graph) {
3705 procedure.execute(graph, found);
3706 } catch (Throwable t2) {
3707 Logger.defaultLogError(t2);
3709 // impl.state.barrier.dec();
3713 public void exception(AsyncReadGraph graph, Throwable t) {
3715 procedure.exception(graph, t);
3716 } catch (Throwable t2) {
3717 Logger.defaultLogError(t2);
3719 // impl.state.barrier.dec();
3727 final public void forHasValue(final ReadGraphImpl impl, final Resource subject, final AsyncProcedure<Boolean> procedure) {
3729 assert(subject != null);
3730 assert(procedure != null);
3732 final ListenerBase listener = getListenerBase(procedure);
3734 // impl.state.barrier.inc();
3737 QueryCache.runnerValueQuery(impl, querySupport.getId(subject), impl.parent, listener, new InternalProcedure<byte[]>() {
3740 public void execute(ReadGraphImpl graph, byte[] object) {
3741 boolean result = object != null;
3743 procedure.execute(graph, result);
3744 } catch (Throwable t2) {
3745 Logger.defaultLogError(t2);
3747 // impl.state.barrier.dec();
3751 public void exception(ReadGraphImpl graph, Throwable t) {
3753 procedure.exception(graph, t);
3754 } catch (Throwable t2) {
3755 Logger.defaultLogError(t2);
3757 // impl.state.barrier.dec();
3761 } catch (DatabaseException e) {
3762 Logger.defaultLogError(e);
3768 final public void forOrderedSet(final ReadGraphImpl impl, final Resource subject, final AsyncMultiProcedure<Resource> procedure) {
3770 assert(subject != null);
3771 assert(procedure != null);
3773 final ListenerBase listener = getListenerBase(procedure);
3777 QueryCache.runnerOrderedSet(impl, querySupport.getId(subject), impl.parent, listener, new IntProcedure() {
3780 public void exception(ReadGraphImpl graph, Throwable t) {
3782 procedure.exception(graph, t);
3783 } catch (Throwable t2) {
3784 Logger.defaultLogError(t2);
3786 // impl.state.barrier.dec();
3790 public void execute(ReadGraphImpl graph, int i) {
3792 procedure.execute(graph, querySupport.getResource(i));
3793 } catch (Throwable t2) {
3794 Logger.defaultLogError(t2);
3799 public void finished(ReadGraphImpl graph) {
3801 procedure.finished(graph);
3802 } catch (Throwable t2) {
3803 Logger.defaultLogError(t2);
3805 // impl.state.barrier.dec();
3809 } catch (DatabaseException e) {
3810 Logger.defaultLogError(e);
3816 // final public <T> void query(final ReadGraphImpl impl, final AsyncRead<T> request, final CacheEntry parent, final AsyncProcedure<T> procedure, ListenerBase listener) throws DatabaseException {
3818 // assert(request != null);
3819 // assert(procedure != null);
3821 // QueryCache.runnerAsyncReadEntry(impl, request, parent, listener, procedure);
3826 // final public <T> T tryQuery(final ReadGraphImpl graph, final Read<T> request) throws DatabaseException {
3828 // assert(graph != null);
3829 // assert(request != null);
3831 // final ReadEntry entry = (ReadEntry)cache.getCached(request);
3832 // if(entry != null && entry.isReady()) {
3833 // return (T)entry.get(graph, this, null);
3835 // return request.perform(graph);
3840 // final public <T> T tryQuery(final ReadGraphImpl graph, final ExternalRead<T> request) throws DatabaseException {
3842 // assert(graph != null);
3843 // assert(request != null);
3845 // final ExternalReadEntry<T> entry = cache.externalReadMap.get(request);
3846 // if(entry != null && entry.isReady()) {
3847 // if(entry.isExcepted()) {
3848 // Throwable t = (Throwable)entry.getResult();
3849 // if(t instanceof DatabaseException) throw (DatabaseException)t;
3850 // else throw new DatabaseException(t);
3852 // return (T)entry.getResult();
3856 // final DataContainer<T> result = new DataContainer<T>();
3857 // final DataContainer<Throwable> exception = new DataContainer<Throwable>();
3859 // request.register(graph, new Listener<T>() {
3862 // public void exception(Throwable t) {
3863 // exception.set(t);
3867 // public void execute(T t) {
3872 // public boolean isDisposed() {
3878 // Throwable t = exception.get();
3880 // if(t instanceof DatabaseException) throw (DatabaseException)t;
3881 // else throw new DatabaseException(t);
3884 // return result.get();
3891 // final public <T> void tryQuery(final ReadGraphImpl graph, final AsyncRead<T> request, AsyncProcedure<T> procedure) {
3893 // assert(graph != null);
3894 // assert(request != null);
3896 // final AsyncReadEntry entry = cache.asyncReadMap.get(request);
3897 // if(entry != null && entry.isReady()) {
3898 // if(entry.isExcepted()) {
3899 // procedure.exception(graph, (Throwable)entry.getResult());
3901 // procedure.execute(graph, (T)entry.getResult());
3904 // request.perform(graph, procedure);
3910 final public <T> void query(final ReadGraphImpl impl, final MultiRead<T> request, final CacheEntry parent, final SyncMultiProcedure<T> procedure, ListenerBase listener) {
3912 assert(request != null);
3913 assert(procedure != null);
3917 queryMultiRead(impl, request, parent, listener, procedure);
3919 } catch (DatabaseException e) {
3921 throw new IllegalStateException(e);
3928 final public <T> void query(final ReadGraphImpl impl, final AsyncMultiRead<T> request, final CacheEntry parent, final AsyncMultiProcedure<T> procedure, ListenerBase listener) {
3930 assert(request != null);
3931 assert(procedure != null);
3933 // impl.state.barrier.inc();
3935 runAsyncMultiRead(impl, request, parent, listener, new AsyncMultiProcedure<T>() {
3937 public void execute(AsyncReadGraph graph, T result) {
3940 procedure.execute(graph, result);
3941 } catch (Throwable t2) {
3942 Logger.defaultLogError(t2);
3947 public void finished(AsyncReadGraph graph) {
3950 procedure.finished(graph);
3951 } catch (Throwable t2) {
3952 Logger.defaultLogError(t2);
3955 // impl.state.barrier.dec();
3960 public String toString() {
3961 return procedure.toString();
3965 public void exception(AsyncReadGraph graph, Throwable t) {
3968 procedure.exception(graph, t);
3969 } catch (Throwable t2) {
3970 Logger.defaultLogError(t2);
3973 // impl.state.barrier.dec();
3982 // final public <T> void query(final ReadGraphImpl impl, final ExternalRead<T> request, final CacheEntry parent, final Procedure<T> procedure, ListenerBase listener) throws DatabaseException {
3984 // assert(request != null);
3985 // assert(procedure != null);
3989 // queryPrimitiveRead(impl, request, parent, listener, new AsyncProcedure<T>() {
3992 // public String toString() {
3993 // return procedure.toString();
3997 // public void execute(AsyncReadGraph graph, T result) {
3999 // procedure.execute(result);
4000 // } catch (Throwable t2) {
4001 // Logger.defaultLogError(t2);
4006 // public void exception(AsyncReadGraph graph, Throwable throwable) {
4008 // procedure.exception(throwable);
4009 // } catch (Throwable t2) {
4010 // Logger.defaultLogError(t2);
4016 // } catch (DatabaseException e) {
4018 // throw new IllegalStateException(e);
4025 public VirtualGraph getProvider(Resource subject, Resource predicate, Resource object) {
4027 return querySupport.getProvider(querySupport.getId(subject), querySupport.getId(predicate), querySupport.getId(object));
4032 public VirtualGraph getProvider(Resource subject, Resource predicate) {
4034 return querySupport.getProvider(querySupport.getId(subject), querySupport.getId(predicate));
4039 public VirtualGraph getValueProvider(Resource subject) {
4041 return querySupport.getValueProvider(querySupport.getId(subject));
4045 public boolean resumeTasks(ReadGraphImpl graph) {
4047 return querySupport.resume(graph);
4051 public boolean isImmutable(int resourceId) {
4052 return querySupport.isImmutable(resourceId);
4055 public boolean isImmutable(Resource resource) {
4056 ResourceImpl impl = (ResourceImpl)resource;
4057 return isImmutable(impl.id);
4062 public Layer0 getL0(ReadGraph graph) {
4064 L0 = Layer0.getInstance(graph);
4069 public Layer0 getL0() {
4073 public static ThreadLocal<Integer> thread = new ThreadLocal<Integer>() {
4074 protected Integer initialValue() {