--- /dev/null
+package org.simantics.db.impl.query;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.simantics.db.AsyncReadGraph;
+import org.simantics.db.ObjectResourceIdMap;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.RelationInfo;
+import org.simantics.db.common.utils.Logger;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.impl.DebugPolicy;
+import org.simantics.db.impl.graph.ReadGraphImpl;
+import org.simantics.db.impl.procedure.InternalProcedure;
+import org.simantics.db.impl.query.QueryProcessor.SessionTask;
+import org.simantics.db.procedure.AsyncMultiProcedure;
+import org.simantics.db.procedure.AsyncProcedure;
+import org.simantics.db.procedure.Listener;
+import org.simantics.db.procedure.ListenerBase;
+import org.simantics.db.procedure.Procedure;
+import org.simantics.db.procedure.SyncMultiProcedure;
+import org.simantics.db.request.AsyncMultiRead;
+import org.simantics.db.request.AsyncRead;
+import org.simantics.db.request.ExternalRead;
+import org.simantics.db.request.MultiRead;
+import org.simantics.db.request.Read;
+
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.map.hash.TObjectIntHashMap;
+
+public class QueryCacheBase {
+
+ // Statistics
+ final int THREADS;
+ public final int THREAD_MASK;
+ int hits = 0;
+ int misses = 0;
+ int updates = 0;
+ public int size = 0;
+
+ public volatile boolean dirty = false;
+ public boolean collecting = false;
+
+ protected final THashMap<String, URIToResource> uRIToResourceMap;
+ //protected final THashMap<String, NamespaceIndex> namespaceIndexMap;
+ protected final UnaryQueryHashMap<InternalProcedure<ObjectResourceIdMap<String>>> childMapMap;
+ protected final DoubleKeyQueryHashMap<IntProcedure> objectsMap;
+ protected final DoubleKeyQueryHashMap<TripleIntProcedure> assertedStatementsMap;
+ protected final DoubleKeyQueryHashMap<IntProcedure> directObjectsMap;
+ protected final DoubleKeyQueryHashMap<TripleIntProcedure> statementsMap;
+ protected final UnaryQueryHashMap<InternalProcedure<IntSet>> typesMap;
+ protected final UnaryQueryHashMap<IntProcedure> principalTypesMap;
+ protected final UnaryQueryHashMap<InternalProcedure<IntSet>> predicatesMap;
+ protected final UnaryQueryHashMap<InternalProcedure<IntSet>> superTypesMap;
+ protected final UnaryQueryHashMap<InternalProcedure<IntSet>> typeHierarchyMap;
+ protected final UnaryQueryHashMap<InternalProcedure<IntSet>> superRelationsMap;
+
+ protected final UnaryQueryHashMap<IntProcedure> orderedSetMap;
+ protected final UnaryQueryHashMap<IntProcedure> assertedPredicatesMap;
+ protected final UnaryQueryHashMap<InternalProcedure<IntSet>> directPredicatesMap;
+ protected final UnaryQueryHashMap<IntProcedure> directSuperRelationsMap;
+
+ protected final UnaryQueryHashMap<InternalProcedure<RelationInfo>> relationInfoQueryMap;
+ protected final UnaryQueryHashMap<InternalProcedure<byte[]>> valueQueryMap;
+
+ protected final StableHashMap<AsyncRead, AsyncReadEntry> asyncReadEntryMap;
+ protected final StableHashMap<Read, ReadEntry> readEntryMap;
+ protected final StableHashMap<MultiRead, MultiReadEntry> multiReadEntryMap;
+ protected final StableHashMap<AsyncMultiRead, AsyncMultiReadEntry> asyncMultiReadEntryMap;
+ protected final StableHashMap<ExternalRead, ExternalReadEntry> externalReadEntryMap;
+
+ final THashMap<CacheEntry, ArrayList<ListenerEntry>> listeners;
+
+ public final QuerySupport querySupport;
+
+ public QueryCacheBase(QuerySupport querySupport, int threads) {
+
+ THREADS = threads;
+ THREAD_MASK = threads - 1;
+
+ this.querySupport = querySupport;
+ directPredicatesMap = new UnaryQueryHashMap();
+ directSuperRelationsMap = new UnaryQueryHashMap();
+ valueQueryMap = new UnaryQueryHashMap();
+ principalTypesMap = new UnaryQueryHashMap();
+ uRIToResourceMap = new THashMap<String, URIToResource>();
+ //namespaceIndexMap = new THashMap<String, NamespaceIndex>();
+ childMapMap = new UnaryQueryHashMap<InternalProcedure<ObjectResourceIdMap<String>>>();
+ relationInfoQueryMap = new UnaryQueryHashMap();
+ typeHierarchyMap = new UnaryQueryHashMap();
+ superTypesMap = new UnaryQueryHashMap();
+ superRelationsMap = new UnaryQueryHashMap();
+ typesMap = new UnaryQueryHashMap();
+ objectsMap = new DoubleKeyQueryHashMap();
+ orderedSetMap = new UnaryQueryHashMap();
+ predicatesMap = new UnaryQueryHashMap();
+ statementsMap = new DoubleKeyQueryHashMap();
+ directObjectsMap = new DoubleKeyQueryHashMap();
+ assertedPredicatesMap = new UnaryQueryHashMap();
+ assertedStatementsMap = new DoubleKeyQueryHashMap();
+ asyncReadEntryMap = new StableHashMap<AsyncRead, AsyncReadEntry>();
+ readEntryMap = new StableHashMap<Read, ReadEntry>();
+ asyncMultiReadEntryMap = new StableHashMap<AsyncMultiRead, AsyncMultiReadEntry>();
+ multiReadEntryMap = new StableHashMap<MultiRead, MultiReadEntry>();
+ externalReadEntryMap = new StableHashMap<ExternalRead, ExternalReadEntry>();
+ listeners = new THashMap<CacheEntry, ArrayList<ListenerEntry>>(10, 0.75f);
+ }
+
+// public <T> Object performQuery(ReadGraphImpl parentGraph, final AsyncRead<T> query, final CacheEntryBase entry_, AsyncProcedure procedure_) throws DatabaseException {
+//
+// AsyncReadEntry<T> entry = (AsyncReadEntry<T>)entry_;
+// AsyncProcedure<T> procedure = (AsyncProcedure<T>)procedure_;
+//
+// ReadGraphImpl queryGraph = parentGraph.withParent(entry_);
+//
+// try {
+//
+// query.perform(queryGraph, new AsyncProcedure<T>() {
+//
+// @Override
+// public void execute(AsyncReadGraph returnGraph, T result) {
+// ReadGraphImpl impl = (ReadGraphImpl)returnGraph;
+// entry.addOrSet(parentGraph, result);
+// try {
+// procedure.execute(parentGraph, result);
+// } catch (Throwable t) {
+// t.printStackTrace();
+// }
+//// parentBarrier.dec(query);
+// }
+//
+// @Override
+// public void exception(AsyncReadGraph returnGraph, Throwable t) {
+// ReadGraphImpl impl = (ReadGraphImpl)returnGraph;
+//// AsyncReadGraph resumeGraph = finalParentGraph.newAsync();
+// entry.except(parentGraph, t);
+// try {
+// procedure.exception(parentGraph, t);
+// } catch (Throwable t2) {
+// t2.printStackTrace();
+// }
+//// parentBarrier.dec(query);
+// }
+//
+// @Override
+// public String toString() {
+// return procedure.toString();
+// }
+//
+// });
+//
+// } catch (Throwable t) {
+//
+// entry.except(t);
+// try {
+// procedure.exception(parentGraph, t);
+// } catch (Throwable t2) {
+// t2.printStackTrace();
+// }
+//// parentBarrier.dec(query);
+//
+// }
+//
+// return null;
+//
+// }
+
+// public <T> Object performQuery(ReadGraphImpl parentGraph, final Read<T> query, final CacheEntryBase entry_, AsyncProcedure procedure_) throws DatabaseException {
+//
+// ReadGraphImpl queryGraph = parentGraph.withParent(entry_);
+//
+// ReadEntry entry = (ReadEntry)entry_;
+//
+// try {
+//
+// T result = (T)query.perform(queryGraph);
+// entry.addOrSet(queryGraph, result);
+//
+// return (T)entry.get(parentGraph, procedure_);
+//
+// } catch (Throwable t) {
+//
+// entry.except(t);
+// return (T)entry.get(parentGraph, procedure_);
+//
+// }
+//
+// }
+
+ public <T> Object performQuery(ReadGraphImpl parentGraph, final ExternalRead<T> query, final CacheEntryBase entry_, AsyncProcedure procedure_) throws DatabaseException {
+
+ ExternalReadEntry entry = (ExternalReadEntry)entry_;
+ AsyncProcedure<T> procedure = (AsyncProcedure<T>)procedure_;
+
+ try {
+
+ query.register(parentGraph, new Listener<T>() {
+
+ AtomicBoolean used = new AtomicBoolean(false);
+
+ @Override
+ public void execute(T result) {
+
+ // Just for safety
+ if(entry.isDiscarded()) return;
+
+ if(used.compareAndSet(false, true)) {
+ //entry.setPending();
+ entry.addOrSet(parentGraph.processor, result);
+ procedure.execute(parentGraph, result);
+ } else {
+ entry.queue(result);
+ parentGraph.processor.updatePrimitive(query);
+ }
+
+ }
+
+ @Override
+ public void exception(Throwable t) {
+
+ entry.except(t);
+
+ if(used.compareAndSet(false, true)) {
+ procedure.exception(parentGraph, t);
+ } else {
+// entry.queue(result);
+ parentGraph.processor.updatePrimitive(query);
+ }
+
+ }
+
+ @Override
+ public String toString() {
+ return procedure.toString();
+ }
+
+ @Override
+ public boolean isDisposed() {
+ return entry.isDiscarded() || !parentGraph.processor.isBound(entry);
+ }
+
+ });
+
+ return entry.getResult();
+
+ } catch (Throwable t) {
+
+ entry.except(t);
+ procedure.exception(parentGraph, t);
+ return entry.getResult();
+
+ }
+
+ }
+
+ public <T> Object performQuery(ReadGraphImpl parentGraph, final AsyncMultiRead<T> query, final CacheEntryBase entry_, Object procedure_) throws DatabaseException {
+
+ ReadGraphImpl queryGraph = parentGraph.withParent(entry_);
+
+ AsyncMultiReadEntry entry = (AsyncMultiReadEntry)entry_;
+ AsyncMultiProcedure<T> procedure = (AsyncMultiProcedure<T>)procedure_;
+
+ try {
+
+ query.perform(queryGraph, new AsyncMultiProcedure<T>() {
+
+ @Override
+ public void execute(AsyncReadGraph graph, T result) {
+ ReadGraphImpl impl = (ReadGraphImpl)graph;
+ entry.addOrSet(result);
+ try {
+ procedure.execute(parentGraph, result);
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+ }
+
+ @Override
+ public void finished(AsyncReadGraph graph) {
+ ReadGraphImpl impl = (ReadGraphImpl)graph;
+ entry.finish(parentGraph);
+ try {
+ procedure.finished(parentGraph);
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+ }
+
+ @Override
+ public void exception(AsyncReadGraph graph, Throwable t) {
+ ReadGraphImpl impl = (ReadGraphImpl)graph;
+ entry.except(parentGraph, t);
+ try {
+ procedure.exception(parentGraph, t);
+ } catch (Throwable t2) {
+ t2.printStackTrace();
+ }
+ }
+
+ });
+
+ return entry.getResult();
+
+ } catch (Throwable t) {
+
+ entry.except(t);
+ try {
+ procedure.exception(parentGraph, t);
+ } catch (Throwable t2) {
+ t2.printStackTrace();
+ }
+
+ return entry.getResult();
+
+ }
+
+ }
+
+ public <T> Object performQuery(ReadGraphImpl parentGraph, final MultiRead<T> query, final CacheEntryBase entry_, Object procedure_) throws DatabaseException {
+
+ ReadGraphImpl queryGraph = parentGraph.withParent(entry_);
+
+ MultiReadEntry entry = (MultiReadEntry)entry_;
+ SyncMultiProcedure<T> procedure = (SyncMultiProcedure<T>)procedure_;
+
+ try {
+
+ query.perform(queryGraph, new SyncMultiProcedure<T>() {
+
+ @Override
+ public void execute(ReadGraph graph, T result) {
+ ReadGraphImpl impl = (ReadGraphImpl)graph;
+ entry.addOrSet(result);
+ try {
+ procedure.execute(parentGraph, result);
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+ }
+
+ @Override
+ public void finished(ReadGraph graph) {
+ ReadGraphImpl impl = (ReadGraphImpl)graph;
+ entry.finish(parentGraph);
+ try {
+ procedure.finished(parentGraph);
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+ }
+
+ @Override
+ public void exception(ReadGraph graph, Throwable t) {
+ ReadGraphImpl impl = (ReadGraphImpl)graph;
+ entry.except((DatabaseException)t);
+ try {
+ procedure.exception(parentGraph, t);
+ } catch (Throwable t2) {
+ t2.printStackTrace();
+ }
+ }
+
+ });
+
+ return entry.getResult();
+
+ } catch (Throwable t) {
+
+ entry.except(t);
+ try {
+ procedure.exception(parentGraph, t);
+ } catch (Throwable t2) {
+ t2.printStackTrace();
+ }
+
+ return entry.getResult();
+
+ }
+
+ }
+
+ public ListenerEntry registerDependencies(ReadGraphImpl graph, CacheEntry child, CacheEntry parent, ListenerBase listener, Object procedure, boolean inferred) {
+
+ if (parent != null && !inferred) {
+ try {
+ if(!child.isImmutable(graph)) {
+ synchronized(child) {
+ child.addParent(parent);
+ }
+ }
+ } catch (DatabaseException e) {
+ Logger.defaultLogError(e);
+ }
+ if(DebugPolicy.DEPENDENCIES) System.out.println(child + " -> " + parent);
+ }
+
+ if (listener != null) {
+ return registerListener(child, listener, procedure);
+ } else {
+ return null;
+ }
+
+ }
+
+ public synchronized ListenerEntry registerListener(final CacheEntry entry, final ListenerBase base, final Object procedure) {
+
+ assert (entry != null);
+
+ if (base.isDisposed())
+ return null;
+
+ return addListener(entry, base, procedure);
+
+ }
+
+ protected void primeListenerEntry(final ListenerEntry entry, final Object result) {
+ entry.setLastKnown(result);
+ }
+
+ private ListenerEntry addListener(CacheEntry entry, ListenerBase base, Object procedure) {
+
+ assert (entry != null);
+ assert (procedure != null);
+
+ ArrayList<ListenerEntry> list = listeners.get(entry);
+ if (list == null) {
+ list = new ArrayList<ListenerEntry>(1);
+ listeners.put(entry, list);
+ }
+
+ ListenerEntry result = new ListenerEntry(entry, base, procedure);
+ int currentIndex = list.indexOf(result);
+ // There was already a listener
+ if(currentIndex > -1) {
+ ListenerEntry current = list.get(currentIndex);
+ if(!current.base.isDisposed()) return null;
+ list.set(currentIndex, result);
+ } else {
+ list.add(result);
+ }
+
+ if(DebugPolicy.LISTENER) {
+ new Exception().printStackTrace();
+ System.out.println("addListener -> " + list.size() + " " + entry + " " + base + " " + procedure);
+ }
+
+ return result;
+
+ }
+
+
+ public Collection<CacheEntry> getRootList() {
+
+ ArrayList<CacheEntry> result = new ArrayList<CacheEntry>();
+
+ for (Object e : valueQueryMap.values()) {
+ result.add((CacheEntry) e);
+ }
+ for (Object e : directPredicatesMap.values()) {
+ result.add((CacheEntry) e);
+ }
+ for (Object e : directSuperRelationsMap.values()) {
+ result.add((CacheEntry) e);
+ }
+ for (Object e : objectsMap.values()) {
+ result.add((CacheEntry) e);
+ }
+ for (Object e : directObjectsMap.values()) {
+ result.add((CacheEntry) e);
+ }
+ for (Object e : principalTypesMap.values()) {
+ result.add((CacheEntry) e);
+ }
+ for (Object e : superRelationsMap.values()) {
+ result.add((CacheEntry) e);
+ }
+ for (Object e : superTypesMap.values()) {
+ result.add((CacheEntry) e);
+ }
+ for (Object e : typesMap.values()) {
+ result.add((CacheEntry) e);
+ }
+ for (Object e : objectsMap.values()) {
+ result.add((CacheEntry) e);
+ }
+ for (Object e : assertedStatementsMap.values()) {
+ result.add((CacheEntry) e);
+ }
+ for (Object e : readEntryMap.values()) {
+ if(e instanceof CacheEntry) {
+ result.add((CacheEntry) e);
+ } else {
+ System.err.println("e=" + e);
+ }
+ }
+ for (Object e : asyncReadEntryMap.values()) {
+ if(e instanceof CacheEntry) {
+ result.add((CacheEntry) e);
+ } else {
+ System.err.println("e=" + e);
+ }
+ }
+ for (Object e : externalReadEntryMap.values()) {
+ result.add((CacheEntry) e);
+ }
+ for (Object e : orderedSetMap.values()) {
+ result.add((CacheEntry) e);
+ }
+
+ return result;
+
+ }
+
+ public int calculateCurrentSize() {
+
+ int realSize = 0;
+
+ realSize += directPredicatesMap.size();
+ realSize += directSuperRelationsMap.size();
+ realSize += principalTypesMap.size();
+ realSize += uRIToResourceMap.size();
+ //realSize += namespaceIndexMap.size();
+ realSize += childMapMap.size();
+
+ realSize += relationInfoQueryMap.size();
+ realSize += superTypesMap.size();
+ realSize += typeHierarchyMap.size();
+ realSize += superRelationsMap.size();
+ realSize += typesMap.size();
+
+ realSize += valueQueryMap.size();
+ realSize += directObjectsMap.size();
+ realSize += objectsMap.size();
+ realSize += orderedSetMap.size();
+ realSize += predicatesMap.size();
+
+ realSize += statementsMap.size();
+ realSize += assertedPredicatesMap.size();
+ realSize += assertedStatementsMap.size();
+ realSize += externalReadEntryMap.size();
+ realSize += asyncReadEntryMap.size();
+
+ realSize += readEntryMap.size();
+ realSize += asyncMultiReadEntryMap.size();
+ realSize += multiReadEntryMap.size();
+
+ return realSize;
+
+ }
+
+ CacheCollectionResult allCaches(CacheCollectionResult result) {
+
+ int level = Integer.MAX_VALUE;
+ directPredicatesMap.values(level, result);
+ directSuperRelationsMap.values(level, result);
+ principalTypesMap.values(level, result);
+ for(CacheEntryBase e : uRIToResourceMap.values())
+ if(e.getLevel() <= level)
+ result.add(e);
+// for(CacheEntryBase e : namespaceIndexMap.values())
+// if(e.getLevel() <= level)
+// result.add(e);
+
+ childMapMap.values(level, result);
+
+ relationInfoQueryMap.values(level, result);
+ superTypesMap.values(level, result);
+ typeHierarchyMap.values(level, result);
+ superRelationsMap.values(level, result);
+ typesMap.values(level, result);
+
+ valueQueryMap.values(level, result);
+ directObjectsMap.values(level, result);
+ objectsMap.values(level, result);
+ orderedSetMap.values(level, result);
+ predicatesMap.values(level, result);
+
+ statementsMap.values(level, result);
+ assertedPredicatesMap.values(level, result);
+ assertedStatementsMap.values(level, result);
+ externalReadEntryMap.values(level, result);
+ asyncReadEntryMap.values(level, result);
+
+ readEntryMap.values(level, result);
+ asyncMultiReadEntryMap.values(level, result);
+ multiReadEntryMap.values(level, result);
+
+ return result;
+
+ }
+
+ public void scanPending() {
+
+ ArrayList<CacheEntry> entries = new ArrayList<CacheEntry>();
+
+ entries.addAll(directPredicatesMap.values());
+ entries.addAll(directSuperRelationsMap.values());
+ entries.addAll(principalTypesMap.values());
+ entries.addAll(uRIToResourceMap.values());
+ //entries.addAll(namespaceIndexMap.values());
+ entries.addAll(childMapMap.values());
+ entries.addAll(relationInfoQueryMap.values());
+ entries.addAll(superTypesMap.values());
+ entries.addAll(superRelationsMap.values());
+ entries.addAll(typesMap.values());
+ entries.addAll(valueQueryMap.values());
+ entries.addAll(directObjectsMap.values());
+ entries.addAll(objectsMap.values());
+ entries.addAll(orderedSetMap.values());
+ entries.addAll(predicatesMap.values());
+ entries.addAll(orderedSetMap.values());
+ entries.addAll(statementsMap.values());
+ // entries.addAll(assertedObjectsMap.values());
+ entries.addAll(assertedPredicatesMap.values());
+ entries.addAll(assertedStatementsMap.values());
+ entries.addAll(externalReadEntryMap.values());
+ entries.addAll(asyncReadEntryMap.values());
+ entries.addAll(externalReadEntryMap.values());
+ entries.addAll(readEntryMap.values());
+ entries.addAll(asyncMultiReadEntryMap.values());
+ entries.addAll(multiReadEntryMap.values());
+ entries.addAll(readEntryMap.values());
+ System.out.println(entries.size() + " entries.");
+ for(Object e : entries) {
+ if(e instanceof CacheEntry) {
+ CacheEntry en = (CacheEntry)e;
+ if(en.isPending()) System.out.println("pending " + e);
+ if(en.isExcepted()) System.out.println("excepted " + e);
+ if(en.isDiscarded()) System.out.println("discarded " + e);
+ if(en.isRefuted()) System.out.println("refuted " + e);
+ if(en.isFresh()) System.out.println("fresh " + e);
+ } else {
+ //System.out.println("Unknown object " + e);
+ }
+ }
+ }
+
+ public static void waitPending(QueryProcessor processor, CacheEntry entry) throws DatabaseException {
+
+ int counter = 0;
+ while(entry.isPending()) {
+ try {
+ SessionTask task = null;//processor.getOwnTask(processor.thread.get());
+ if(task != null) {
+ task.run(processor.thread.get());
+ } else {
+ Thread.sleep(1);
+ counter++;
+ if(counter > 5000) {
+ CacheEntryBase base = ((CacheEntryBase)entry);
+// if(base.created != null) {
+// System.err.println("created:");
+// base.created.printStackTrace();
+// }
+// if(base.performed != null) {
+// System.err.println("performed:");
+// base.performed.printStackTrace();
+// }
+// if(base.ready != null) {
+// System.err.println("ready:");
+// base.ready.printStackTrace();
+// }
+ new Exception("Timeout waiting for request to complete: " + entry.getOriginalRequest().toString()).printStackTrace();
+ throw new DatabaseException("Timeout waiting for request to complete.");
+ //System.err.println("asd");
+ //base.getQuery().recompute(null, null, entry);
+ }
+ }
+ } catch (InterruptedException e) {
+ }
+ }
+
+ }
+
+ //////////////////////////////////////
+
+ public static Collection<Objects> entriesObjects(QueryProcessor processor, int r1) {
+ synchronized(processor.cache.objectsMap) {
+ return processor.cache.objectsMap.values(r1);
+ }
+ }
+
+ public static Collection<Objects> entriesObjects(QueryProcessor processor) {
+ synchronized(processor.cache.objectsMap) {
+ return processor.cache.objectsMap.values();
+ }
+ }
+
+ public static Collection<CacheEntry> entriesDirectPredicates(QueryProcessor processor) {
+ synchronized(processor.cache.directPredicatesMap) {
+ return processor.cache.directPredicatesMap.values();
+ }
+ }
+
+ static final Collection<DirectObjects> entriesDirectObjects(final QueryProcessor processor, final int r1) {
+ DoubleKeyQueryHashMap<IntProcedure> hash = processor.cache.directObjectsMap;
+ return hash.values(r1);
+ }
+
+ static final Collection<Statements> entriesStatements(final QueryProcessor processor, final int r1) {
+ return processor.cache.statementsMap.values(r1);
+ }
+
+ static final Types entryTypes(final QueryProcessor processor, final int r) {
+ return (Types)processor.cache.typesMap.get(r);
+ }
+
+ static final PrincipalTypes entryPrincipalTypes(final QueryProcessor processor, final int r) {
+ return (PrincipalTypes)processor.cache.principalTypesMap.get(r);
+ }
+
+ static final OrderedSet entryOrderedSet(final QueryProcessor processor, final int r) {
+ return (OrderedSet)processor.cache.orderedSetMap.get(r);
+ }
+
+ static final ValueQuery entryValueQuery(final QueryProcessor processor, final int r) {
+ return (ValueQuery)processor.cache.valueQueryMap.get(r);
+ }
+
+ static final DirectPredicates entryDirectPredicates(final QueryProcessor processor, final int r) {
+ return (DirectPredicates)processor.cache.directPredicatesMap.get(r);
+ }
+
+ public static final ReadEntry entryRead(final QueryProcessor processor, final Read request) {
+ return (ReadEntry)processor.cache.readEntryMap.get(request);
+ }
+
+ public static final MultiReadEntry entryMultiRead(final QueryProcessor processor, final MultiRead request) {
+ return (MultiReadEntry)processor.cache.multiReadEntryMap.get(request);
+ }
+
+ public static final AsyncReadEntry entryAsyncRead(final QueryProcessor processor, final AsyncRead request) {
+ return (AsyncReadEntry)processor.cache.asyncReadEntryMap.get(request);
+ }
+
+ public static final AsyncMultiReadEntry entryAsyncMultiRead(final QueryProcessor processor, final AsyncMultiRead request) {
+ return (AsyncMultiReadEntry)processor.cache.asyncMultiReadEntryMap.get(request);
+ }
+
+ protected static final long keyR2(long r1, long r2) {
+ long result = (r1<<32) | (r2 & 0xffffffffL);
+ return result;
+ }
+
+ protected static final <T> T id(T o) {
+ return o;
+ }
+
+ protected static final int keyR(int r) {
+ return r;
+ }
+
+ protected static final String keyID(String id) {
+ return id;
+ }
+
+ protected static InternalProcedure<IntSet> emptyIntSetProcedure = new InternalProcedure<IntSet>() {
+
+ @Override
+ public void execute(ReadGraphImpl graph, IntSet result) {
+ }
+
+ @Override
+ public void exception(ReadGraphImpl graph, Throwable throwable) {
+ }
+
+ };
+
+ protected static InternalProcedure<byte[]> emptyBytesProcedure = new InternalProcedure<byte[]>() {
+
+ @Override
+ public void execute(ReadGraphImpl graph, byte[] bytes) {
+ }
+
+ @Override
+ public void exception(ReadGraphImpl graph, Throwable throwable) {
+ }
+
+ };
+
+ protected static InternalProcedure<Integer> emptyIntegerProcedure = new InternalProcedure<Integer>() {
+
+ @Override
+ public void execute(ReadGraphImpl graph, Integer i) {
+ }
+
+ @Override
+ public void exception(ReadGraphImpl graph, Throwable throwable) {
+ }
+
+ };
+
+
+ protected static InternalProcedure<TObjectIntHashMap<String>> emptyNamespaceProcedure = new InternalProcedure<TObjectIntHashMap<String>>() {
+
+ @Override
+ public void execute(ReadGraphImpl graph, TObjectIntHashMap<String> i) {
+ }
+
+ @Override
+ public void exception(ReadGraphImpl graph, Throwable throwable) {
+ }
+
+ };
+
+
+ protected static InternalProcedure<RelationInfo> emptyRelationInfoProcedure = new InternalProcedure<RelationInfo>() {
+
+ @Override
+ public void execute(ReadGraphImpl graph, RelationInfo i) {
+ }
+
+ @Override
+ public void exception(ReadGraphImpl graph, Throwable throwable) {
+ }
+
+ };
+
+ protected static InternalProcedure<ObjectResourceIdMap<String>> emptyChildMapProcedure = new InternalProcedure<ObjectResourceIdMap<String>>() {
+
+ @Override
+ public void execute(ReadGraphImpl graph, ObjectResourceIdMap<String> i) {
+ }
+
+ @Override
+ public void exception(ReadGraphImpl graph, Throwable throwable) {
+ }
+
+ };
+
+ protected static IntProcedure emptyIntProcedure = new IntProcedure() {
+
+ @Override
+ public void finished(ReadGraphImpl graph) {
+ }
+
+ @Override
+ public void execute(ReadGraphImpl graph, int i) {
+ }
+
+ @Override
+ public void exception(ReadGraphImpl graph, Throwable throwable) {
+ }
+ };
+
+ protected static TripleIntProcedure emptyTripleIntProcedure = new TripleIntProcedure() {
+
+ @Override
+ public void execute(ReadGraphImpl graph, int s, int p, int o) {
+ }
+
+ @Override
+ public void finished(ReadGraphImpl graph) {
+ }
+
+ @Override
+ public void exception(ReadGraphImpl graph, Throwable throwable) {
+ }
+
+ };
+
+ protected static AsyncProcedure<Object> emptyAsyncProcedure = new AsyncProcedure<Object>() {
+
+ @Override
+ public void execute(AsyncReadGraph graph, Object result) {
+ }
+
+ @Override
+ public void exception(AsyncReadGraph graph, Throwable throwable) {
+ }
+
+ };
+
+ protected static AsyncMultiProcedure<Object> emptyAsyncMultiProcedure = new AsyncMultiProcedure<Object>() {
+
+ @Override
+ public void execute(AsyncReadGraph graph, Object result) {
+ }
+
+ @Override
+ public void finished(AsyncReadGraph graph) {
+ }
+
+ @Override
+ public void exception(AsyncReadGraph graph, Throwable throwable) {
+ }
+
+ };
+
+ protected static SyncMultiProcedure<Object> emptySyncMultiProcedure = new SyncMultiProcedure<Object>() {
+
+ @Override
+ public void execute(ReadGraph graph, Object result) {
+ }
+
+ @Override
+ public void finished(ReadGraph graph) {
+ }
+
+ @Override
+ public void exception(ReadGraph graph, Throwable throwable) {
+ }
+
+ };
+
+ protected static InternalProcedure<IntSet> emptyProcedureTypes = emptyIntSetProcedure;
+ protected static InternalProcedure<IntSet> emptyProcedureSuperTypes = emptyIntSetProcedure;
+ protected static InternalProcedure<IntSet> emptyProcedureTypeHierarchy = emptyIntSetProcedure;
+ protected static InternalProcedure<IntSet> emptyProcedureSuperRelations = emptyIntSetProcedure;
+ protected static InternalProcedure<IntSet> emptyProcedurePredicates = emptyIntSetProcedure;
+ protected static InternalProcedure<IntSet> emptyProcedureDirectPredicates = emptyIntSetProcedure;
+
+ protected static IntProcedure emptyProcedureObjects = emptyIntProcedure;
+ protected static IntProcedure emptyProcedureDirectObjects = emptyIntProcedure;
+ protected static IntProcedure emptyProcedurePrincipalTypes = emptyIntProcedure;
+ protected static IntProcedure emptyProcedureDirectSuperRelations = emptyIntProcedure;
+ protected static IntProcedure emptyProcedureAssertedPredicates = emptyIntProcedure;
+ protected static IntProcedure emptyProcedureOrderedSet = emptyIntProcedure;
+
+ protected static TripleIntProcedure emptyProcedureStatements = emptyTripleIntProcedure;
+ protected static TripleIntProcedure emptyProcedureAssertedStatements = emptyTripleIntProcedure;
+
+ protected static InternalProcedure<byte[]> emptyProcedureValueQuery = emptyBytesProcedure;
+
+ protected static InternalProcedure<Integer> emptyProcedureURIToResource = emptyIntegerProcedure;
+ protected static InternalProcedure<TObjectIntHashMap<String>> emptyProcedureNamespaceIndex = emptyNamespaceProcedure;
+ protected static InternalProcedure<ObjectResourceIdMap<String>> emptyProcedureChildMap = emptyChildMapProcedure;
+ protected static InternalProcedure<RelationInfo> emptyProcedureRelationInfoQuery = emptyRelationInfoProcedure;
+
+ protected static AsyncProcedure emptyProcedureReadEntry = emptyAsyncProcedure;
+ protected static AsyncProcedure emptyProcedureAsyncReadEntry = emptyAsyncProcedure;
+ protected static SyncMultiProcedure emptyProcedureMultiReadEntry = emptySyncMultiProcedure;
+ protected static AsyncMultiProcedure emptyProcedureAsyncMultiReadEntry = emptyAsyncMultiProcedure;
+ protected static AsyncProcedure emptyProcedureExternalReadEntry = emptyAsyncProcedure;
+
+ static class AsyncProcedureWrapper<T> implements AsyncProcedure<T> {
+
+ private AsyncProcedure<T> procedure;
+ private T result = null;
+ private Throwable throwable = null;
+ private Semaphore s = new Semaphore(0);
+
+ AsyncProcedureWrapper(AsyncProcedure<T> procedure) {
+ this.procedure = procedure;
+ }
+
+ @Override
+ public void execute(AsyncReadGraph graph, T result) {
+ if(procedure != null) procedure.execute(graph, result);
+ this.result = result;
+ s.release();
+ }
+
+ @Override
+ public void exception(AsyncReadGraph graph, Throwable throwable) {
+ if(procedure != null) procedure.exception(graph, throwable);
+ this.throwable = throwable;
+ s.release();
+ }
+
+ public T get() throws DatabaseException {
+ try {
+ s.acquire();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ if(throwable != null) {
+ if(throwable instanceof DatabaseException) throw (DatabaseException)throwable;
+ else throw new DatabaseException(throwable);
+ } else {
+ return result;
+ }
+ }
+
+ }
+
+ static class ExternalProcedureWrapper<T> implements AsyncProcedure<T> {
+
+ private Procedure<T> procedure;
+ private T result = null;
+ private Throwable throwable = null;
+
+ ExternalProcedureWrapper(Procedure<T> procedure) {
+ this.procedure = procedure;
+ }
+
+ @Override
+ public void execute(AsyncReadGraph graph, T result) {
+ if(procedure != null) procedure.execute(result);
+ this.result = result;
+ }
+
+ @Override
+ public void exception(AsyncReadGraph graph, Throwable throwable) {
+ if(procedure != null) procedure.exception(throwable);
+ this.throwable = throwable;
+ }
+
+ public T get() throws DatabaseException {
+ if(throwable != null) {
+ if(throwable instanceof DatabaseException) throw (DatabaseException)throwable;
+ else throw new DatabaseException(throwable);
+ } else {
+ return result;
+ }
+ }
+
+ }
+
+
+ static class InternalProcedureWrapper<T> implements InternalProcedure<T> {
+
+ private InternalProcedure<T> procedure;
+ private T result = null;
+ private Throwable throwable = null;
+
+ InternalProcedureWrapper(InternalProcedure<T> procedure) {
+ this.procedure = procedure;
+ }
+
+ @Override
+ public void execute(ReadGraphImpl graph, T result) throws DatabaseException {
+ if(procedure != null) procedure.execute(graph, result);
+ this.result = result;
+ }
+
+ @Override
+ public void exception(ReadGraphImpl graph, Throwable throwable) throws DatabaseException {
+ if(procedure != null) procedure.exception(graph, throwable);
+ this.throwable = throwable;
+ }
+
+ public T get() throws DatabaseException {
+ if(throwable != null) {
+ if(throwable instanceof DatabaseException) throw (DatabaseException)throwable;
+ else throw new DatabaseException(throwable);
+ } else {
+ return result;
+ }
+ }
+
+ }
+
+ static class IntSetWrapper implements IntProcedure {
+
+ private IntProcedure procedure;
+ private final IntSet result;
+ private Throwable throwable = null;
+
+ IntSetWrapper(ReadGraphImpl graph, IntProcedure procedure) {
+ this.procedure = procedure;
+ result = new IntSet(graph.processor.querySupport);
+ }
+
+ @Override
+ public void execute(ReadGraphImpl graph, int i) throws DatabaseException {
+ if(procedure != null) procedure.execute(graph, i);
+ result.add(i);
+ }
+
+ @Override
+ public void exception(ReadGraphImpl graph, Throwable throwable) throws DatabaseException {
+ if(procedure != null) procedure.exception(graph, throwable);
+ this.throwable = throwable;
+ }
+
+ @Override
+ public void finished(ReadGraphImpl graph) throws DatabaseException {
+ if(procedure != null) procedure.finished(graph);
+ }
+
+ public IntSet get() throws DatabaseException {
+ if(throwable != null) {
+ if(throwable instanceof DatabaseException) throw (DatabaseException)throwable;
+ else throw new DatabaseException(throwable);
+ } else {
+ return result;
+ }
+ }
+
+ }
+
+ static class TripleIntProcedureWrapper implements TripleIntProcedure {
+
+ private TripleIntProcedure procedure;
+ private IntArray result = new IntArray();
+ private Throwable throwable = null;
+
+ TripleIntProcedureWrapper(TripleIntProcedure procedure) {
+ this.procedure = procedure;
+ }
+
+ @Override
+ public void execute(ReadGraphImpl graph, int i1, int i2, int i3) throws DatabaseException {
+ if(procedure != null) procedure.execute(graph, i1, i2, i3);
+ result.add(i1);
+ result.add(i2);
+ result.add(i3);
+ }
+
+ @Override
+ public void exception(ReadGraphImpl graph, Throwable throwable) throws DatabaseException {
+ if(procedure != null) procedure.exception(graph, throwable);
+ this.throwable = throwable;
+ }
+
+ @Override
+ public void finished(ReadGraphImpl graph) throws DatabaseException {
+ if(procedure != null) procedure.finished(graph);
+ }
+
+ public IntArray get() throws DatabaseException {
+ if(throwable != null) {
+ if(throwable instanceof DatabaseException) throw (DatabaseException)throwable;
+ else throw new DatabaseException(throwable);
+ } else {
+ return result;
+ }
+ }
+
+ }
+
+ public static <T> T resultExternalReadEntry(ReadGraphImpl graph, ExternalRead r, CacheEntry parent, ListenerBase listener, Procedure<T> procedure) throws DatabaseException {
+ ExternalProcedureWrapper<T> wrap = new ExternalProcedureWrapper<>(procedure);
+ QueryCache.runnerExternalReadEntry(graph, r, parent, listener, wrap);
+ return wrap.get();
+ }
+
+ public static <T> T resultReadEntry(ReadGraphImpl graph, Read r, CacheEntry parent, ListenerBase listener, AsyncProcedure<T> procedure) throws DatabaseException {
+ AsyncProcedureWrapper<T> wrap = new AsyncProcedureWrapper<>(procedure);
+ QueryCache.runnerReadEntry(graph, r, parent, listener, wrap, true);
+ return wrap.get();
+ }
+
+ public static <T> T resultAsyncReadEntry(ReadGraphImpl graph, AsyncRead r, CacheEntry parent, ListenerBase listener, AsyncProcedure<T> procedure) throws DatabaseException {
+ AsyncProcedureWrapper<T> wrap = new AsyncProcedureWrapper<>(procedure);
+ QueryCache.runnerAsyncReadEntry(graph, r, parent, listener, wrap, true);
+ return wrap.get();
+ }
+
+ public static byte[] resultValueQuery(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener) throws DatabaseException {
+ InternalProcedureWrapper<byte[]> wrap = new InternalProcedureWrapper<>(null);
+ QueryCache.runnerValueQuery(graph, r, parent, listener, wrap);
+ return wrap.get();
+ }
+
+ public static RelationInfo resultRelationInfoQuery(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener) throws DatabaseException {
+ InternalProcedureWrapper<RelationInfo> wrap = new InternalProcedureWrapper<>(null);
+ QueryCache.runnerRelationInfoQuery(graph, r, parent, listener, wrap);
+ return wrap.get();
+ }
+
+ public static IntSet resultSuperRelations(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener) throws DatabaseException {
+ InternalProcedureWrapper<IntSet> wrap = new InternalProcedureWrapper<>(null);
+ QueryCache.runnerSuperRelations(graph, r, parent, listener, wrap);
+ return wrap.get();
+ }
+
+ public static IntSet resultSuperTypes(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener) throws DatabaseException {
+ InternalProcedureWrapper<IntSet> wrap = new InternalProcedureWrapper<>(null);
+ QueryCache.runnerSuperTypes(graph, r, parent, listener, wrap);
+ return wrap.get();
+ }
+
+ public static IntSet resultTypes(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener) throws DatabaseException {
+ InternalProcedureWrapper<IntSet> wrap = new InternalProcedureWrapper<>(null);
+ QueryCache.runnerTypes(graph, r, parent, listener, wrap);
+ return wrap.get();
+ }
+
+ public static IntSet resultPredicates(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener) throws DatabaseException {
+ InternalProcedureWrapper<IntSet> wrap = new InternalProcedureWrapper<>(null);
+ QueryCache.runnerPredicates(graph, r, parent, listener, wrap);
+ return wrap.get();
+ }
+
+ public static IntSet resultDirectPredicates(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener) throws DatabaseException {
+ InternalProcedureWrapper<IntSet> wrap = new InternalProcedureWrapper<>(null);
+ QueryCache.runnerDirectPredicates(graph, r, parent, listener, wrap);
+ return wrap.get();
+ }
+
+ public static IntArray resultAssertedStatements(ReadGraphImpl graph, int r1, int r2, CacheEntry parent, ListenerBase listener) throws DatabaseException {
+ TripleIntProcedureWrapper wrap = new TripleIntProcedureWrapper(null);
+ QueryCache.runnerAssertedStatements(graph, r1, r2, parent, listener, wrap);
+ return wrap.get();
+ }
+
+ public static Integer resultURIToResource(ReadGraphImpl graph, String id, CacheEntry parent, ListenerBase listener) throws DatabaseException {
+ InternalProcedureWrapper<Integer> wrap = new InternalProcedureWrapper<Integer>(null);
+ QueryCache.runnerURIToResource(graph, id, parent, listener, wrap);
+ return wrap.get();
+ }
+
+ public static ObjectResourceIdMap<String> resultChildMap(ReadGraphImpl graph, int r, CacheEntry parent, ListenerBase listener) throws DatabaseException {
+ InternalProcedureWrapper<ObjectResourceIdMap<String>> wrap = new InternalProcedureWrapper<ObjectResourceIdMap<String>>(null);
+ QueryCache.runnerChildMap(graph, r, parent, listener, wrap);
+ return wrap.get();
+ }
+
+ static boolean shouldCache(QueryProcessor processor, int r) {
+ return processor.isImmutable(r);
+ }
+
+ static boolean shouldCache(QueryProcessor processor, int r, int r2) {
+ return processor.isImmutable(r);
+ }
+
+ static boolean shouldCache(QueryProcessor processor, Object o) {
+ return false;
+ }
+
+}
\ No newline at end of file