--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.db.impl.query;\r
+\r
+import org.simantics.db.impl.graph.ReadGraphImpl;\r
+import org.simantics.db.procedure.AsyncProcedure;\r
+import org.simantics.db.procedure.ListenerBase;\r
+import org.simantics.db.procedure.Procedure;\r
+\r
+\r
+final public class DirectStatements /*extends CollectionBinaryQuery<TripleIntProcedure>*/ {\r
+\r
+ /*\r
+ public DirectStatements(final int r1, final int r2) {\r
+ super(r1, r2);\r
+ }\r
+\r
+ public static DirectStatements newInstance(final int r1, final int r2) {\r
+ return new DirectStatements(r1, r2);\r
+ }\r
+\r
+ final static DirectStatements entry(final QueryProcessor provider, final int r1, final int r2) {\r
+\r
+ return (DirectStatements)provider.statementsMap[provider.resourceThread(r1)].get(id(r1,r2));\r
+\r
+ }\r
+\r
+ final static Collection<DirectStatements> entries(final QueryProcessor processor, final int r1) {\r
+ BinaryQueryHashMap<TripleIntProcedure> hash = processor.statementsMap[processor.resourceThread(r1)];\r
+ return hash.values(r1);\r
+ }\r
+ */\r
+ \r
+ final public static void queryEach(ReadGraphImpl graph, final int r, final QueryProcessor provider, final CacheEntry parent, final ListenerBase listener, final AsyncProcedure<org.simantics.db.DirectStatements> procedure, boolean ignoreVirtual) {\r
+\r
+ assert(r != 0);\r
+\r
+ org.simantics.db.DirectStatements result = provider.querySupport.getStatements(graph, r, provider, ignoreVirtual);\r
+ procedure.execute(graph, result);\r
+\r
+ }\r
+\r
+ final public static void queryEach(ReadGraphImpl graph, final int r, final QueryProcessor provider, final CacheEntry parent, final ListenerBase listener, final Procedure<org.simantics.db.DirectStatements> procedure) {\r
+\r
+ assert(r != 0);\r
+\r
+ try {\r
+\r
+ org.simantics.db.DirectStatements result = provider.querySupport.getStatements(graph, r, provider, true);\r
+ procedure.execute(result);\r
+ \r
+// provider.querySupport.getStatements(graph, r, procedure);\r
+\r
+ } catch (Throwable t) {\r
+\r
+ t.printStackTrace();\r
+\r
+ }\r
+\r
+ }\r
+\r
+ /*\r
+ @Override\r
+ public BinaryQuery<TripleIntProcedure> getEntry(int callerThread, QueryProcessor provider) {\r
+ return provider.statementsMap[callerThread].get(id);\r
+ }\r
+\r
+ @Override\r
+ public void putEntry(int callerThread, QueryProcessor provider) {\r
+ provider.statementsMap[callerThread].put(id, this);\r
+ }\r
+\r
+ @Override\r
+ final public void removeEntry(int callerThread, QueryProcessor provider) {\r
+ provider.statementsMap[callerThread].remove(id);\r
+ }\r
+\r
+ final private void forSingleAssertion(ReadGraphImpl graph, final QueryProcessor queryProvider, final TripleIntProcedure procedure) {\r
+\r
+ final AtomicInteger results = new AtomicInteger();\r
+\r
+ PrincipalTypes.queryEach(graph, r1(), queryProvider, this, null, new SyncIntProcedure() {\r
+\r
+ @Override\r
+ public void run(ReadGraphImpl graph) {\r
+\r
+ int rc = results.get();\r
+\r
+ if(isExcepted()) {\r
+\r
+ procedure.exception(graph, (Throwable)getResult());\r
+\r
+ } else {\r
+\r
+ // No result or single result\r
+ if(rc == 0 || rc == 1) {\r
+\r
+ finish(graph, queryProvider);\r
+ procedure.finished(graph);\r
+\r
+ } else {\r
+\r
+ ManyObjectsForFunctionalRelationException exception = new ManyObjectsForFunctionalRelationException("Functional relation has more than one statement.", r1());\r
+ except(exception);\r
+ procedure.exception(graph, exception);\r
+\r
+ }\r
+\r
+ }\r
+\r
+ }\r
+\r
+ @Override\r
+ public void execute(ReadGraphImpl graph, int type) {\r
+\r
+ inc();\r
+\r
+ AssertedStatements.queryEach(graph, type, r2(), queryProvider, DirectStatements.this, null, new TripleIntProcedureAdapter() {\r
+\r
+ @Override\r
+ public void execute(ReadGraphImpl graph, int s, int p, int o) {\r
+\r
+ int event = results.getAndIncrement();\r
+ if(event == 0) {\r
+\r
+ addOrSet(s, p, o);\r
+ procedure.execute(graph, s, p, o);\r
+\r
+ }\r
+\r
+ }\r
+\r
+ @Override\r
+ public void finished(ReadGraphImpl graph) {\r
+\r
+ dec(graph);\r
+\r
+ }\r
+\r
+ @Override\r
+ public void exception(ReadGraphImpl graph, Throwable t) {\r
+\r
+ except(t);\r
+ dec(graph);\r
+\r
+ }\r
+\r
+ });\r
+\r
+ }\r
+\r
+ @Override\r
+ public void finished(ReadGraphImpl graph) {\r
+\r
+ dec(graph);\r
+\r
+ }\r
+\r
+ });\r
+\r
+ }\r
+\r
+ // Search for one statement\r
+ final public void computeFunctionalIndex(ReadGraphImpl graph, final QueryProcessor provider, final RelationInfo ri, final TripleIntProcedure procedure, final boolean store) {\r
+\r
+ if(ri.isFinal) {\r
+\r
+ boolean found = provider.querySupport.getObjects(graph, r1(), r2(), new IntProcedure() {\r
+\r
+ @Override\r
+ public void execute(ReadGraphImpl graph, int i) {\r
+ addOrSet(r1(), r2(), i);\r
+ }\r
+\r
+ @Override\r
+ public void exception(ReadGraphImpl graph, Throwable t) {\r
+ if(DebugException.DEBUG) new DebugException(t).printStackTrace();\r
+ }\r
+\r
+ @Override\r
+ public void finished(ReadGraphImpl graph) {\r
+ }\r
+\r
+ });\r
+\r
+ // If functional relation was found there is no need to check assertions\r
+ if(found) {\r
+\r
+ final IntArray array = (IntArray)getResult();\r
+ if(array.size() > 3) {\r
+ Throwable exception = new ManyObjectsForFunctionalRelationException("Functional relation " + r2() + " has multiple objects " + Arrays.toString(array.toArray()) + " for subject " + r1());\r
+ except(exception);\r
+ procedure.exception(graph, exception);\r
+ return;\r
+ }\r
+ procedure.execute(graph, array.data[0], array.data[1], array.data[2]);\r
+ finish(graph, provider);\r
+ procedure.finished(graph);\r
+ return;\r
+\r
+ }\r
+\r
+ // Check for assertions\r
+ forSingleAssertion(graph, provider, procedure);\r
+\r
+\r
+ } else {\r
+\r
+ final AtomicBoolean found = new AtomicBoolean(false);\r
+\r
+ DirectPredicates.queryEach(graph, r1(), provider, DirectStatements.this, null, new SyncIntProcedure() {\r
+\r
+ @Override\r
+ public void run(ReadGraphImpl graph) {\r
+\r
+ if(found.get()) return;\r
+\r
+ // Check for assertions\r
+ forSingleAssertion(graph, provider, procedure);\r
+\r
+ }\r
+\r
+ @Override\r
+ public void execute(ReadGraphImpl graph, final int pred) {\r
+\r
+ if(found.get()) return;\r
+\r
+ if(pred == r2()) {\r
+\r
+ inc();\r
+\r
+ DirectObjects.queryEach(graph, r1(), pred, provider, DirectStatements.this, null, new IntProcedure() {\r
+\r
+ @Override\r
+ public void execute(ReadGraphImpl graph, int i) {\r
+\r
+ if(found.compareAndSet(false, true)) {\r
+\r
+ addOrSet(r1(), pred, i);\r
+ finish(graph, provider);\r
+ procedure.execute(graph, r1(), pred, i);\r
+ procedure.finished(graph);\r
+\r
+ } else {\r
+\r
+ ManyObjectsForFunctionalRelationException exception = new ManyObjectsForFunctionalRelationException("Functional relation has more than one statement.", r1());\r
+ except(exception);\r
+ procedure.exception(graph, exception);\r
+\r
+ }\r
+\r
+ }\r
+\r
+ @Override\r
+ public void finished(ReadGraphImpl graph) {\r
+\r
+ dec(graph);\r
+\r
+ }\r
+\r
+ @Override\r
+ public void exception(ReadGraphImpl graph, Throwable t) {\r
+ procedure.exception(graph, t);\r
+ }\r
+\r
+ });\r
+\r
+ } else {\r
+\r
+ inc();\r
+\r
+ SuperRelations.queryEach(graph, pred, provider, DirectStatements.this, null, new InternalProcedure<IntSet>() {\r
+\r
+ @Override\r
+ public void execute(ReadGraphImpl graph, IntSet result) {\r
+\r
+ if(found.get()) {\r
+ dec(graph);\r
+ return;\r
+ }\r
+\r
+ if(result.contains(r2())) {\r
+\r
+ inc();\r
+\r
+ DirectObjects.queryEach(graph, r1(), pred, provider, DirectStatements.this, null, new IntProcedure() {\r
+\r
+ @Override\r
+ public void execute(ReadGraphImpl graph, int i) {\r
+\r
+ if(found.compareAndSet(false, true)) {\r
+\r
+ addOrSet(r1(), pred, i);\r
+ finish(graph, provider);\r
+ procedure.execute(graph, r1(), pred, i);\r
+ procedure.finished(graph);\r
+\r
+ } else {\r
+\r
+ ManyObjectsForFunctionalRelationException exception = new ManyObjectsForFunctionalRelationException("Functional relation has more than one statement.", r1());\r
+ except(exception);\r
+ procedure.exception(graph, exception);\r
+\r
+ }\r
+\r
+ }\r
+\r
+ @Override\r
+ public void finished(ReadGraphImpl graph) {\r
+\r
+ dec(graph);\r
+\r
+ }\r
+\r
+ @Override\r
+ public void exception(ReadGraphImpl graph, Throwable t) {\r
+ procedure.exception(graph, t);\r
+ }\r
+\r
+ });\r
+\r
+ }\r
+\r
+ dec(graph);\r
+\r
+ }\r
+\r
+ @Override\r
+ public void exception(ReadGraphImpl graph, Throwable t) {\r
+ procedure.exception(graph, t);\r
+ }\r
+\r
+ });\r
+\r
+ }\r
+\r
+ }\r
+\r
+ @Override\r
+ public void finished(ReadGraphImpl graph) {\r
+\r
+ dec(graph);\r
+\r
+ }\r
+\r
+ });\r
+\r
+ }\r
+\r
+ }\r
+\r
+ final private void forAssertions(ReadGraphImpl graph, final QueryProcessor queryProvider, final TripleIntProcedure procedure) {\r
+\r
+ PrincipalTypes.queryEach(graph, r1(), queryProvider, this, null, new SyncIntProcedure() {\r
+\r
+ @Override\r
+ public void run(ReadGraphImpl graph) {\r
+\r
+ finish(graph, queryProvider);\r
+ procedure.finished(graph);\r
+\r
+ }\r
+\r
+ TripleIntProcedure proc = new TripleIntProcedureAdapter() {\r
+\r
+ @Override\r
+ public void execute(ReadGraphImpl graph, int s, int p, int o) {\r
+ addOrSet(s, p, o);\r
+ procedure.execute(graph, s, p, o);\r
+ }\r
+\r
+ @Override\r
+ public void finished(ReadGraphImpl graph) {\r
+ dec(graph);\r
+ }\r
+\r
+ @Override\r
+ public void exception(ReadGraphImpl graph, Throwable t) {\r
+ procedure.exception(graph, t);\r
+ }\r
+\r
+ }; \r
+\r
+ @Override\r
+ public void execute(ReadGraphImpl graph, int type) {\r
+\r
+ inc();\r
+\r
+ AssertedStatements.queryEach(graph, type, r2(), queryProvider, DirectStatements.this, null, proc);\r
+\r
+ }\r
+\r
+ @Override\r
+ public void finished(ReadGraphImpl graph) {\r
+ dec(graph); \r
+ }\r
+\r
+ });\r
+\r
+\r
+ }\r
+\r
+ final public void computeNotFunctionalIndex(ReadGraphImpl graph, final QueryProcessor provider, RelationInfo ri, final TripleIntProcedure procedure, final boolean store) {\r
+\r
+ if(ri.isFinal) {\r
+\r
+ provider.querySupport.getObjects(graph, r1(), r2(), new IntProcedure() {\r
+\r
+ @Override\r
+ public void execute(ReadGraphImpl graph, int i) {\r
+ addOrSet(r1(), r2(), i);\r
+ }\r
+\r
+ @Override\r
+ public void exception(ReadGraphImpl graph, Throwable t) {\r
+ if(DebugException.DEBUG) new DebugException(t).printStackTrace();\r
+ procedure.exception(graph, t);\r
+ }\r
+\r
+ @Override\r
+ public void finished(ReadGraphImpl graph) {\r
+ }\r
+\r
+ });\r
+\r
+ final IntArray value = (IntArray)getResult();\r
+ for(int i=0;i<value.size();i+=3) {\r
+ procedure.execute(graph, value.data[i], value.data[i+1], value.data[i+2]);\r
+ }\r
+\r
+ forAssertions(graph, provider, procedure);\r
+\r
+ } else {\r
+\r
+ DirectPredicates.queryEach(graph, r1(), provider, DirectStatements.this, null, new SyncIntProcedure() {\r
+\r
+ @Override\r
+ public void run(ReadGraphImpl graph) {\r
+\r
+ forAssertions(graph, provider, procedure);\r
+\r
+ }\r
+\r
+ @Override\r
+ public void execute(ReadGraphImpl graph, final int pred) {\r
+\r
+ // System.out.println("directpredicates execute " + pred);\r
+\r
+ if(pred == r2()) {\r
+\r
+ inc();\r
+\r
+ DirectObjects.queryEach(graph, r1(), pred, provider, DirectStatements.this, null, new IntProcedure() {\r
+\r
+ @Override\r
+ public void execute(ReadGraphImpl graph, int i) {\r
+ // System.out.println("pred=" + pred + " object=" + i);\r
+ addOrSet(r1(), pred, i);\r
+ procedure.execute(graph, r1(), pred, i);\r
+ }\r
+\r
+ @Override\r
+ public void finished(ReadGraphImpl graph) {\r
+ dec(graph);\r
+ }\r
+\r
+ @Override\r
+ public void exception(ReadGraphImpl graph, Throwable t) {\r
+ procedure.exception(graph, t);\r
+ }\r
+\r
+ });\r
+\r
+ } else {\r
+\r
+ inc();\r
+\r
+ SuperRelations.queryEach(graph, pred, provider, DirectStatements.this, null, new InternalProcedure<IntSet>() {\r
+\r
+ @Override\r
+ public void execute(ReadGraphImpl graph, IntSet result) {\r
+\r
+ if(result.contains(r2())) {\r
+\r
+ inc();\r
+\r
+ DirectObjects.queryEach(graph, r1(), pred, provider, DirectStatements.this, null, new IntProcedure() {\r
+\r
+ @Override\r
+ public void execute(ReadGraphImpl graph, int i) {\r
+\r
+ // if(pred == 65548)\r
+ // System.out.println("s=" + r1() + "p=" + pred + " o=" + i);\r
+\r
+ addOrSet(r1(), pred, i);\r
+ procedure.execute(graph, r1(), pred, i);\r
+\r
+ }\r
+\r
+ @Override\r
+ public void finished(ReadGraphImpl graph) {\r
+ dec(graph);\r
+ }\r
+\r
+ @Override\r
+ public void exception(ReadGraphImpl graph, Throwable t) {\r
+ procedure.exception(graph, t);\r
+ }\r
+\r
+ });\r
+\r
+ }\r
+\r
+ dec(graph);\r
+\r
+ }\r
+\r
+ @Override\r
+ public void exception(ReadGraphImpl graph, Throwable t) {\r
+ procedure.exception(graph, t);\r
+ }\r
+\r
+ });\r
+\r
+ }\r
+\r
+ }\r
+\r
+ @Override\r
+ public void finished(ReadGraphImpl graph) {\r
+ dec(graph);\r
+ }\r
+\r
+ });\r
+\r
+ }\r
+\r
+ }\r
+\r
+\r
+ @Override\r
+ public void computeForEach(ReadGraphImpl graph, final QueryProcessor provider, final TripleIntProcedure procedure, final boolean store) {\r
+\r
+ RelationInfoQuery.queryEach(graph, r2(), provider, this, null, new InternalProcedure<RelationInfo>() {\r
+\r
+ @Override\r
+ public void execute(ReadGraphImpl graph, final RelationInfo ri) {\r
+\r
+ provider.querySupport.ensureLoaded(graph, r1(), r2());\r
+ if(ri.isFunctional) {\r
+ computeFunctionalIndex(graph, provider, ri, procedure, store);\r
+ } else {\r
+ computeNotFunctionalIndex(graph, provider, ri, procedure, store);\r
+ }\r
+ \r
+ }\r
+\r
+ @Override\r
+ public void exception(ReadGraphImpl graph, Throwable t) {\r
+ procedure.exception(graph, t);\r
+ }\r
+\r
+ });\r
+\r
+ }\r
+\r
+ @Override\r
+ public String toString() {\r
+ return "Statements[" + r1() + " - " + r2() + "]";\r
+ }\r
+\r
+ final private void finish(ReadGraphImpl graph, QueryProcessor provider) {\r
+\r
+ assert(isPending());\r
+\r
+ synchronized(this) {\r
+ setReady();\r
+ }\r
+\r
+ }\r
+\r
+ synchronized public void addOrSet(int s, int p, int o) {\r
+\r
+ assert(isPending());\r
+\r
+ IntArray value = (IntArray)getResult();\r
+ value.add(s);\r
+ value.add(p);\r
+ value.add(o);\r
+\r
+ }\r
+\r
+ @Override\r
+ public void performFromCache(ReadGraphImpl graph, QueryProcessor provider, final TripleIntProcedure procedure) {\r
+\r
+ assert(isReady());\r
+\r
+ if(handleException(graph, procedure)) return;\r
+ \r
+ final IntArray value = (IntArray)getResult();\r
+ for(int i=0;i<value.size();i+=3) {\r
+ procedure.execute(graph, value.data[i], value.data[i+1], value.data[i+2]);\r
+ }\r
+\r
+ procedure.finished(graph);\r
+\r
+ }\r
+\r
+ @Override\r
+ public void recompute(ReadGraphImpl graph, QueryProcessor provider) {\r
+\r
+ final Semaphore s = new Semaphore(0);\r
+\r
+ computeForEach(graph, provider, new TripleIntProcedureAdapter() {\r
+\r
+ @Override\r
+ public void finished(ReadGraphImpl graph) {\r
+ s.release();\r
+ }\r
+\r
+ @Override\r
+ public void exception(ReadGraphImpl graph, Throwable t) {\r
+ new Error("Error in recompute.", t).printStackTrace();\r
+ s.release();\r
+ }\r
+\r
+ }, true);\r
+\r
+ while(!s.tryAcquire()) {\r
+ provider.resume(graph);\r
+ }\r
+\r
+ }\r
+\r
+ @Override\r
+ public int type() {\r
+ return RequestFlags.IMMEDIATE_UPDATE;\r
+ }\r
+ */\r
+\r
+}\r