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;
145 public LinkedList<SessionTask> freeScheduling = new LinkedList<SessionTask>();
147 public LinkedList<SessionTask> topLevelTasks = new LinkedList<SessionTask>();
151 INIT, RUN, SLEEP, DISPOSED
155 public ThreadState[] threadStates;
157 final Object querySupportLock;
159 public Long modificationCounter = 0L;
161 public void close() {
164 public SessionTask getSubTask(ReadGraphImpl parent) {
165 synchronized(querySupportLock) {
167 while(index < freeScheduling.size()) {
168 SessionTask task = freeScheduling.get(index);
169 if(task.isSubtask(parent) && task.maybeReady()) {
170 return freeScheduling.remove(index);
179 * We are running errands while waiting for requests to complete.
180 * We can only run work that is part of the current root request to avoid any deadlocks
182 public boolean performPending(ReadGraphImpl under) {
183 SessionTask task = getSubTask(under);
185 task.run(thread.get());
191 final public void scheduleNow(SessionTask request) {
192 SessionTask toExecute = scheduleOrReturnForExecution(request);
193 if(toExecute != null)
194 toExecute.run(thread.get());
197 final public SessionTask scheduleOrReturnForExecution(SessionTask request) {
199 assert(request != null);
201 synchronized(querySupportLock) {
203 LinkedList<SessionTask> queue = request.rootGraph != null ? freeScheduling : topLevelTasks;
205 if(BarrierTracing.BOOKKEEPING) {
206 Exception current = new Exception();
207 Exception previous = BarrierTracing.tasks.put(request, current);
208 if(previous != null) {
209 previous.printStackTrace();
210 current.printStackTrace();
214 queue.addFirst(request);
225 final public int THREAD_MASK;
227 final public static ThreadGroup QueryThreadGroup = new ThreadGroup("Query Thread Group");
229 public static abstract class SessionTask {
231 final protected ReadGraphImpl rootGraph;
232 private int counter = 0;
233 protected int position = 1;
234 private Exception trace;
236 public SessionTask() {
240 public SessionTask(ReadGraphImpl rootGraph) {
241 this.rootGraph = rootGraph;
244 public boolean isSubtask(ReadGraphImpl graph) {
245 return graph.isParent(rootGraph);
248 public abstract void run0(int thread);
250 public final void run(int thread) {
252 if(BarrierTracing.BOOKKEEPING) {
253 trace.printStackTrace();
254 new Exception().printStackTrace();
256 throw new IllegalStateException("Multiple invocations of SessionTask!");
258 if(BarrierTracing.BOOKKEEPING) {
259 trace = new Exception();
264 public boolean maybeReady() {
269 public String toString() {
270 if(rootGraph == null)
271 return "SessionTask[no graph]";
273 return "SessionTask[" + rootGraph.parent + "]";
278 public static abstract class SessionRead extends SessionTask {
280 final public Semaphore notify;
281 final public DataContainer<Throwable> throwable;
283 public SessionRead(DataContainer<Throwable> throwable, Semaphore notify) {
285 this.throwable = throwable;
286 this.notify = notify;
291 public boolean resume(ReadGraphImpl graph) {
292 return executors[0].runSynchronized();
295 public QueryProcessor(final int threads, QuerySupport core, Set<Thread> threadSet)
296 throws DatabaseException {
299 THREAD_MASK = threads - 1;
302 cache = new QueryCache(core, threads);
303 session = querySupport.getSession();
304 resourceSupport = querySupport.getSupport();
305 querySupportLock = core.getLock();
307 executors = new QueryThread[THREADS];
308 threadStates = new ThreadState[THREADS];
310 for (int i = 0; i < THREADS; i++) {
311 threadStates[i] = ThreadState.INIT;
314 for (int i = 0; i < THREADS; i++) {
318 executors[i] = new QueryThread(session, this, index, "Query Thread " + index);
320 threadSet.add(executors[i]);
325 for (int i = 0; i < THREADS; i++) {
326 executors[i].start();
329 // Make sure that query threads are up and running
330 while(sleepers.get() != THREADS) {
333 } catch (InterruptedException e) {
338 rootLibrary = core.getBuiltin("http:/");
339 boolean builtinsInstalled = rootLibrary != 0;
341 if (builtinsInstalled) {
342 functionalRelation = core.getBuiltin(Layer0.URIs.FunctionalRelation);
343 assert (functionalRelation != 0);
345 functionalRelation = 0;
347 if (builtinsInstalled) {
348 instanceOf = core.getBuiltin(Layer0.URIs.InstanceOf);
349 assert (instanceOf != 0);
353 if (builtinsInstalled) {
354 inverseOf = core.getBuiltin(Layer0.URIs.InverseOf);
355 assert (inverseOf != 0);
360 if (builtinsInstalled) {
361 inherits = core.getBuiltin(Layer0.URIs.Inherits);
362 assert (inherits != 0);
366 if (builtinsInstalled) {
367 asserts = core.getBuiltin(Layer0.URIs.Asserts);
368 assert (asserts != 0);
372 if (builtinsInstalled) {
373 hasPredicate = core.getBuiltin(Layer0.URIs.HasPredicate);
374 assert (hasPredicate != 0);
378 if (builtinsInstalled) {
379 hasPredicateInverse = core.getBuiltin(Layer0.URIs.HasPredicateInverse);
380 assert (hasPredicateInverse != 0);
382 hasPredicateInverse = 0;
384 if (builtinsInstalled) {
385 hasObject = core.getBuiltin(Layer0.URIs.HasObject);
386 assert (hasObject != 0);
390 if (builtinsInstalled) {
391 subrelationOf = core.getBuiltin(Layer0.URIs.SubrelationOf);
392 assert (subrelationOf != 0);
396 if (builtinsInstalled) {
397 superrelationOf = core.getBuiltin(Layer0.URIs.SuperrelationOf);
398 assert (superrelationOf != 0);
402 if (builtinsInstalled) {
403 library = core.getBuiltin(Layer0.URIs.Library);
404 assert (library != 0);
408 if (builtinsInstalled) {
409 consistsOf = core.getBuiltin(Layer0.URIs.ConsistsOf);
410 assert (consistsOf != 0);
414 if (builtinsInstalled) {
415 hasName = core.getBuiltin(Layer0.URIs.HasName);
416 assert (hasName != 0);
422 final public void releaseWrite(ReadGraphImpl graph) {
423 propagateChangesInQueryCache(graph);
424 modificationCounter++;
427 final public int getId(final Resource r) {
428 return querySupport.getId(r);
431 public QuerySupport getCore() {
435 public int getFunctionalRelation() {
436 return functionalRelation;
439 public int getInherits() {
443 public int getInstanceOf() {
447 public int getInverseOf() {
451 public int getSubrelationOf() {
452 return subrelationOf;
455 public int getSuperrelationOf() {
456 return superrelationOf;
459 public int getAsserts() {
463 public int getHasPredicate() {
467 public int getHasPredicateInverse() {
468 return hasPredicateInverse;
471 public int getHasObject() {
475 public int getRootLibrary() {
479 public Resource getRootLibraryResource() {
480 if (rootLibraryResource == null) {
481 // Synchronization is not needed here, it doesn't matter if multiple
482 // threads simultaneously set rootLibraryResource once.
483 int root = getRootLibrary();
485 throw new UnsupportedOperationException("database is not initialized, cannot get root library resource");
486 this.rootLibraryResource = new ResourceImpl(querySupport.getSupport(), root);
488 return rootLibraryResource;
491 public int getLibrary() {
495 public int getConsistsOf() {
499 public int getHasName() {
503 public void forResource(ReadGraphImpl graph, final String id, CacheEntry parent, final InternalProcedure<Integer> procedure) {
507 QueryCache.runnerURIToResource(graph, id, parent, null, new InternalProcedure<Integer>() {
510 public void execute(ReadGraphImpl graph, Integer result) throws DatabaseException {
512 if (result != null && result != 0) {
513 procedure.execute(graph, result);
517 // Fall back to using the fixed builtins.
518 // result = querySupport.getBuiltin(id);
519 // if (result != 0) {
520 // procedure.execute(graph, result);
525 // result = querySupport.getRandomAccessReference(id);
526 // } catch (ResourceNotFoundException e) {
527 // procedure.exception(graph, e);
532 procedure.execute(graph, result);
534 procedure.exception(graph, new ResourceNotFoundException(id));
540 public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
541 procedure.exception(graph, t);
545 } catch (DatabaseException e) {
549 procedure.exception(graph, e);
551 } catch (DatabaseException e1) {
553 Logger.defaultLogError(e1);
561 public void forBuiltin(ReadGraphImpl graph, final String id, CacheEntry parent, final InternalProcedure<Integer> procedure) throws DatabaseException {
563 Integer result = querySupport.getBuiltin(id);
565 procedure.execute(graph, result);
567 procedure.exception(graph, new ResourceNotFoundException(id));
572 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) {
575 QueryCache.runnerMultiReadEntry(graph, query, parent, listener, procedure);
576 } catch (DatabaseException e) {
577 throw new IllegalStateException(e);
582 public final <T> void runAsyncMultiRead(final ReadGraphImpl graph, final AsyncMultiRead<T> query, final CacheEntry parent, final ListenerBase listener, final AsyncMultiProcedure<T> procedure) {
586 QueryCache.runnerAsyncMultiReadEntry(graph, query, parent, listener, procedure);
587 } catch (DatabaseException e) {
588 throw new IllegalStateException(e);
593 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 {
594 QueryCache.runnerExternalReadEntry(graph, query, parent, listener, procedure);
598 // public <T> T query(final ReadGraphImpl graph, final Read<T> query, final CacheEntry parent, final AsyncProcedure<T> procedure, final ListenerBase listener) throws DatabaseException {
600 // return QueryCache.resultReadEntry(graph, query, parent, listener, procedure);
604 public <T> void queryMultiRead(final ReadGraphImpl graph, final MultiRead<T> query, final CacheEntry parent, final ListenerBase listener, final SyncMultiProcedure<T> procedure) throws DatabaseException {
606 QueryCache.runnerMultiReadEntry(graph, query, parent, listener, procedure);
610 public <T> void queryPrimitiveRead(final ReadGraphImpl graph, final ExternalRead<T> query, final CacheEntry parent, final ListenerBase listener, final AsyncProcedure<T> procedure) throws DatabaseException {
612 QueryCache.runnerExternalReadEntry(graph, query, parent, listener, procedure);
616 boolean isBound(ExternalReadEntry<?> entry) {
617 if(entry.hasParents()) return true;
618 else if(listening.hasListener(entry)) return true;
622 static class Dummy implements InternalProcedure<Object>, IntProcedure {
625 public void execute(ReadGraphImpl graph, int i) {
629 public void finished(ReadGraphImpl graph) {
633 public void execute(ReadGraphImpl graph, Object result) {
637 public void exception(ReadGraphImpl graph, Throwable throwable) {
642 private static final Dummy dummy = new Dummy();
645 public <Procedure> Object performForEach2(ReadGraphImpl graph, UnaryQuery<Procedure> query, CacheEntry parent, ListenerBase listener, Procedure procedure) throws Throwable {
647 if (DebugPolicy.PERFORM)
648 System.out.println("PE[ " + (query.hashCode() & THREAD_MASK) + "] " + query);
651 assert (!collecting);
653 assert(query.assertNotDiscarded());
655 registerDependencies(graph, query, parent, listener, procedure, false);
657 // FRESH, REFUTED, EXCEPTED go here
658 if (!query.isReady()) {
663 query.computeForEach(graph, this, (Procedure)dummy, true);
664 return query.get(graph, this, null);
670 return query.get(graph, this, procedure);
678 interface QueryCollectorSupport {
679 public CacheCollectionResult allCaches();
680 public Collection<CacheEntry> getRootList();
681 public int getCurrentSize();
682 public int calculateCurrentSize();
683 public CacheEntryBase iterate(int level);
684 public void remove();
685 public void setLevel(CacheEntryBase entry, int level);
686 public boolean start(boolean flush);
689 interface QueryCollector {
691 public void collect(int youngTarget, int allowedTimeInMs);
695 class QueryCollectorSupportImpl implements QueryCollectorSupport {
697 private static final boolean DEBUG = false;
698 private static final double ITERATION_RATIO = 0.2;
700 private CacheCollectionResult iteration = new CacheCollectionResult();
701 private boolean fresh = true;
702 private boolean needDataInStart = true;
704 QueryCollectorSupportImpl() {
708 public CacheCollectionResult allCaches() {
709 CacheCollectionResult result = new CacheCollectionResult();
710 QueryProcessor.this.allCaches(result);
715 public boolean start(boolean flush) {
716 // We need new data from query maps
718 if(needDataInStart || flush) {
719 // Last run ended after processing all queries => refresh data
720 restart(flush ? 0.0 : ITERATION_RATIO);
722 // continue with previous big data
724 // Notify caller about iteration situation
725 return iteration.isAtStart();
728 private void restart(double targetRatio) {
730 needDataInStart = true;
732 long start = System.nanoTime();
735 // We need new data from query maps
737 int iterationSize = iteration.size()+1;
738 int diff = calculateCurrentSize()-iterationSize;
740 double ratio = (double)diff / (double)iterationSize;
741 boolean dirty = Math.abs(ratio) >= targetRatio;
744 iteration = allCaches();
746 System.err.print("iterate: allCaches in " + 1e-9*(System.nanoTime()-start) + "s. (" + iteration.size() + ") ");
747 for(int i=0;i<CacheCollectionResult.LEVELS;i++)
748 System.err.print(" " + iteration.levels[i].size());
749 System.err.println("");
756 needDataInStart = false;
758 // We are returning here within the same GC round - reuse the cache table
767 public CacheEntryBase iterate(int level) {
769 CacheEntryBase entry = iteration.next(level);
771 restart(ITERATION_RATIO);
775 while(entry != null && entry.isDiscarded()) {
776 entry = iteration.next(level);
784 public void remove() {
789 public void setLevel(CacheEntryBase entry, int level) {
790 iteration.setLevel(entry, level);
793 public Collection<CacheEntry> getRootList() {
794 return cache.getRootList();
798 public int calculateCurrentSize() {
799 return cache.calculateCurrentSize();
803 public int getCurrentSize() {
808 // final private static int MINIMUM_SIZE = (int)(Runtime.getRuntime().maxMemory() / 600);
810 private QueryCollectorSupport collectorSupport = new QueryCollectorSupportImpl();
811 private QueryCollector collector = new QueryCollectorImpl(this, collectorSupport);
813 public int querySize() {
817 public void gc(int youngTarget, int allowedTimeInMs) {
819 collector.collect(youngTarget, allowedTimeInMs);
824 void processParentReport(CacheEntry entry, Map<CacheEntry, Set<CacheEntry>> workarea) {
826 if(entry.isDiscarded()) return;
827 if(workarea.containsKey(entry)) return;
829 Iterable<CacheEntry> parents = entry.getParents(this);
830 HashSet<CacheEntry> ps = new HashSet<CacheEntry>();
831 for(CacheEntry e : parents) {
832 if(e.isDiscarded()) continue;
834 processParentReport(e, workarea);
836 workarea.put(entry, ps);
840 public synchronized String reportQueryActivity(File file) throws IOException {
842 System.err.println("reportQueries " + file.getAbsolutePath());
847 PrintStream b = new PrintStream(new BufferedOutputStream(new FileOutputStream(file)));
849 List<Pair<String,Integer>> entries = CollectionUtils.valueSortedEntries(Development.histogram);
850 Collections.reverse(entries);
852 for(Pair<String,Integer> entry : entries) {
853 b.println(entry.first + ": " + entry.second);
858 Development.histogram.clear();
864 public synchronized String reportQueries(File file) throws IOException {
866 System.err.println("reportQueries " + file.getAbsolutePath());
871 PrintStream b = new PrintStream(new BufferedOutputStream(new FileOutputStream(file)));
873 long start = System.nanoTime();
875 // ArrayList<CacheEntry> all = ;
877 Map<CacheEntry, Set<CacheEntry>> workarea = new HashMap<CacheEntry, Set<CacheEntry>>();
878 Collection<CacheEntryBase> caches = allCaches(new CacheCollectionResult()).toCollection();
879 for(CacheEntryBase entry : caches) {
880 processParentReport(entry, workarea);
883 // for(CacheEntry e : all) System.err.println("entry: " + e);
885 long duration = System.nanoTime() - start;
886 System.err.println("Query root set in " + 1e-9*duration + "s.");
888 start = System.nanoTime();
890 HashMap<CacheEntry, Integer> flagMap = new HashMap<CacheEntry, Integer>();
894 for(CacheEntry entry : workarea.keySet()) {
895 boolean listener = listening.hasListenerAfterDisposing(entry);
896 boolean hasParents = entry.getParents(this).iterator().hasNext();
899 flagMap.put(entry, 0);
900 } else if (!hasParents) {
902 flagMap.put(entry, 1);
905 flagMap.put(entry, 2);
918 long start2 = System.nanoTime();
920 int boundCounter = 0;
921 int unboundCounter = 0;
922 int unknownCounter = 0;
924 for(CacheEntry<?> entry : workarea.keySet()) {
926 //System.err.println("process " + entry);
928 int flags = flagMap.get(entry);
929 int bindStatus = flags & 3;
931 if(bindStatus == 0) boundCounter++;
932 else if(bindStatus == 1) unboundCounter++;
933 else if(bindStatus == 2) unknownCounter++;
935 if(bindStatus < 2) continue;
938 for(CacheEntry parent : entry.getParents(this)) {
940 if(parent.isDiscarded()) flagMap.put(parent, 1);
942 int flags2 = flagMap.get(parent);
943 int bindStatus2 = flags2 & 3;
944 // Parent is bound => child is bound
945 if(bindStatus2 == 0) {
949 // Parent is unknown => child is unknown
950 else if (bindStatus2 == 2) {
957 flagMap.put(entry, newStatus);
961 duration = System.nanoTime() - start2;
962 System.err.println("Query analysis pass (" + boundCounter + "/" + unboundCounter + "/" + unknownCounter + ") in "+ 1e-9*duration + "s.");
963 b.println("Query analysis pass (" + boundCounter + "/" + unboundCounter + "/" + unknownCounter + ") in "+ 1e-9*duration + "s.");
965 } while(!done && loops++ < 20);
969 for(CacheEntry entry : workarea.keySet()) {
971 int bindStatus = flagMap.get(entry);
972 if(bindStatus == 2) System.err.println("Undefined bind status for " + entry);
978 duration = System.nanoTime() - start;
979 System.err.println("Query analysis in " + 1e-9*duration + "s.");
981 Map<Class<?>, Integer> counts = new HashMap<Class<?>, Integer>();
983 for(CacheEntry entry : workarea.keySet()) {
984 Class<?> clazz = entry.getClass();
985 if(entry instanceof ReadEntry) clazz = ((ReadEntry)entry).id.getClass();
986 else if(entry instanceof MultiReadEntry) clazz = ((MultiReadEntry)entry).id.getClass();
987 else if(entry instanceof AsyncReadEntry) clazz = ((AsyncReadEntry)entry).id.getClass();
988 else if(entry instanceof AsyncMultiReadEntry) clazz = ((AsyncMultiReadEntry)entry).id.getClass();
989 else if(entry instanceof ExternalReadEntry) clazz = ((ExternalReadEntry)entry).id.getClass();
990 Integer c = counts.get(clazz);
991 if(c == null) counts.put(clazz, -1);
992 else counts.put(clazz, c-1);
995 b.print("// Simantics DB client query report file\n");
996 b.print("// This file contains the following information\n");
997 b.print("// -The amount of cached query instances per query class\n");
998 b.print("// -The sizes of retained child sets\n");
999 b.print("// -List of parents for each query (search for 'P <query name>')\n");
1000 b.print("// -Followed by status, where\n");
1001 b.print("// -0=bound\n");
1002 b.print("// -1=free\n");
1003 b.print("// -2=unknown\n");
1004 b.print("// -L=has listener\n");
1005 b.print("// -List of children for each query (search for 'C <query name>')\n");
1007 b.print("----------------------------------------\n");
1009 b.print("// Queries by class\n");
1010 for(Pair<Class<?>, Integer> p : CollectionUtils.valueSortedEntries(counts)) {
1011 b.print(-p.second + " " + p.first.getName() + "\n");
1014 Map<CacheEntry, Integer> hist = new HashMap<CacheEntry, Integer>();
1015 for(CacheEntry e : workarea.keySet())
1018 boolean changed = true;
1020 while(changed && iter++<50) {
1024 Map<CacheEntry, Integer> newHist = new HashMap<CacheEntry, Integer>();
1025 for(CacheEntry e : workarea.keySet())
1028 for(Map.Entry<CacheEntry, Set<CacheEntry>> e : workarea.entrySet()) {
1029 Integer c = hist.get(e.getKey());
1030 for(CacheEntry p : e.getValue()) {
1031 Integer i = newHist.get(p);
1032 newHist.put(p, i+c);
1035 for(CacheEntry e : workarea.keySet()) {
1036 Integer value = newHist.get(e);
1037 Integer old = hist.get(e);
1038 if(!value.equals(old)) {
1040 // System.err.println("hist " + e + ": " + old + " => " + value);
1045 System.err.println("Retained set iteration " + iter);
1049 b.print("// Queries by retained set\n");
1050 for(Pair<CacheEntry, Integer> p : CollectionUtils.valueSortedEntries(hist)) {
1051 b.print("" + -p.second + " " + p.first + "\n");
1054 HashMap<CacheEntry, Collection<CacheEntry>> inverse = new HashMap<CacheEntry, Collection<CacheEntry>>();
1056 b.print("// Entry parent listing\n");
1057 for(CacheEntry entry : workarea.keySet()) {
1058 int status = flagMap.get(entry);
1059 boolean hasListener = listening.hasListenerAfterDisposing(entry);
1060 b.print("Q " + entry.toString());
1062 b.print(" (L" + status + ")");
1065 b.print(" (" + status + ")");
1068 for(CacheEntry parent : workarea.get(entry)) {
1069 Collection<CacheEntry> inv = inverse.get(parent);
1071 inv = new ArrayList<CacheEntry>();
1072 inverse.put(parent, inv);
1075 b.print(" " + parent.toString());
1080 b.print("// Entry child listing\n");
1081 for(Map.Entry<CacheEntry, Collection<CacheEntry>> entry : inverse.entrySet()) {
1082 b.print("C " + entry.getKey().toString());
1084 for(CacheEntry child : entry.getValue()) {
1085 Integer h = hist.get(child);
1089 b.print(" <no children>");
1091 b.print(" " + child.toString());
1096 b.print("#queries: " + workarea.keySet().size() + "\n");
1097 b.print("#listeners: " + listeners + "\n");
1101 return "Dumped " + workarea.keySet().size() + " queries.";
1105 boolean removeQuery(CacheEntry entry) {
1107 // This entry has been removed before. No need to do anything here.
1108 if(entry.isDiscarded()) return false;
1110 assert (!entry.isDiscarded());
1112 Query query = entry.getQuery();
1114 query.removeEntry(this);
1119 if((entry.getGCStatus() & CacheEntry.HAS_BEEN_BOUND) != 0)
1130 * @return true if this entry is being listened
1132 private boolean updateQuery(UpdateEntry e, LinkedList<UpdateEntry> todo, IdentityHashMap<CacheEntry, CacheEntry> immediates) throws DatabaseException {
1136 CacheEntry entry = e.entry;
1139 * If the dependency graph forms a DAG, some entries are inserted in the
1140 * todo list many times. They only need to be processed once though.
1142 if (entry.isDiscarded()) {
1143 if (Development.DEVELOPMENT) {
1144 if(Development.<Boolean>getProperty(DevelopmentKeys.QUERYPROCESSOR_UPDATE, Bindings.BOOLEAN)) {
1145 System.err.print("D");
1146 for (int i = 0; i < e.indent; i++)
1147 System.err.print(" ");
1148 System.err.println(entry.getQuery());
1151 // System.err.println(" => DISCARDED");
1155 // if (entry.isRefuted()) {
1156 // if (Development.DEVELOPMENT) {
1157 // if(Development.<Boolean>getProperty(DevelopmentKeys.QUERYPROCESSOR_UPDATE, Bindings.BOOLEAN)) {
1158 // System.err.print("R");
1159 // for (int i = 0; i < e.indent; i++)
1160 // System.err.print(" ");
1161 // System.err.println(entry.getQuery());
1167 if (entry.isExcepted()) {
1168 if (Development.DEVELOPMENT) {
1169 if(Development.<Boolean>getProperty(DevelopmentKeys.QUERYPROCESSOR_UPDATE, Bindings.BOOLEAN)) {
1170 System.err.print("E");
1175 if (entry.isPending()) {
1176 if (Development.DEVELOPMENT) {
1177 if(Development.<Boolean>getProperty(DevelopmentKeys.QUERYPROCESSOR_UPDATE, Bindings.BOOLEAN)) {
1178 System.err.print("P");
1185 if (Development.DEVELOPMENT) {
1186 if(Development.<Boolean>getProperty(DevelopmentKeys.QUERYPROCESSOR_UPDATE, Bindings.BOOLEAN)) {
1187 System.err.print("U ");
1188 for (int i = 0; i < e.indent; i++)
1189 System.err.print(" ");
1190 System.err.print(entry.getQuery());
1194 Query query = entry.getQuery();
1195 int type = query.type();
1197 boolean hasListener = listening.hasListener(entry);
1199 if (Development.DEVELOPMENT) {
1200 if(Development.<Boolean>getProperty(DevelopmentKeys.QUERYPROCESSOR_UPDATE, Bindings.BOOLEAN)) {
1201 if(listening.hasListener(entry)) {
1202 System.err.println(" (L)");
1204 System.err.println("");
1209 if(entry.isPending() || entry.isExcepted()) {
1212 if ((type & RequestFlags.UPDATE_MASK) == RequestFlags.IMMEDIATE_UPDATE) {
1214 immediates.put(entry, entry);
1229 if ((type & RequestFlags.UPDATE_MASK) == RequestFlags.IMMEDIATE_UPDATE) {
1231 immediates.put(entry, entry);
1245 // System.err.println(" => FOO " + type);
1248 ArrayList<ListenerEntry> entries = listening.listeners.get(entry);
1249 if(entries != null) {
1250 for (ListenerEntry le : entries) {
1251 listening.scheduleListener(le);
1256 // If invalid, update parents
1257 if (type == RequestFlags.INVALIDATE) {
1258 listening.updateParents(e.indent, entry, todo);
1266 * @param av1 an array (guaranteed)
1267 * @param av2 any object
1268 * @return <code>true</code> if the two arrays are equal
1270 private final boolean arrayEquals(Object av1, Object av2) {
1273 Class<?> c1 = av1.getClass().getComponentType();
1274 Class<?> c2 = av2.getClass().getComponentType();
1275 if (c2 == null || !c1.equals(c2))
1277 boolean p1 = c1.isPrimitive();
1278 boolean p2 = c2.isPrimitive();
1282 return Arrays.equals((Object[]) av1, (Object[]) av2);
1283 if (boolean.class.equals(c1))
1284 return Arrays.equals((boolean[]) av1, (boolean[]) av2);
1285 else if (byte.class.equals(c1))
1286 return Arrays.equals((byte[]) av1, (byte[]) av2);
1287 else if (int.class.equals(c1))
1288 return Arrays.equals((int[]) av1, (int[]) av2);
1289 else if (long.class.equals(c1))
1290 return Arrays.equals((long[]) av1, (long[]) av2);
1291 else if (float.class.equals(c1))
1292 return Arrays.equals((float[]) av1, (float[]) av2);
1293 else if (double.class.equals(c1))
1294 return Arrays.equals((double[]) av1, (double[]) av2);
1295 throw new RuntimeException("??? Contact application querySupport.");
1300 final Object compareTo(ReadGraphImpl graph, final CacheEntry entry, final Object oldValue) {
1304 Query query = entry.getQuery();
1306 if (Development.DEVELOPMENT) {
1307 if(Development.<Boolean>getProperty(DevelopmentKeys.QUERYPROCESSOR_RECOMPUTE, Bindings.BOOLEAN)) {
1308 System.err.println("R " + query);
1312 entry.prepareRecompute(querySupport);
1314 ReadGraphImpl parentGraph = graph.forRecompute(entry);
1316 query.recompute(parentGraph);
1318 if(entry.isExcepted()) return ListenerEntry.NO_VALUE;
1320 Object newValue = entry.getResult();
1322 if (ListenerEntry.NO_VALUE == oldValue) {
1323 if (Development.DEVELOPMENT) {
1324 if(Development.<Boolean>getProperty(DevelopmentKeys.QUERYPROCESSOR_CHANGES, Bindings.BOOLEAN)) {
1325 System.out.println("C " + query);
1326 System.out.println("- " + oldValue);
1327 System.out.println("- " + newValue);
1333 boolean changed = false;
1335 if (newValue != null) {
1336 if (newValue.getClass().isArray()) {
1337 changed = !arrayEquals(newValue, oldValue);
1339 changed = !newValue.equals(oldValue);
1342 changed = (oldValue != null);
1344 if (Development.DEVELOPMENT) {
1345 if(Development.<Boolean>getProperty(DevelopmentKeys.QUERYPROCESSOR_CHANGES, Bindings.BOOLEAN)) {
1346 System.err.println("C " + query);
1347 System.err.println("- " + oldValue);
1348 System.err.println("- " + newValue);
1352 return changed ? newValue : ListenerEntry.NOT_CHANGED;
1354 } catch (Throwable t) {
1356 Logger.defaultLogError(t);
1358 return ListenerEntry.NO_VALUE;
1367 * @return true if this entry still has listeners
1369 public boolean update(final ReadGraphImpl graph, final CacheEntry entry) {
1371 assert (!cache.collecting);
1375 boolean hadListeners = false;
1376 boolean listenersUnknown = false;
1380 assert(entry != null);
1381 LinkedList<UpdateEntry> todo = new LinkedList<UpdateEntry>();
1382 IdentityHashMap<CacheEntry, CacheEntry> immediates = new IdentityHashMap<CacheEntry, CacheEntry>();
1383 todo.add(new UpdateEntry(null, entry, 0));
1387 // Walk the tree and collect immediate updates
1388 while (!todo.isEmpty()) {
1389 UpdateEntry e = todo.pop();
1390 hadListeners |= updateQuery(e, todo, immediates);
1393 if(immediates.isEmpty()) break;
1395 // Evaluate all immediate updates and collect parents to update
1396 for(CacheEntry immediate : immediates.values()) {
1398 if(immediate.isDiscarded()) {
1402 if(immediate.isExcepted()) {
1404 Object newValue = compareTo(graph, immediate, ListenerEntry.NO_VALUE);
1405 if (newValue != ListenerEntry.NOT_CHANGED)
1406 listening.updateParents(0, immediate, todo);
1410 Object oldValue = immediate.getResult();
1411 Object newValue = compareTo(graph, immediate, oldValue);
1413 if (newValue != ListenerEntry.NOT_CHANGED) {
1414 listening.updateParents(0, immediate, todo);
1416 // If not changed, keep the old value
1417 immediate.setResult(oldValue);
1418 immediate.setReady();
1419 listenersUnknown = true;
1429 } catch (Throwable t) {
1430 Logger.defaultLogError(t);
1436 return hadListeners | listenersUnknown;
1440 private ObjectUpdateSet scheduledObjectUpdates = new ObjectUpdateSet();
1441 private ValueUpdateSet scheduledValueUpdates = new ValueUpdateSet();
1442 private ValueUpdateSet scheduledInvalidates = new ValueUpdateSet();
1443 // Maybe use a mutex from util.concurrent?
1444 private Object primitiveUpdateLock = new Object();
1445 private THashSet scheduledPrimitiveUpdates = new THashSet();
1447 private ArrayList<CacheEntry> refutations = new ArrayList<>();
1449 private void markForUpdate(ReadGraphImpl graph, CacheEntry e) {
1454 private void updateRefutations(ReadGraphImpl graph) {
1456 for(CacheEntry e : refutations)
1459 refutations.clear();
1463 public void propagateChangesInQueryCache(final ReadGraphImpl graph) {
1465 // Make sure that listening has performed its work
1468 cache.dirty = false;
1471 if (Development.DEVELOPMENT) {
1472 if(Development.<Boolean>getProperty(DevelopmentKeys.QUERYPROCESSOR_UPDATE, Bindings.BOOLEAN)) {
1473 System.err.println("== Query update ==");
1477 // Special case - one statement
1478 if(scheduledObjectUpdates.size() == 1 && scheduledValueUpdates.size() == 0 && scheduledPrimitiveUpdates.size() == 0 && scheduledInvalidates.size() == 0) {
1480 long arg0 = scheduledObjectUpdates.getFirst();
1482 final int subject = (int)(arg0 >>> 32);
1483 final int predicate = (int)(arg0 & 0xffffffff);
1485 for(Objects o : QueryCache.entriesObjects(QueryProcessor.this, subject)) markForUpdate(graph, o);
1486 for(DirectObjects o : QueryCache.entriesDirectObjects(QueryProcessor.this, subject)) markForUpdate(graph, o);
1487 for(Statements o : QueryCache.entriesStatements(QueryProcessor.this, subject)) markForUpdate(graph, o);
1489 if(predicate == instanceOf || predicate == inherits || predicate == subrelationOf) {
1490 PrincipalTypes principalTypes = QueryCache.entryPrincipalTypes(QueryProcessor.this, subject);
1491 if(principalTypes != null) markForUpdate(graph, principalTypes);
1492 Types types = QueryCache.entryTypes(QueryProcessor.this, subject);
1493 if(types != null) markForUpdate(graph, types);
1496 if(predicate == subrelationOf) {
1497 SuperRelations superRelations = SuperRelations.entry(QueryProcessor.this, subject);
1498 if(superRelations != null) markForUpdate(graph, superRelations);
1501 DirectPredicates dp = QueryCache.entryDirectPredicates(QueryProcessor.this, subject);
1502 if(dp != null) markForUpdate(graph, dp);
1503 OrderedSet os = QueryCache.entryOrderedSet(QueryProcessor.this, predicate);
1504 if(os != null) markForUpdate(graph, os);
1506 updateRefutations(graph);
1508 scheduledObjectUpdates.clear();
1510 if (Development.DEVELOPMENT) {
1511 if(Development.<Boolean>getProperty(DevelopmentKeys.QUERYPROCESSOR_UPDATE, Bindings.BOOLEAN)) {
1512 System.err.println("== Query update ends ==");
1520 // Special case - one value
1521 if(scheduledObjectUpdates.size() == 0 && scheduledValueUpdates.size() == 1 && scheduledPrimitiveUpdates.size() == 0 && scheduledInvalidates.size() == 0) {
1523 int arg0 = scheduledValueUpdates.getFirst();
1525 ValueQuery valueQuery = QueryCache.entryValueQuery(QueryProcessor.this, arg0);
1526 if(valueQuery != null) markForUpdate(graph, valueQuery);
1528 updateRefutations(graph);
1530 scheduledValueUpdates.clear();
1532 if (Development.DEVELOPMENT) {
1533 if(Development.<Boolean>getProperty(DevelopmentKeys.QUERYPROCESSOR_UPDATE, Bindings.BOOLEAN)) {
1534 System.err.println("== Query update ends ==");
1542 final TIntHashSet predicates = new TIntHashSet();
1543 final TIntHashSet orderedSets = new TIntHashSet();
1545 THashSet primitiveUpdates;
1546 synchronized (primitiveUpdateLock) {
1547 primitiveUpdates = scheduledPrimitiveUpdates;
1548 scheduledPrimitiveUpdates = new THashSet();
1551 scheduledValueUpdates.forEach(new TIntProcedure() {
1554 public boolean execute(int arg0) {
1555 ValueQuery valueQuery = QueryCache.entryValueQuery(QueryProcessor.this, arg0);
1556 if(valueQuery != null) markForUpdate(graph, valueQuery);
1562 scheduledInvalidates.forEach(new TIntProcedure() {
1565 public boolean execute(int resource) {
1567 ValueQuery valueQuery = QueryCache.entryValueQuery(QueryProcessor.this, resource);
1568 if(valueQuery != null) markForUpdate(graph, valueQuery);
1570 PrincipalTypes principalTypes = QueryCache.entryPrincipalTypes(QueryProcessor.this, resource);
1571 if(principalTypes != null) markForUpdate(graph, principalTypes);
1572 Types types = QueryCache.entryTypes(QueryProcessor.this, resource);
1573 if(types != null) markForUpdate(graph, types);
1575 SuperRelations superRelations = SuperRelations.entry(QueryProcessor.this, resource);
1576 if(superRelations != null) markForUpdate(graph, superRelations);
1578 predicates.add(resource);
1585 scheduledObjectUpdates.forEach(new TLongProcedure() {
1588 public boolean execute(long arg0) {
1590 final int subject = (int)(arg0 >>> 32);
1591 final int predicate = (int)(arg0 & 0xffffffff);
1593 if(predicate == instanceOf || predicate == inherits || predicate == subrelationOf) {
1594 PrincipalTypes principalTypes = QueryCache.entryPrincipalTypes(QueryProcessor.this, subject);
1595 if(principalTypes != null) markForUpdate(graph, principalTypes);
1596 Types types = QueryCache.entryTypes(QueryProcessor.this, subject);
1597 if(types != null) markForUpdate(graph, types);
1600 if(predicate == subrelationOf) {
1601 SuperRelations superRelations = SuperRelations.entry(QueryProcessor.this, subject);
1602 if(superRelations != null) markForUpdate(graph, superRelations);
1605 predicates.add(subject);
1606 orderedSets.add(predicate);
1614 predicates.forEach(new TIntProcedure() {
1617 public boolean execute(final int subject) {
1619 for(Objects o : QueryCache.entriesObjects(QueryProcessor.this, subject)) markForUpdate(graph, o);
1620 for(DirectObjects o : QueryCache.entriesDirectObjects(QueryProcessor.this, subject)) markForUpdate(graph, o);
1621 for(Statements o : QueryCache.entriesStatements(QueryProcessor.this, subject)) markForUpdate(graph, o);
1623 DirectPredicates entry = QueryCache.entryDirectPredicates(QueryProcessor.this, subject);
1624 if(entry != null) markForUpdate(graph, entry);
1632 orderedSets.forEach(new TIntProcedure() {
1635 public boolean execute(int orderedSet) {
1637 OrderedSet entry = QueryCache.entryOrderedSet(QueryProcessor.this, orderedSet);
1638 if(entry != null) markForUpdate(graph, entry);
1646 updateRefutations(graph);
1648 primitiveUpdates.forEach(new TObjectProcedure() {
1651 public boolean execute(Object arg0) {
1653 ExternalReadEntry query = (ExternalReadEntry)cache.externalReadEntryMap.get(arg0);
1654 if (query != null) {
1655 boolean listening = update(graph, query);
1656 if (!listening && !query.hasParents()) {
1657 cache.externalReadEntryMap.remove(arg0);
1666 scheduledValueUpdates.clear();
1667 scheduledObjectUpdates.clear();
1668 scheduledInvalidates.clear();
1670 if (Development.DEVELOPMENT) {
1671 if(Development.<Boolean>getProperty(DevelopmentKeys.QUERYPROCESSOR_UPDATE, Bindings.BOOLEAN)) {
1672 System.err.println("== Query update ends ==");
1678 public void updateValue(final int resource) {
1679 scheduledValueUpdates.add(resource);
1683 public void updateStatements(final int resource, final int predicate) {
1684 scheduledObjectUpdates.add((((long)resource) << 32) + predicate);
1688 private int lastInvalidate = 0;
1690 public void invalidateResource(final int resource) {
1691 if(lastInvalidate == resource) return;
1692 scheduledValueUpdates.add(resource);
1693 lastInvalidate = resource;
1697 public void updatePrimitive(final ExternalRead primitive) {
1699 // External reads may be updated from arbitrary threads.
1700 // Synchronize to prevent race-conditions.
1701 synchronized (primitiveUpdateLock) {
1702 scheduledPrimitiveUpdates.add(primitive);
1704 querySupport.dirtyPrimitives();
1709 public synchronized String toString() {
1710 return "QueryProvider [size = " + cache.size + ", hits = " + cache.hits + " misses = " + cache.misses + ", updates = " + cache.updates + "]";
1714 protected void doDispose() {
1716 requests.release(Integer.MAX_VALUE / 2);
1718 for(int index = 0; index < THREADS; index++) {
1719 executors[index].dispose();
1723 for(int i=0;i<100;i++) {
1725 boolean alive = false;
1726 for(int index = 0; index < THREADS; index++) {
1727 alive |= executors[index].isAlive();
1732 } catch (InterruptedException e) {
1733 Logger.defaultLogError(e);
1738 // Then start interrupting
1739 for(int i=0;i<100;i++) {
1741 boolean alive = false;
1742 for(int index = 0; index < THREADS; index++) {
1743 alive |= executors[index].isAlive();
1746 for(int index = 0; index < THREADS; index++) {
1747 executors[index].interrupt();
1751 // // Then just destroy
1752 // for(int index = 0; index < THREADS; index++) {
1753 // executors[index].destroy();
1756 for(int index = 0; index < THREADS; index++) {
1758 executors[index].join(5000);
1759 } catch (InterruptedException e) {
1760 Logger.defaultLogError("QueryThread " + index + " will not die.", e);
1762 executors[index] = null;
1767 public int getHits() {
1771 public int getMisses() {
1772 return cache.misses;
1775 public int getSize() {
1779 public Set<Long> getReferencedClusters() {
1780 HashSet<Long> result = new HashSet<Long>();
1781 for (CacheEntry entry : QueryCache.entriesObjects(this)) {
1782 Objects query = (Objects) entry.getQuery();
1783 result.add(querySupport.getClusterId(query.r1()));
1785 for (CacheEntry entry : QueryCache.entriesDirectPredicates(this)) {
1786 DirectPredicates query = (DirectPredicates) entry.getQuery();
1787 result.add(querySupport.getClusterId(query.id));
1789 for (CacheEntry entry : cache.valueQueryMap.values()) {
1790 ValueQuery query = (ValueQuery) entry.getQuery();
1791 result.add(querySupport.getClusterId(query.id));
1796 public void assertDone() {
1799 CacheCollectionResult allCaches(CacheCollectionResult result) {
1801 return cache.allCaches(result);
1805 public void printDiagnostics() {
1808 public void requestCluster(ReadGraphImpl graph, long clusterId, Runnable runnable) {
1809 querySupport.requestCluster(graph, clusterId, runnable);
1812 public int clean() {
1813 collector.collect(0, Integer.MAX_VALUE);
1817 public void clean(final Collection<ExternalRead<?>> requests) {
1818 QueryCollectorSupport collectorSupport = new QueryCollectorSupport() {
1819 Iterator<ExternalRead<?>> iterator = requests.iterator();
1821 public CacheCollectionResult allCaches() {
1822 throw new UnsupportedOperationException();
1825 public CacheEntryBase iterate(int level) {
1826 if(iterator.hasNext()) {
1827 ExternalRead<?> request = iterator.next();
1828 ExternalReadEntry entry = cache.externalReadEntryMap.get(request);
1829 if (entry != null) return entry;
1830 else return iterate(level);
1832 iterator = requests.iterator();
1837 public void remove() {
1838 throw new UnsupportedOperationException();
1841 public void setLevel(CacheEntryBase entry, int level) {
1842 throw new UnsupportedOperationException();
1845 public Collection<CacheEntry> getRootList() {
1846 ArrayList<CacheEntry> result = new ArrayList<CacheEntry>(requests.size());
1847 for (ExternalRead<?> request : requests) {
1848 ExternalReadEntry entry = cache.externalReadEntryMap.get(request);
1855 public int getCurrentSize() {
1859 public int calculateCurrentSize() {
1860 // This tells the collector to attempt collecting everything.
1861 return Integer.MAX_VALUE;
1864 public boolean start(boolean flush) {
1868 new QueryCollectorImpl2(this, collectorSupport).collect(0, Integer.MAX_VALUE);
1871 public void scanPending() {
1873 cache.scanPending();
1877 public ReadGraphImpl graphForVirtualRequest() {
1878 return ReadGraphImpl.createAsync(this);
1882 private HashMap<Resource, Class<?>> builtinValues;
1884 public Class<?> getBuiltinValue(Resource r) {
1885 if(builtinValues == null) initBuiltinValues();
1886 return builtinValues.get(r);
1889 Exception callerException = null;
1891 public interface AsyncBarrier {
1894 // public void inc(String debug);
1895 // public void dec(String debug);
1898 // final public QueryProcessor processor;
1899 // final public QuerySupport support;
1901 // boolean disposed = false;
1903 private void initBuiltinValues() {
1905 Layer0 b = getSession().peekService(Layer0.class);
1906 if(b == null) return;
1908 builtinValues = new HashMap<Resource, Class<?>>();
1910 builtinValues.put(b.String, String.class);
1911 builtinValues.put(b.Double, Double.class);
1912 builtinValues.put(b.Float, Float.class);
1913 builtinValues.put(b.Long, Long.class);
1914 builtinValues.put(b.Integer, Integer.class);
1915 builtinValues.put(b.Byte, Byte.class);
1916 builtinValues.put(b.Boolean, Boolean.class);
1918 builtinValues.put(b.StringArray, String[].class);
1919 builtinValues.put(b.DoubleArray, double[].class);
1920 builtinValues.put(b.FloatArray, float[].class);
1921 builtinValues.put(b.LongArray, long[].class);
1922 builtinValues.put(b.IntegerArray, int[].class);
1923 builtinValues.put(b.ByteArray, byte[].class);
1924 builtinValues.put(b.BooleanArray, boolean[].class);
1928 // public ReadGraphSupportImpl(final QueryProcessor provider2) {
1930 // if (null == provider2) {
1931 // this.processor = null;
1935 // this.processor = provider2;
1936 // support = provider2.getCore();
1937 // initBuiltinValues();
1941 // final static public ReadGraphSupportImpl basedOn(ReadGraphSupportImpl impl) {
1942 // return new ReadGraphSupportImpl(impl.processor);
1946 final public Session getSession() {
1950 final public ResourceSupport getResourceSupport() {
1951 return resourceSupport;
1955 final public void forEachPredicate(final ReadGraphImpl impl, final Resource subject, final AsyncMultiProcedure<Resource> procedure) {
1959 for(Resource predicate : getPredicates(impl, subject))
1960 procedure.execute(impl, predicate);
1962 procedure.finished(impl);
1964 } catch (Throwable e) {
1965 procedure.exception(impl, e);
1971 final public void forEachPredicate(final ReadGraphImpl impl, final Resource subject, final MultiProcedure<Resource> procedure) {
1973 throw new UnsupportedOperationException();
1975 // assert(subject != null);
1976 // assert(procedure != null);
1978 // final ListenerBase listener = getListenerBase(procedure);
1981 // QueryCache.runnerPredicates(impl, querySupport.getId(subject), impl.parent, listener, new IntProcedure() {
1984 // public void execute(ReadGraphImpl graph, int i) {
1986 // procedure.execute(querySupport.getResource(i));
1987 // } catch (Throwable t2) {
1988 // Logger.defaultLogError(t2);
1993 // public void finished(ReadGraphImpl graph) {
1995 // procedure.finished();
1996 // } catch (Throwable t2) {
1997 // Logger.defaultLogError(t2);
1999 //// impl.state.barrier.dec();
2003 // public void exception(ReadGraphImpl graph, Throwable t) {
2005 // procedure.exception(t);
2006 // } catch (Throwable t2) {
2007 // Logger.defaultLogError(t2);
2009 //// impl.state.barrier.dec();
2013 // } catch (DatabaseException e) {
2014 // Logger.defaultLogError(e);
2020 final public IntSet getPredicates(final ReadGraphImpl impl, final Resource subject) throws Throwable {
2021 return QueryCacheBase.resultPredicates(impl, querySupport.getId(subject), impl.parent, null);
2025 final public void forEachStatement(final ReadGraphImpl impl, final Resource subject,
2026 final Resource predicate, final MultiProcedure<Statement> procedure) {
2028 assert(subject != null);
2029 assert(predicate != null);
2030 assert(procedure != null);
2032 final ListenerBase listener = getListenerBase(procedure);
2034 // impl.state.barrier.inc();
2037 Statements.queryEach(impl, querySupport.getId(subject), querySupport.getId(predicate), this, impl.parent, listener, new TripleIntProcedureAdapter() {
2040 public void execute(ReadGraphImpl graph, int s, int p, int o) {
2042 procedure.execute(querySupport.getStatement(s, p, o));
2043 } catch (Throwable t2) {
2044 Logger.defaultLogError(t2);
2049 public void finished(ReadGraphImpl graph) {
2051 procedure.finished();
2052 } catch (Throwable t2) {
2053 Logger.defaultLogError(t2);
2055 // impl.state.barrier.dec();
2059 public void exception(ReadGraphImpl graph, Throwable t) {
2061 procedure.exception(t);
2062 } catch (Throwable t2) {
2063 Logger.defaultLogError(t2);
2065 // impl.state.barrier.dec();
2069 } catch (DatabaseException e) {
2070 Logger.defaultLogError(e);
2076 final public void forEachStatement(final ReadGraphImpl impl, final Resource subject,
2077 final Resource predicate, final AsyncMultiProcedure<Statement> procedure) {
2079 assert(subject != null);
2080 assert(predicate != null);
2081 assert(procedure != null);
2083 final ListenerBase listener = getListenerBase(procedure);
2085 TripleIntProcedureAdapter proc = new TripleIntProcedureAdapter() {
2087 boolean first = true;
2090 public void execute(ReadGraphImpl graph, int s, int p, int o) {
2093 procedure.execute(graph, querySupport.getStatement(s, p, o));
2095 procedure.execute(impl.newRestart(graph), querySupport.getStatement(s, p, o));
2097 } catch (Throwable t2) {
2098 Logger.defaultLogError(t2);
2103 public void finished(ReadGraphImpl graph) {
2108 procedure.finished(graph);
2109 // impl.state.barrier.dec(this);
2111 procedure.finished(impl.newRestart(graph));
2113 } catch (Throwable t2) {
2114 Logger.defaultLogError(t2);
2120 public void exception(ReadGraphImpl graph, Throwable t) {
2125 procedure.exception(graph, t);
2126 // impl.state.barrier.dec(this);
2128 procedure.exception(impl.newRestart(graph), t);
2130 } catch (Throwable t2) {
2131 Logger.defaultLogError(t2);
2138 int sId = querySupport.getId(subject);
2139 int pId = querySupport.getId(predicate);
2141 // if(AsyncBarrierImpl.BOOKKEEPING) impl.state.barrier.inc(proc, "#Statements" + sId + "#" + pId);
2142 // else impl.state.barrier.inc(null, null);
2145 Statements.queryEach(impl, sId, pId, this, impl.parent, listener, proc);
2146 } catch (DatabaseException e) {
2147 Logger.defaultLogError(e);
2153 final public void forEachStatement(final ReadGraphImpl impl, final Resource subject,
2154 final Resource predicate, final StatementProcedure procedure) {
2156 assert(subject != null);
2157 assert(predicate != null);
2158 assert(procedure != null);
2160 final ListenerBase listener = getListenerBase(procedure);
2162 TripleIntProcedureAdapter proc = new TripleIntProcedureAdapter() {
2164 boolean first = true;
2167 public void execute(ReadGraphImpl graph, int s, int p, int o) {
2170 procedure.execute(graph, s, p, o);
2172 procedure.execute(impl.newRestart(graph), s, p, o);
2174 } catch (Throwable t2) {
2175 Logger.defaultLogError(t2);
2180 public void finished(ReadGraphImpl graph) {
2185 procedure.finished(graph);
2186 // impl.state.barrier.dec(this);
2188 procedure.finished(impl.newRestart(graph));
2190 } catch (Throwable t2) {
2191 Logger.defaultLogError(t2);
2197 public void exception(ReadGraphImpl graph, Throwable t) {
2202 procedure.exception(graph, t);
2203 // impl.state.barrier.dec(this);
2205 procedure.exception(impl.newRestart(graph), t);
2207 } catch (Throwable t2) {
2208 Logger.defaultLogError(t2);
2215 int sId = querySupport.getId(subject);
2216 int pId = querySupport.getId(predicate);
2218 // if(AsyncBarrierImpl.BOOKKEEPING) impl.state.barrier.inc(proc, "#Statements" + sId + "#" + pId);
2219 // else impl.state.barrier.inc(null, null);
2222 Statements.queryEach(impl, sId, pId, this, impl.parent, listener, proc);
2223 } catch (DatabaseException e) {
2224 Logger.defaultLogError(e);
2230 final public void forStatementSet(final ReadGraphImpl impl, final Resource subject, final Resource predicate, final AsyncSetListener<Statement> procedure) {
2232 assert(subject != null);
2233 assert(predicate != null);
2234 assert(procedure != null);
2236 forEachStatement(impl, subject, predicate, new AsyncMultiListener<Statement>() {
2238 private Set<Statement> current = null;
2239 private Set<Statement> run = new HashSet<Statement>();
2242 public void execute(AsyncReadGraph graph, Statement result) {
2244 boolean found = false;
2246 if(current != null) {
2248 found = current.remove(result);
2252 if(!found) procedure.add(graph, result);
2259 public void finished(AsyncReadGraph graph) {
2261 if(current != null) {
2262 for(Statement r : current) procedure.remove(graph, r);
2267 run = new HashSet<Statement>();
2272 public void exception(AsyncReadGraph graph, Throwable t) {
2273 procedure.exception(graph, t);
2277 public boolean isDisposed() {
2278 return procedure.isDisposed();
2286 final public void forEachAssertedStatement(final ReadGraphImpl impl, final Resource subject,
2287 final Resource predicate, final AsyncMultiProcedure<Statement> procedure) {
2289 assert(subject != null);
2290 assert(predicate != null);
2291 assert(procedure != null);
2293 final ListenerBase listener = getListenerBase(procedure);
2295 // impl.state.barrier.inc();
2298 QueryCache.runnerAssertedStatements(impl, querySupport.getId(subject), querySupport.getId(predicate), impl.parent, listener, new TripleIntProcedureAdapter() {
2301 public void execute(ReadGraphImpl graph, int s, int p, int o) {
2303 procedure.execute(graph, querySupport.getStatement(s, p, o));
2304 } catch (Throwable t2) {
2305 Logger.defaultLogError(t2);
2310 public void finished(ReadGraphImpl graph) {
2312 procedure.finished(graph);
2313 } catch (Throwable t2) {
2314 Logger.defaultLogError(t2);
2316 // impl.state.barrier.dec();
2320 public void exception(ReadGraphImpl graph, Throwable t) {
2322 procedure.exception(graph, t);
2323 } catch (Throwable t2) {
2324 Logger.defaultLogError(t2);
2326 // impl.state.barrier.dec();
2330 } catch (DatabaseException e) {
2331 Logger.defaultLogError(e);
2336 private static ListenerBase getListenerBase(Object procedure) {
2337 if(procedure instanceof ListenerBase) return (ListenerBase)procedure;
2342 final public void forEachObject(final ReadGraphImpl impl, final Resource subject, final Resource predicate, final MultiProcedure<Resource> procedure) {
2344 assert(subject != null);
2345 assert(predicate != null);
2346 assert(procedure != null);
2348 final ListenerBase listener = getListenerBase(procedure);
2350 // impl.state.barrier.inc();
2353 QueryCache.runnerObjects(impl, querySupport.getId(subject), querySupport.getId(predicate), impl.parent, listener, new IntProcedure() {
2356 public void execute(ReadGraphImpl graph, int i) {
2358 procedure.execute(querySupport.getResource(i));
2359 } catch (Throwable t2) {
2360 Logger.defaultLogError(t2);
2365 public void finished(ReadGraphImpl graph) {
2367 procedure.finished();
2368 } catch (Throwable t2) {
2369 Logger.defaultLogError(t2);
2371 // impl.state.barrier.dec();
2375 public void exception(ReadGraphImpl graph, Throwable t) {
2376 System.out.println("forEachObject exception " + t);
2378 procedure.exception(t);
2379 } catch (Throwable t2) {
2380 Logger.defaultLogError(t2);
2382 // impl.state.barrier.dec();
2386 } catch (DatabaseException e) {
2387 Logger.defaultLogError(e);
2393 final public void forEachDirectPredicate(final ReadGraphImpl impl, final Resource subject, final AsyncProcedure<Set<Resource>> procedure) {
2395 assert(subject != null);
2396 assert(procedure != null);
2398 final ListenerBase listener = getListenerBase(procedure);
2400 int sId = querySupport.getId(subject);
2403 QueryCache.runnerDirectPredicates(impl, sId, impl.parent, listener, new InternalProcedure<IntSet>() {
2406 public void execute(ReadGraphImpl graph, IntSet result) throws DatabaseException {
2407 procedure.execute(graph, result);
2411 public void exception(ReadGraphImpl graph, Throwable throwable) throws DatabaseException {
2412 procedure.exception(graph, throwable);
2416 } catch (DatabaseException e) {
2417 Logger.defaultLogError(e);
2422 final public DirectStatements getDirectStatements(final ReadGraphImpl impl, final Resource subject, final boolean ignoreVirtual) {
2424 // assert(subject != null);
2425 // assert(procedure != null);
2427 // final ListenerBase listener = getListenerBase(procedure);
2429 // org.simantics.db.impl.query.DirectStatements.queryEach(impl, querySupport.getId(subject), this, impl.parent, listener, procedure);
2431 return querySupport.getStatements(impl, querySupport.getId(subject), this, ignoreVirtual);
2436 // final public void forEachDirectStatement(final ReadGraphImpl impl, final Resource subject, final SyncProcedure<DirectStatements> procedure, boolean ignoreVirtual) {
2438 // assert(subject != null);
2439 // assert(procedure != null);
2441 // final ListenerBase listener = getListenerBase(procedure);
2443 // org.simantics.db.impl.query.DirectStatements.queryEach(impl, querySupport.getId(subject), this, impl.parent, listener, procedure, ignoreVirtual);
2447 private static final Resource INVALID_RESOURCE = new ResourceImpl(null, Integer.MIN_VALUE);
2450 final public void forPossibleObject(final ReadGraphImpl impl, final Resource subject, final Resource predicate, final AsyncProcedure<Resource> procedure) {
2452 forEachObject(impl, subject, predicate, new AsyncMultiProcedure<Resource>() {
2454 private Resource single = null;
2457 public synchronized void execute(AsyncReadGraph graph, Resource result) {
2458 if(single == null) {
2461 single = INVALID_RESOURCE;
2466 public synchronized void finished(AsyncReadGraph graph) {
2467 if(single == null || single == INVALID_RESOURCE) procedure.execute(graph, null);
2468 else procedure.execute(graph, single);
2472 public synchronized void exception(AsyncReadGraph graph, Throwable throwable) {
2473 procedure.exception(graph, throwable);
2480 final public void forEachObject(final ReadGraphImpl impl, final Resource subject, final Resource predicate, final ListenerBase listener, final IntProcedure procedure) {
2482 final int sId = querySupport.getId(subject);
2483 final int pId = querySupport.getId(predicate);
2486 QueryCache.runnerObjects(impl, sId, pId, impl.parent, listener, procedure);
2487 } catch (DatabaseException e) {
2488 Logger.defaultLogError(e);
2493 static class Runner2Procedure implements IntProcedure {
2495 public int single = 0;
2496 public Throwable t = null;
2498 public void clear() {
2504 public void execute(ReadGraphImpl graph, int i) {
2505 if(single == 0) single = i;
2510 public void finished(ReadGraphImpl graph) {
2511 if(single == -1) single = 0;
2515 public void exception(ReadGraphImpl graph, Throwable throwable) {
2520 public int get() throws DatabaseException {
2522 if(t instanceof DatabaseException) throw (DatabaseException)t;
2523 else throw new DatabaseException(t);
2530 final public int getSingleObject(final ReadGraphImpl impl, final Resource subject, final Resource predicate) throws DatabaseException {
2532 final int sId = querySupport.getId(subject);
2533 final int pId = querySupport.getId(predicate);
2535 Runner2Procedure proc = new Runner2Procedure();
2536 QueryCache.runnerObjects(impl, sId, pId, impl.parent, null, proc);
2541 final public void forEachObject(final ReadGraphImpl impl, final Resource subject, final Resource predicate, final AsyncMultiProcedure<Resource> procedure) {
2543 assert(subject != null);
2544 assert(predicate != null);
2546 final ListenerBase listener = getListenerBase(procedure);
2548 if(impl.parent != null || listener != null) {
2550 IntProcedure ip = new IntProcedure() {
2552 AtomicBoolean first = new AtomicBoolean(true);
2555 public void execute(ReadGraphImpl graph, int i) {
2558 procedure.execute(impl, querySupport.getResource(i));
2560 procedure.execute(impl.newRestart(graph), querySupport.getResource(i));
2562 } catch (Throwable t2) {
2563 Logger.defaultLogError(t2);
2569 public void finished(ReadGraphImpl graph) {
2571 if(first.compareAndSet(true, false)) {
2572 procedure.finished(impl);
2573 // impl.state.barrier.dec(this);
2575 procedure.finished(impl.newRestart(graph));
2577 } catch (Throwable t2) {
2578 Logger.defaultLogError(t2);
2583 public void exception(ReadGraphImpl graph, Throwable t) {
2585 procedure.exception(graph, t);
2586 } catch (Throwable t2) {
2587 Logger.defaultLogError(t2);
2589 // impl.state.barrier.dec(this);
2593 public String toString() {
2594 return "forEachObject with " + procedure;
2599 // if(AsyncBarrierImpl.BOOKKEEPING) impl.state.barrier.inc(ip, "#Objects" + subject + "#" + predicate);
2600 // else impl.state.barrier.inc(null, null);
2602 forEachObject(impl, subject, predicate, listener, ip);
2606 IntProcedure ip = new IntProcedure() {
2609 public void execute(ReadGraphImpl graph, int i) {
2610 procedure.execute(graph, querySupport.getResource(i));
2614 public void finished(ReadGraphImpl graph) {
2615 procedure.finished(graph);
2619 public void exception(ReadGraphImpl graph, Throwable t) {
2620 procedure.exception(graph, t);
2624 public String toString() {
2625 return "forEachObject with " + procedure;
2630 forEachObject(impl, subject, predicate, listener, ip);
2637 final public void forObjectSet(final ReadGraphImpl impl, final Resource subject, final Resource predicate, final AsyncSetListener<Resource> procedure) {
2639 assert(subject != null);
2640 assert(predicate != null);
2641 assert(procedure != null);
2643 forEachObject(impl, subject, predicate, new AsyncMultiListener<Resource>() {
2645 private Set<Resource> current = null;
2646 private Set<Resource> run = new HashSet<Resource>();
2649 public void execute(AsyncReadGraph graph, Resource result) {
2651 boolean found = false;
2653 if(current != null) {
2655 found = current.remove(result);
2659 if(!found) procedure.add(graph, result);
2666 public void finished(AsyncReadGraph graph) {
2668 if(current != null) {
2669 for(Resource r : current) procedure.remove(graph, r);
2674 run = new HashSet<Resource>();
2679 public boolean isDisposed() {
2680 return procedure.isDisposed();
2684 public void exception(AsyncReadGraph graph, Throwable t) {
2685 procedure.exception(graph, t);
2689 public String toString() {
2690 return "forObjectSet " + procedure;
2698 final public void forPredicateSet(final ReadGraphImpl impl, final Resource subject, final AsyncSetListener<Resource> procedure) {
2700 assert(subject != null);
2701 assert(procedure != null);
2703 forEachPredicate(impl, subject, new AsyncMultiListener<Resource>() {
2705 private Set<Resource> current = null;
2706 private Set<Resource> run = new HashSet<Resource>();
2709 public void execute(AsyncReadGraph graph, Resource result) {
2711 boolean found = false;
2713 if(current != null) {
2715 found = current.remove(result);
2719 if(!found) procedure.add(graph, result);
2726 public void finished(AsyncReadGraph graph) {
2728 if(current != null) {
2729 for(Resource r : current) procedure.remove(graph, r);
2734 run = new HashSet<Resource>();
2739 public boolean isDisposed() {
2740 return procedure.isDisposed();
2744 public void exception(AsyncReadGraph graph, Throwable t) {
2745 procedure.exception(graph, t);
2749 public String toString() {
2750 return "forPredicateSet " + procedure;
2758 final public void forPrincipalTypeSet(final ReadGraphImpl impl, final Resource subject, final AsyncSetListener<Resource> procedure) {
2760 assert(subject != null);
2761 assert(procedure != null);
2763 forEachPrincipalType(impl, subject, new AsyncMultiListener<Resource>() {
2765 private Set<Resource> current = null;
2766 private Set<Resource> run = new HashSet<Resource>();
2769 public void execute(AsyncReadGraph graph, Resource result) {
2771 boolean found = false;
2773 if(current != null) {
2775 found = current.remove(result);
2779 if(!found) procedure.add(graph, result);
2786 public void finished(AsyncReadGraph graph) {
2788 if(current != null) {
2789 for(Resource r : current) procedure.remove(graph, r);
2794 run = new HashSet<Resource>();
2799 public boolean isDisposed() {
2800 return procedure.isDisposed();
2804 public void exception(AsyncReadGraph graph, Throwable t) {
2805 procedure.exception(graph, t);
2809 public String toString() {
2810 return "forPrincipalTypeSet " + procedure;
2818 final public void forAssertedObjectSet(final ReadGraphImpl impl, final Resource subject, final Resource predicate, final AsyncSetListener<Resource> procedure) {
2820 assert(subject != null);
2821 assert(predicate != null);
2822 assert(procedure != null);
2824 forEachAssertedObject(impl, subject, predicate, new AsyncMultiListener<Resource>() {
2826 private Set<Resource> current = null;
2827 private Set<Resource> run = new HashSet<Resource>();
2830 public void execute(AsyncReadGraph graph, Resource result) {
2832 boolean found = false;
2834 if(current != null) {
2836 found = current.remove(result);
2840 if(!found) procedure.add(graph, result);
2847 public void finished(AsyncReadGraph graph) {
2849 if(current != null) {
2850 for(Resource r : current) procedure.remove(graph, r);
2855 run = new HashSet<Resource>();
2860 public boolean isDisposed() {
2861 return procedure.isDisposed();
2865 public void exception(AsyncReadGraph graph, Throwable t) {
2866 procedure.exception(graph, t);
2870 public String toString() {
2871 return "forObjectSet " + procedure;
2879 final public void forAssertedStatementSet(final ReadGraphImpl impl, final Resource subject, final Resource predicate, final AsyncSetListener<Statement> procedure) {
2881 assert(subject != null);
2882 assert(predicate != null);
2883 assert(procedure != null);
2885 forEachAssertedStatement(impl, subject, predicate, new AsyncMultiListener<Statement>() {
2887 private Set<Statement> current = null;
2888 private Set<Statement> run = new HashSet<Statement>();
2891 public void execute(AsyncReadGraph graph, Statement result) {
2893 boolean found = false;
2895 if(current != null) {
2897 found = current.remove(result);
2901 if(!found) procedure.add(graph, result);
2908 public void finished(AsyncReadGraph graph) {
2910 if(current != null) {
2911 for(Statement s : current) procedure.remove(graph, s);
2916 run = new HashSet<Statement>();
2921 public boolean isDisposed() {
2922 return procedure.isDisposed();
2926 public void exception(AsyncReadGraph graph, Throwable t) {
2927 procedure.exception(graph, t);
2931 public String toString() {
2932 return "forStatementSet " + procedure;
2940 final public void forEachAssertedObject(final ReadGraphImpl impl, final Resource subject,
2941 final Resource predicate, final AsyncMultiProcedure<Resource> procedure) {
2943 assert(subject != null);
2944 assert(predicate != null);
2945 assert(procedure != null);
2947 final ListenerBase listener = getListenerBase(procedure);
2950 QueryCache.runnerAssertedStatements(impl, querySupport.getId(subject), querySupport.getId(predicate), impl.parent, listener, new TripleIntProcedure() {
2953 public void execute(ReadGraphImpl graph, int s, int p, int o) {
2955 procedure.execute(graph, querySupport.getResource(o));
2956 } catch (Throwable t2) {
2957 Logger.defaultLogError(t2);
2962 public void finished(ReadGraphImpl graph) {
2964 procedure.finished(graph);
2965 } catch (Throwable t2) {
2966 Logger.defaultLogError(t2);
2968 // impl.state.barrier.dec();
2972 public void exception(ReadGraphImpl graph, Throwable t) {
2974 procedure.exception(graph, t);
2975 } catch (Throwable t2) {
2976 Logger.defaultLogError(t2);
2978 // impl.state.barrier.dec();
2982 } catch (DatabaseException e) {
2983 Logger.defaultLogError(e);
2989 final public void forEachPrincipalType(final ReadGraphImpl impl, final Resource subject, final AsyncMultiProcedure<Resource> procedure) {
2991 assert(subject != null);
2992 assert(procedure != null);
2994 final ListenerBase listener = getListenerBase(procedure);
2996 IntProcedure ip = new IntProcedure() {
2999 public void execute(ReadGraphImpl graph, int i) {
3001 procedure.execute(graph, querySupport.getResource(i));
3002 } catch (Throwable t2) {
3003 Logger.defaultLogError(t2);
3008 public void finished(ReadGraphImpl graph) {
3010 procedure.finished(graph);
3011 } catch (Throwable t2) {
3012 Logger.defaultLogError(t2);
3014 // impl.state.barrier.dec(this);
3018 public void exception(ReadGraphImpl graph, Throwable t) {
3020 procedure.exception(graph, t);
3021 } catch (Throwable t2) {
3022 Logger.defaultLogError(t2);
3024 // impl.state.barrier.dec(this);
3029 int sId = querySupport.getId(subject);
3031 // if(AsyncBarrierImpl.BOOKKEEPING) impl.state.barrier.inc(ip, "#PrincipalTypes#" + sId);
3032 // else impl.state.barrier.inc(null, null);
3035 QueryCache.runnerPrincipalTypes(impl, sId, impl.parent, listener, ip);
3036 } catch (DatabaseException e) {
3037 Logger.defaultLogError(e);
3043 final public void forEachPrincipalType(final ReadGraphImpl impl, final Resource subject, final MultiProcedure<Resource> procedure) {
3045 assert(subject != null);
3046 assert(procedure != null);
3048 final ListenerBase listener = getListenerBase(procedure);
3050 // impl.state.barrier.inc();
3053 QueryCache.runnerPrincipalTypes(impl, querySupport.getId(subject), impl.parent, listener, new IntProcedure() {
3056 public void execute(ReadGraphImpl graph, int i) {
3058 procedure.execute(querySupport.getResource(i));
3059 } catch (Throwable t2) {
3060 Logger.defaultLogError(t2);
3065 public void finished(ReadGraphImpl graph) {
3067 procedure.finished();
3068 } catch (Throwable t2) {
3069 Logger.defaultLogError(t2);
3071 // impl.state.barrier.dec();
3075 public void exception(ReadGraphImpl graph, Throwable t) {
3077 procedure.exception(t);
3078 } catch (Throwable t2) {
3079 Logger.defaultLogError(t2);
3081 // impl.state.barrier.dec();
3085 } catch (DatabaseException e) {
3086 Logger.defaultLogError(e);
3090 final public void forTypes(final ReadGraphImpl impl, final Resource subject, final AsyncProcedure<Set<Resource>> procedure) {
3092 assert(subject != null);
3093 assert(procedure != null);
3095 final ListenerBase listener = getListenerBase(procedure);
3096 assert(listener == null);
3098 InternalProcedure<IntSet> ip = new InternalProcedure<IntSet>() {
3101 public void execute(final ReadGraphImpl graph, IntSet set) {
3102 procedure.execute(graph, set);
3106 public void exception(ReadGraphImpl graph, Throwable t) {
3107 procedure.exception(graph, t);
3112 int sId = querySupport.getId(subject);
3115 QueryCache.runnerTypes(impl, sId, impl.parent, listener, ip);
3116 } catch (DatabaseException e) {
3117 Logger.defaultLogError(e);
3123 final public IntSet getTypes(final ReadGraphImpl impl, final Resource subject) throws Throwable {
3125 assert(subject != null);
3127 return QueryCacheBase.resultTypes(impl, querySupport.getId(subject), impl.parent, null);
3132 final public RelationInfo getRelationInfo(final ReadGraphImpl impl, final Resource subject) throws DatabaseException {
3134 assert(subject != null);
3136 return QueryCache.resultRelationInfoQuery(impl, querySupport.getId(subject), impl.parent, null);
3141 final public void forSupertypes(final ReadGraphImpl impl, final Resource subject, final AsyncProcedure<Set<Resource>> procedure) {
3143 assert(subject != null);
3144 assert(procedure != null);
3146 final ListenerBase listener = getListenerBase(procedure);
3149 QueryCache.runnerSuperTypes(impl, querySupport.getId(subject), impl.parent, listener, new InternalProcedure<IntSet>() {
3151 AtomicBoolean first = new AtomicBoolean(true);
3154 public void execute(final ReadGraphImpl graph, IntSet set) {
3155 // final HashSet<Resource> result = new HashSet<Resource>();
3156 // set.forEach(new TIntProcedure() {
3159 // public boolean execute(int type) {
3160 // result.add(querySupport.getResource(type));
3166 if(first.compareAndSet(true, false)) {
3167 procedure.execute(graph, set);
3168 // impl.state.barrier.dec();
3170 procedure.execute(impl.newRestart(graph), set);
3172 } catch (Throwable t2) {
3173 Logger.defaultLogError(t2);
3178 public void exception(ReadGraphImpl graph, Throwable t) {
3180 if(first.compareAndSet(true, false)) {
3181 procedure.exception(graph, t);
3182 // impl.state.barrier.dec();
3184 procedure.exception(impl.newRestart(graph), t);
3186 } catch (Throwable t2) {
3187 Logger.defaultLogError(t2);
3192 } catch (DatabaseException e) {
3193 Logger.defaultLogError(e);
3199 final public void forDirectSuperrelations(final ReadGraphImpl impl, final Resource subject, final AsyncMultiProcedure<Resource> procedure) {
3201 assert(subject != null);
3202 assert(procedure != null);
3204 final ListenerBase listener = getListenerBase(procedure);
3206 IntProcedure ip = new IntProcedureAdapter() {
3209 public void execute(final ReadGraphImpl graph, int superRelation) {
3211 procedure.execute(graph, querySupport.getResource(superRelation));
3212 } catch (Throwable t2) {
3213 Logger.defaultLogError(t2);
3218 public void finished(final ReadGraphImpl graph) {
3220 procedure.finished(graph);
3221 } catch (Throwable t2) {
3222 Logger.defaultLogError(t2);
3224 // impl.state.barrier.dec(this);
3229 public void exception(ReadGraphImpl graph, Throwable t) {
3231 procedure.exception(graph, t);
3232 } catch (Throwable t2) {
3233 Logger.defaultLogError(t2);
3235 // impl.state.barrier.dec(this);
3240 int sId = querySupport.getId(subject);
3242 // if(AsyncBarrierImpl.BOOKKEEPING) impl.state.barrier.inc(ip, "#DirectSuperRelations#" + sId);
3243 // else impl.state.barrier.inc(null, null);
3246 QueryCache.runnerDirectSuperRelations(impl, sId, impl.parent, listener, ip);
3247 } catch (DatabaseException e) {
3248 Logger.defaultLogError(e);
3251 // DirectSuperRelations.queryEach(impl, sId, this, impl.parent, listener, ip);
3256 final public void forPossibleSuperrelation(final ReadGraphImpl impl, final Resource subject, final AsyncProcedure<Resource> procedure) {
3258 assert(subject != null);
3259 assert(procedure != null);
3261 final ListenerBase listener = getListenerBase(procedure);
3263 // impl.state.barrier.inc();
3265 PossibleSuperRelation.queryEach(impl, querySupport.getId(subject), this, impl.parent, listener, procedure);
3270 final public void forSuperrelations(final ReadGraphImpl impl, final Resource subject, final AsyncProcedure<Set<Resource>> procedure) {
3272 assert(subject != null);
3273 assert(procedure != null);
3275 final ListenerBase listener = getListenerBase(procedure);
3277 InternalProcedure<IntSet> ip = new InternalProcedure<IntSet>() {
3280 public void execute(final ReadGraphImpl graph, IntSet set) {
3281 // final HashSet<Resource> result = new HashSet<Resource>();
3282 // set.forEach(new TIntProcedure() {
3285 // public boolean execute(int type) {
3286 // result.add(querySupport.getResource(type));
3292 procedure.execute(graph, set);
3293 } catch (Throwable t2) {
3294 Logger.defaultLogError(t2);
3296 // impl.state.barrier.dec(this);
3300 public void exception(ReadGraphImpl graph, Throwable t) {
3302 procedure.exception(graph, t);
3303 } catch (Throwable t2) {
3304 Logger.defaultLogError(t2);
3306 // impl.state.barrier.dec(this);
3311 int sId = querySupport.getId(subject);
3313 // if(AsyncBarrierImpl.BOOKKEEPING) impl.state.barrier.inc(ip, "#SuperRelations#" + sId);
3314 // else impl.state.barrier.inc(null, null);
3317 QueryCache.runnerSuperRelations(impl, sId, impl.parent, listener, ip);
3318 } catch (DatabaseException e) {
3319 Logger.defaultLogError(e);
3324 final public byte[] getValue(final ReadGraphImpl impl, final Resource subject) throws DatabaseException {
3325 return getValue(impl, querySupport.getId(subject));
3328 final public byte[] getValue(final ReadGraphImpl impl, final int subject) throws DatabaseException {
3329 return QueryCache.resultValueQuery(impl, subject, impl.parent, null);
3333 final public void forValue(final ReadGraphImpl impl, final Resource subject, final AsyncProcedure<byte[]> procedure) {
3335 assert(subject != null);
3336 assert(procedure != null);
3338 int sId = querySupport.getId(subject);
3340 // if(procedure != null) {
3342 final ListenerBase listener = getListenerBase(procedure);
3344 InternalProcedure<byte[]> ip = new InternalProcedure<byte[]>() {
3346 AtomicBoolean first = new AtomicBoolean(true);
3349 public void execute(ReadGraphImpl graph, byte[] result) {
3351 if(first.compareAndSet(true, false)) {
3352 procedure.execute(graph, result);
3353 // impl.state.barrier.dec(this);
3355 procedure.execute(impl.newRestart(graph), result);
3357 } catch (Throwable t2) {
3358 Logger.defaultLogError(t2);
3363 public void exception(ReadGraphImpl graph, Throwable t) {
3365 if(first.compareAndSet(true, false)) {
3366 procedure.exception(graph, t);
3367 // impl.state.barrier.dec(this);
3369 procedure.exception(impl.newRestart(graph), t);
3371 } catch (Throwable t2) {
3372 Logger.defaultLogError(t2);
3378 // if(AsyncBarrierImpl.BOOKKEEPING) impl.state.barrier.inc(ip, "#Value" + sId);
3379 // else impl.state.barrier.inc(null, null);
3382 QueryCache.runnerValueQuery(impl, sId, impl.parent, listener, ip);
3383 } catch (DatabaseException e) {
3384 throw new IllegalStateException("Internal error");
3389 // return QueryCacheBase.runnerValueQuery(impl, sId, impl.parent, null, null);
3393 // throw new IllegalStateException("Internal error");
3398 final public void forPossibleValue(final ReadGraphImpl impl, final Resource subject, final AsyncProcedure<byte[]> procedure) {
3400 assert(subject != null);
3401 assert(procedure != null);
3403 final ListenerBase listener = getListenerBase(procedure);
3405 if(impl.parent != null || listener != null) {
3407 InternalProcedure<byte[]> ip = new InternalProcedure<byte[]>() {
3409 AtomicBoolean first = new AtomicBoolean(true);
3412 public void execute(ReadGraphImpl graph, byte[] result) {
3414 if(first.compareAndSet(true, false)) {
3415 procedure.execute(graph, result);
3416 // impl.state.barrier.dec(this);
3418 procedure.execute(impl.newRestart(graph), result);
3420 } catch (Throwable t2) {
3421 Logger.defaultLogError(t2);
3426 public void exception(ReadGraphImpl graph, Throwable t) {
3428 if(first.compareAndSet(true, false)) {
3429 procedure.exception(graph, t);
3430 // impl.state.barrier.dec(this);
3432 procedure.exception(impl.newRestart(graph), t);
3434 } catch (Throwable t2) {
3435 Logger.defaultLogError(t2);
3441 int sId = querySupport.getId(subject);
3443 // if(AsyncBarrierImpl.BOOKKEEPING) impl.state.barrier.inc(ip, "#Value" + sId);
3444 // else impl.state.barrier.inc(null, null);
3447 QueryCache.runnerValueQuery(impl, sId, impl.parent, listener, ip);
3448 } catch (DatabaseException e) {
3449 Logger.defaultLogError(e);
3454 InternalProcedure<byte[]> ip = new InternalProcedure<byte[]>() {
3457 public void execute(ReadGraphImpl graph, byte[] result) {
3459 procedure.execute(graph, result);
3464 public void exception(ReadGraphImpl graph, Throwable t) {
3466 procedure.exception(graph, t);
3472 int sId = querySupport.getId(subject);
3475 QueryCache.runnerValueQuery(impl, sId, impl.parent, listener, ip);
3476 } catch (DatabaseException e) {
3477 Logger.defaultLogError(e);
3485 final public void forInverse(final ReadGraphImpl impl, final Resource relation, final AsyncProcedure<Resource> procedure) {
3487 assert(relation != null);
3488 assert(procedure != null);
3490 final ListenerBase listener = getListenerBase(procedure);
3492 IntProcedure ip = new IntProcedure() {
3494 private int result = 0;
3496 final AtomicBoolean found = new AtomicBoolean(false);
3497 final AtomicBoolean done = new AtomicBoolean(false);
3500 public void finished(ReadGraphImpl graph) {
3502 // Shall fire exactly once!
3503 if(done.compareAndSet(false, true)) {
3506 procedure.exception(graph, new NoInverseException(""));
3507 // impl.state.barrier.dec(this);
3509 procedure.execute(graph, querySupport.getResource(result));
3510 // impl.state.barrier.dec(this);
3512 } catch (Throwable t) {
3513 Logger.defaultLogError(t);
3520 public void execute(ReadGraphImpl graph, int i) {
3522 if(found.compareAndSet(false, true)) {
3525 // Shall fire exactly once!
3526 if(done.compareAndSet(false, true)) {
3528 procedure.exception(graph, new ManyObjectsForFunctionalRelationException("Multiple items e.g. " + this.result + " and " + result));
3529 // impl.state.barrier.dec(this);
3530 } catch (Throwable t) {
3531 Logger.defaultLogError(t);
3539 public void exception(ReadGraphImpl graph, Throwable t) {
3540 // Shall fire exactly once!
3541 if(done.compareAndSet(false, true)) {
3543 procedure.exception(graph, t);
3544 // impl.state.barrier.dec(this);
3545 } catch (Throwable t2) {
3546 Logger.defaultLogError(t2);
3553 int sId = querySupport.getId(relation);
3555 // if(AsyncBarrierImpl.BOOKKEEPING) impl.state.barrier.inc(ip, "#DirectObjects#" + sId);
3556 // else impl.state.barrier.inc(null, null);
3559 QueryCache.runnerObjects(impl, sId, getInverseOf(), impl.parent, listener, ip);
3560 } catch (DatabaseException e) {
3561 Logger.defaultLogError(e);
3567 final public void forResource(final ReadGraphImpl impl, final String id, final AsyncProcedure<Resource> procedure) {
3570 assert(procedure != null);
3572 InternalProcedure<Integer> ip = new InternalProcedure<Integer>() {
3575 public void execute(ReadGraphImpl graph, Integer result) {
3577 procedure.execute(graph, querySupport.getResource(result));
3578 } catch (Throwable t2) {
3579 Logger.defaultLogError(t2);
3581 // impl.state.barrier.dec(this);
3585 public void exception(ReadGraphImpl graph, Throwable t) {
3588 procedure.exception(graph, t);
3589 } catch (Throwable t2) {
3590 Logger.defaultLogError(t2);
3592 // impl.state.barrier.dec(this);
3597 // if(AsyncBarrierImpl.BOOKKEEPING) impl.state.barrier.inc(ip, "Resource");
3598 // else impl.state.barrier.inc(null, null);
3600 forResource(impl, id, impl.parent, ip);
3605 final public void forBuiltin(final ReadGraphImpl impl, final String id, final AsyncProcedure<Resource> procedure) {
3608 assert(procedure != null);
3610 // impl.state.barrier.inc();
3613 forBuiltin(impl, id, impl.parent, new InternalProcedure<Integer>() {
3616 public void execute(ReadGraphImpl graph, Integer result) {
3618 procedure.execute(graph, querySupport.getResource(result));
3619 } catch (Throwable t2) {
3620 Logger.defaultLogError(t2);
3622 // impl.state.barrier.dec();
3626 public void exception(ReadGraphImpl graph, Throwable t) {
3628 procedure.exception(graph, t);
3629 } catch (Throwable t2) {
3630 Logger.defaultLogError(t2);
3632 // impl.state.barrier.dec();
3636 } catch (DatabaseException e) {
3637 Logger.defaultLogError(e);
3643 final public void forHasStatement(final ReadGraphImpl impl, final Resource subject, final AsyncProcedure<Boolean> procedure) {
3645 assert(subject != null);
3646 assert(procedure != null);
3648 final ListenerBase listener = getListenerBase(procedure);
3651 IntSet result = QueryCache.resultDirectPredicates(impl, querySupport.getId(subject), impl.parent, listener);
3652 procedure.execute(impl, !result.isEmpty());
3653 } catch (DatabaseException e) {
3654 procedure.exception(impl, e);
3660 final public void forHasStatement(final ReadGraphImpl impl, final Resource subject, final Resource predicate, final AsyncProcedure<Boolean> procedure) {
3662 assert(subject != null);
3663 assert(predicate != null);
3664 assert(procedure != null);
3666 AsyncMultiProcedure<Resource> ip = new AsyncMultiProcedureAdapter<Resource>() {
3668 boolean found = false;
3671 synchronized public void execute(AsyncReadGraph graph, Resource resource) {
3676 synchronized public void finished(AsyncReadGraph graph) {
3678 procedure.execute(graph, found);
3679 } catch (Throwable t2) {
3680 Logger.defaultLogError(t2);
3682 // impl.state.barrier.dec(this);
3686 public void exception(AsyncReadGraph graph, Throwable t) {
3688 procedure.exception(graph, t);
3689 } catch (Throwable t2) {
3690 Logger.defaultLogError(t2);
3692 // impl.state.barrier.dec(this);
3697 // if(AsyncBarrierImpl.BOOKKEEPING) impl.state.barrier.inc(ip, "#ForEachObject#" + subject + "#" + predicate);
3698 // else impl.state.barrier.inc(null, null);
3700 forEachObject(impl, subject, predicate, ip);
3705 final public void forHasStatement(final ReadGraphImpl impl, final Resource subject, final Resource predicate, final Resource object, final AsyncProcedure<Boolean> procedure) {
3707 assert(subject != null);
3708 assert(predicate != null);
3709 assert(procedure != null);
3711 // impl.state.barrier.inc();
3713 forEachObject(impl, subject, predicate, new AsyncMultiProcedureAdapter<Resource>() {
3715 boolean found = false;
3718 synchronized public void execute(AsyncReadGraph graph, Resource resource) {
3719 if(resource.equals(object)) found = true;
3723 synchronized public void finished(AsyncReadGraph graph) {
3725 procedure.execute(graph, found);
3726 } catch (Throwable t2) {
3727 Logger.defaultLogError(t2);
3729 // impl.state.barrier.dec();
3733 public void exception(AsyncReadGraph graph, Throwable t) {
3735 procedure.exception(graph, t);
3736 } catch (Throwable t2) {
3737 Logger.defaultLogError(t2);
3739 // impl.state.barrier.dec();
3747 final public void forHasValue(final ReadGraphImpl impl, final Resource subject, final AsyncProcedure<Boolean> procedure) {
3749 assert(subject != null);
3750 assert(procedure != null);
3752 final ListenerBase listener = getListenerBase(procedure);
3754 // impl.state.barrier.inc();
3757 QueryCache.runnerValueQuery(impl, querySupport.getId(subject), impl.parent, listener, new InternalProcedure<byte[]>() {
3760 public void execute(ReadGraphImpl graph, byte[] object) {
3761 boolean result = object != null;
3763 procedure.execute(graph, result);
3764 } catch (Throwable t2) {
3765 Logger.defaultLogError(t2);
3767 // impl.state.barrier.dec();
3771 public void exception(ReadGraphImpl graph, Throwable t) {
3773 procedure.exception(graph, t);
3774 } catch (Throwable t2) {
3775 Logger.defaultLogError(t2);
3777 // impl.state.barrier.dec();
3781 } catch (DatabaseException e) {
3782 Logger.defaultLogError(e);
3788 final public void forOrderedSet(final ReadGraphImpl impl, final Resource subject, final AsyncMultiProcedure<Resource> procedure) {
3790 assert(subject != null);
3791 assert(procedure != null);
3793 final ListenerBase listener = getListenerBase(procedure);
3797 QueryCache.runnerOrderedSet(impl, querySupport.getId(subject), impl.parent, listener, new IntProcedure() {
3800 public void exception(ReadGraphImpl graph, Throwable t) {
3802 procedure.exception(graph, t);
3803 } catch (Throwable t2) {
3804 Logger.defaultLogError(t2);
3806 // impl.state.barrier.dec();
3810 public void execute(ReadGraphImpl graph, int i) {
3812 procedure.execute(graph, querySupport.getResource(i));
3813 } catch (Throwable t2) {
3814 Logger.defaultLogError(t2);
3819 public void finished(ReadGraphImpl graph) {
3821 procedure.finished(graph);
3822 } catch (Throwable t2) {
3823 Logger.defaultLogError(t2);
3825 // impl.state.barrier.dec();
3829 } catch (DatabaseException e) {
3830 Logger.defaultLogError(e);
3836 // final public <T> void query(final ReadGraphImpl impl, final AsyncRead<T> request, final CacheEntry parent, final AsyncProcedure<T> procedure, ListenerBase listener) throws DatabaseException {
3838 // assert(request != null);
3839 // assert(procedure != null);
3841 // QueryCache.runnerAsyncReadEntry(impl, request, parent, listener, procedure);
3846 // final public <T> T tryQuery(final ReadGraphImpl graph, final Read<T> request) throws DatabaseException {
3848 // assert(graph != null);
3849 // assert(request != null);
3851 // final ReadEntry entry = (ReadEntry)cache.getCached(request);
3852 // if(entry != null && entry.isReady()) {
3853 // return (T)entry.get(graph, this, null);
3855 // return request.perform(graph);
3860 // final public <T> T tryQuery(final ReadGraphImpl graph, final ExternalRead<T> request) throws DatabaseException {
3862 // assert(graph != null);
3863 // assert(request != null);
3865 // final ExternalReadEntry<T> entry = cache.externalReadMap.get(request);
3866 // if(entry != null && entry.isReady()) {
3867 // if(entry.isExcepted()) {
3868 // Throwable t = (Throwable)entry.getResult();
3869 // if(t instanceof DatabaseException) throw (DatabaseException)t;
3870 // else throw new DatabaseException(t);
3872 // return (T)entry.getResult();
3876 // final DataContainer<T> result = new DataContainer<T>();
3877 // final DataContainer<Throwable> exception = new DataContainer<Throwable>();
3879 // request.register(graph, new Listener<T>() {
3882 // public void exception(Throwable t) {
3883 // exception.set(t);
3887 // public void execute(T t) {
3892 // public boolean isDisposed() {
3898 // Throwable t = exception.get();
3900 // if(t instanceof DatabaseException) throw (DatabaseException)t;
3901 // else throw new DatabaseException(t);
3904 // return result.get();
3911 // final public <T> void tryQuery(final ReadGraphImpl graph, final AsyncRead<T> request, AsyncProcedure<T> procedure) {
3913 // assert(graph != null);
3914 // assert(request != null);
3916 // final AsyncReadEntry entry = cache.asyncReadMap.get(request);
3917 // if(entry != null && entry.isReady()) {
3918 // if(entry.isExcepted()) {
3919 // procedure.exception(graph, (Throwable)entry.getResult());
3921 // procedure.execute(graph, (T)entry.getResult());
3924 // request.perform(graph, procedure);
3930 final public <T> void query(final ReadGraphImpl impl, final MultiRead<T> request, final CacheEntry parent, final SyncMultiProcedure<T> procedure, ListenerBase listener) {
3932 assert(request != null);
3933 assert(procedure != null);
3937 queryMultiRead(impl, request, parent, listener, procedure);
3939 } catch (DatabaseException e) {
3941 throw new IllegalStateException(e);
3948 final public <T> void query(final ReadGraphImpl impl, final AsyncMultiRead<T> request, final CacheEntry parent, final AsyncMultiProcedure<T> procedure, ListenerBase listener) {
3950 assert(request != null);
3951 assert(procedure != null);
3953 // impl.state.barrier.inc();
3955 runAsyncMultiRead(impl, request, parent, listener, new AsyncMultiProcedure<T>() {
3957 public void execute(AsyncReadGraph graph, T result) {
3960 procedure.execute(graph, result);
3961 } catch (Throwable t2) {
3962 Logger.defaultLogError(t2);
3967 public void finished(AsyncReadGraph graph) {
3970 procedure.finished(graph);
3971 } catch (Throwable t2) {
3972 Logger.defaultLogError(t2);
3975 // impl.state.barrier.dec();
3980 public String toString() {
3981 return procedure.toString();
3985 public void exception(AsyncReadGraph graph, Throwable t) {
3988 procedure.exception(graph, t);
3989 } catch (Throwable t2) {
3990 Logger.defaultLogError(t2);
3993 // impl.state.barrier.dec();
4002 // final public <T> void query(final ReadGraphImpl impl, final ExternalRead<T> request, final CacheEntry parent, final Procedure<T> procedure, ListenerBase listener) throws DatabaseException {
4004 // assert(request != null);
4005 // assert(procedure != null);
4009 // queryPrimitiveRead(impl, request, parent, listener, new AsyncProcedure<T>() {
4012 // public String toString() {
4013 // return procedure.toString();
4017 // public void execute(AsyncReadGraph graph, T result) {
4019 // procedure.execute(result);
4020 // } catch (Throwable t2) {
4021 // Logger.defaultLogError(t2);
4026 // public void exception(AsyncReadGraph graph, Throwable throwable) {
4028 // procedure.exception(throwable);
4029 // } catch (Throwable t2) {
4030 // Logger.defaultLogError(t2);
4036 // } catch (DatabaseException e) {
4038 // throw new IllegalStateException(e);
4045 public VirtualGraph getProvider(Resource subject, Resource predicate, Resource object) {
4047 return querySupport.getProvider(querySupport.getId(subject), querySupport.getId(predicate), querySupport.getId(object));
4052 public VirtualGraph getProvider(Resource subject, Resource predicate) {
4054 return querySupport.getProvider(querySupport.getId(subject), querySupport.getId(predicate));
4059 public VirtualGraph getValueProvider(Resource subject) {
4061 return querySupport.getValueProvider(querySupport.getId(subject));
4065 public boolean resumeTasks(ReadGraphImpl graph) {
4067 return querySupport.resume(graph);
4071 public boolean isImmutable(int resourceId) {
4072 return querySupport.isImmutable(resourceId);
4075 public boolean isImmutable(Resource resource) {
4076 ResourceImpl impl = (ResourceImpl)resource;
4077 return isImmutable(impl.id);
4082 public Layer0 getL0(ReadGraph graph) {
4084 L0 = Layer0.getInstance(graph);
4089 public static ThreadLocal<Integer> thread = new ThreadLocal<Integer>() {
4090 protected Integer initialValue() {