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