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 org.simantics.db.impl.graph.ReadGraphImpl;
15 import org.simantics.db.procedure.AsyncProcedure;
16 import org.simantics.db.procedure.ListenerBase;
17 import org.simantics.db.procedure.Procedure;
20 final public class DirectStatements /*extends CollectionBinaryQuery<TripleIntProcedure>*/ {
23 public DirectStatements(final int r1, final int r2) {
27 public static DirectStatements newInstance(final int r1, final int r2) {
28 return new DirectStatements(r1, r2);
31 final static DirectStatements entry(final QueryProcessor provider, final int r1, final int r2) {
33 return (DirectStatements)provider.statementsMap[provider.resourceThread(r1)].get(id(r1,r2));
37 final static Collection<DirectStatements> entries(final QueryProcessor processor, final int r1) {
38 BinaryQueryHashMap<TripleIntProcedure> hash = processor.statementsMap[processor.resourceThread(r1)];
39 return hash.values(r1);
43 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) {
47 org.simantics.db.DirectStatements result = provider.querySupport.getStatements(graph, r, provider, ignoreVirtual);
48 procedure.execute(graph, result);
52 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) {
58 org.simantics.db.DirectStatements result = provider.querySupport.getStatements(graph, r, provider, true);
59 procedure.execute(result);
61 // provider.querySupport.getStatements(graph, r, procedure);
63 } catch (Throwable t) {
73 public BinaryQuery<TripleIntProcedure> getEntry(int callerThread, QueryProcessor provider) {
74 return provider.statementsMap[callerThread].get(id);
78 public void putEntry(int callerThread, QueryProcessor provider) {
79 provider.statementsMap[callerThread].put(id, this);
83 final public void removeEntry(int callerThread, QueryProcessor provider) {
84 provider.statementsMap[callerThread].remove(id);
87 final private void forSingleAssertion(ReadGraphImpl graph, final QueryProcessor queryProvider, final TripleIntProcedure procedure) {
89 final AtomicInteger results = new AtomicInteger();
91 PrincipalTypes.queryEach(graph, r1(), queryProvider, this, null, new SyncIntProcedure() {
94 public void run(ReadGraphImpl graph) {
96 int rc = results.get();
100 procedure.exception(graph, (Throwable)getResult());
104 // No result or single result
105 if(rc == 0 || rc == 1) {
107 finish(graph, queryProvider);
108 procedure.finished(graph);
112 ManyObjectsForFunctionalRelationException exception = new ManyObjectsForFunctionalRelationException("Functional relation has more than one statement.", r1());
114 procedure.exception(graph, exception);
123 public void execute(ReadGraphImpl graph, int type) {
127 AssertedStatements.queryEach(graph, type, r2(), queryProvider, DirectStatements.this, null, new TripleIntProcedureAdapter() {
130 public void execute(ReadGraphImpl graph, int s, int p, int o) {
132 int event = results.getAndIncrement();
136 procedure.execute(graph, s, p, o);
143 public void finished(ReadGraphImpl graph) {
150 public void exception(ReadGraphImpl graph, Throwable t) {
162 public void finished(ReadGraphImpl graph) {
172 // Search for one statement
173 final public void computeFunctionalIndex(ReadGraphImpl graph, final QueryProcessor provider, final RelationInfo ri, final TripleIntProcedure procedure, final boolean store) {
177 boolean found = provider.querySupport.getObjects(graph, r1(), r2(), new IntProcedure() {
180 public void execute(ReadGraphImpl graph, int i) {
181 addOrSet(r1(), r2(), i);
185 public void exception(ReadGraphImpl graph, Throwable t) {
186 if(DebugException.DEBUG) new DebugException(t).printStackTrace();
190 public void finished(ReadGraphImpl graph) {
195 // If functional relation was found there is no need to check assertions
198 final IntArray array = (IntArray)getResult();
199 if(array.size() > 3) {
200 Throwable exception = new ManyObjectsForFunctionalRelationException("Functional relation " + r2() + " has multiple objects " + Arrays.toString(array.toArray()) + " for subject " + r1());
202 procedure.exception(graph, exception);
205 procedure.execute(graph, array.data[0], array.data[1], array.data[2]);
206 finish(graph, provider);
207 procedure.finished(graph);
212 // Check for assertions
213 forSingleAssertion(graph, provider, procedure);
218 final AtomicBoolean found = new AtomicBoolean(false);
220 DirectPredicates.queryEach(graph, r1(), provider, DirectStatements.this, null, new SyncIntProcedure() {
223 public void run(ReadGraphImpl graph) {
225 if(found.get()) return;
227 // Check for assertions
228 forSingleAssertion(graph, provider, procedure);
233 public void execute(ReadGraphImpl graph, final int pred) {
235 if(found.get()) return;
241 DirectObjects.queryEach(graph, r1(), pred, provider, DirectStatements.this, null, new IntProcedure() {
244 public void execute(ReadGraphImpl graph, int i) {
246 if(found.compareAndSet(false, true)) {
248 addOrSet(r1(), pred, i);
249 finish(graph, provider);
250 procedure.execute(graph, r1(), pred, i);
251 procedure.finished(graph);
255 ManyObjectsForFunctionalRelationException exception = new ManyObjectsForFunctionalRelationException("Functional relation has more than one statement.", r1());
257 procedure.exception(graph, exception);
264 public void finished(ReadGraphImpl graph) {
271 public void exception(ReadGraphImpl graph, Throwable t) {
272 procedure.exception(graph, t);
281 SuperRelations.queryEach(graph, pred, provider, DirectStatements.this, null, new InternalProcedure<IntSet>() {
284 public void execute(ReadGraphImpl graph, IntSet result) {
291 if(result.contains(r2())) {
295 DirectObjects.queryEach(graph, r1(), pred, provider, DirectStatements.this, null, new IntProcedure() {
298 public void execute(ReadGraphImpl graph, int i) {
300 if(found.compareAndSet(false, true)) {
302 addOrSet(r1(), pred, i);
303 finish(graph, provider);
304 procedure.execute(graph, r1(), pred, i);
305 procedure.finished(graph);
309 ManyObjectsForFunctionalRelationException exception = new ManyObjectsForFunctionalRelationException("Functional relation has more than one statement.", r1());
311 procedure.exception(graph, exception);
318 public void finished(ReadGraphImpl graph) {
325 public void exception(ReadGraphImpl graph, Throwable t) {
326 procedure.exception(graph, t);
338 public void exception(ReadGraphImpl graph, Throwable t) {
339 procedure.exception(graph, t);
349 public void finished(ReadGraphImpl graph) {
361 final private void forAssertions(ReadGraphImpl graph, final QueryProcessor queryProvider, final TripleIntProcedure procedure) {
363 PrincipalTypes.queryEach(graph, r1(), queryProvider, this, null, new SyncIntProcedure() {
366 public void run(ReadGraphImpl graph) {
368 finish(graph, queryProvider);
369 procedure.finished(graph);
373 TripleIntProcedure proc = new TripleIntProcedureAdapter() {
376 public void execute(ReadGraphImpl graph, int s, int p, int o) {
378 procedure.execute(graph, s, p, o);
382 public void finished(ReadGraphImpl graph) {
387 public void exception(ReadGraphImpl graph, Throwable t) {
388 procedure.exception(graph, t);
394 public void execute(ReadGraphImpl graph, int type) {
398 AssertedStatements.queryEach(graph, type, r2(), queryProvider, DirectStatements.this, null, proc);
403 public void finished(ReadGraphImpl graph) {
412 final public void computeNotFunctionalIndex(ReadGraphImpl graph, final QueryProcessor provider, RelationInfo ri, final TripleIntProcedure procedure, final boolean store) {
416 provider.querySupport.getObjects(graph, r1(), r2(), new IntProcedure() {
419 public void execute(ReadGraphImpl graph, int i) {
420 addOrSet(r1(), r2(), i);
424 public void exception(ReadGraphImpl graph, Throwable t) {
425 if(DebugException.DEBUG) new DebugException(t).printStackTrace();
426 procedure.exception(graph, t);
430 public void finished(ReadGraphImpl graph) {
435 final IntArray value = (IntArray)getResult();
436 for(int i=0;i<value.size();i+=3) {
437 procedure.execute(graph, value.data[i], value.data[i+1], value.data[i+2]);
440 forAssertions(graph, provider, procedure);
444 DirectPredicates.queryEach(graph, r1(), provider, DirectStatements.this, null, new SyncIntProcedure() {
447 public void run(ReadGraphImpl graph) {
449 forAssertions(graph, provider, procedure);
454 public void execute(ReadGraphImpl graph, final int pred) {
456 // System.out.println("directpredicates execute " + pred);
462 DirectObjects.queryEach(graph, r1(), pred, provider, DirectStatements.this, null, new IntProcedure() {
465 public void execute(ReadGraphImpl graph, int i) {
466 // System.out.println("pred=" + pred + " object=" + i);
467 addOrSet(r1(), pred, i);
468 procedure.execute(graph, r1(), pred, i);
472 public void finished(ReadGraphImpl graph) {
477 public void exception(ReadGraphImpl graph, Throwable t) {
478 procedure.exception(graph, t);
487 SuperRelations.queryEach(graph, pred, provider, DirectStatements.this, null, new InternalProcedure<IntSet>() {
490 public void execute(ReadGraphImpl graph, IntSet result) {
492 if(result.contains(r2())) {
496 DirectObjects.queryEach(graph, r1(), pred, provider, DirectStatements.this, null, new IntProcedure() {
499 public void execute(ReadGraphImpl graph, int i) {
502 // System.out.println("s=" + r1() + "p=" + pred + " o=" + i);
504 addOrSet(r1(), pred, i);
505 procedure.execute(graph, r1(), pred, i);
510 public void finished(ReadGraphImpl graph) {
515 public void exception(ReadGraphImpl graph, Throwable t) {
516 procedure.exception(graph, t);
528 public void exception(ReadGraphImpl graph, Throwable t) {
529 procedure.exception(graph, t);
539 public void finished(ReadGraphImpl graph) {
551 public void computeForEach(ReadGraphImpl graph, final QueryProcessor provider, final TripleIntProcedure procedure, final boolean store) {
553 RelationInfoQuery.queryEach(graph, r2(), provider, this, null, new InternalProcedure<RelationInfo>() {
556 public void execute(ReadGraphImpl graph, final RelationInfo ri) {
558 provider.querySupport.ensureLoaded(graph, r1(), r2());
559 if(ri.isFunctional) {
560 computeFunctionalIndex(graph, provider, ri, procedure, store);
562 computeNotFunctionalIndex(graph, provider, ri, procedure, store);
568 public void exception(ReadGraphImpl graph, Throwable t) {
569 procedure.exception(graph, t);
577 public String toString() {
578 return "Statements[" + r1() + " - " + r2() + "]";
581 final private void finish(ReadGraphImpl graph, QueryProcessor provider) {
591 synchronized public void addOrSet(int s, int p, int o) {
595 IntArray value = (IntArray)getResult();
603 public void performFromCache(ReadGraphImpl graph, QueryProcessor provider, final TripleIntProcedure procedure) {
607 if(handleException(graph, procedure)) return;
609 final IntArray value = (IntArray)getResult();
610 for(int i=0;i<value.size();i+=3) {
611 procedure.execute(graph, value.data[i], value.data[i+1], value.data[i+2]);
614 procedure.finished(graph);
619 public void recompute(ReadGraphImpl graph, QueryProcessor provider) {
621 final Semaphore s = new Semaphore(0);
623 computeForEach(graph, provider, new TripleIntProcedureAdapter() {
626 public void finished(ReadGraphImpl graph) {
631 public void exception(ReadGraphImpl graph, Throwable t) {
632 new Error("Error in recompute.", t).printStackTrace();
638 while(!s.tryAcquire()) {
639 provider.resume(graph);
646 return RequestFlags.IMMEDIATE_UPDATE;