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.util.concurrent.atomic.AtomicInteger;
16 import org.simantics.db.RelationInfo;
17 import org.simantics.db.exception.DatabaseException;
18 import org.simantics.db.exception.ManyObjectsForFunctionalRelationException;
19 import org.simantics.db.impl.graph.ReadGraphImpl;
20 import org.simantics.db.impl.procedure.InternalProcedure;
21 import org.simantics.db.impl.procedure.TripleIntProcedureAdapter;
22 import org.simantics.db.procedure.ListenerBase;
23 import org.simantics.db.request.RequestFlags;
26 final public class AssertedStatements extends CollectionBinaryQuery<TripleIntProcedure> {
28 public AssertedStatements(final int r1, final int r2) {
32 public static AssertedStatements newInstance(final int r1, final int r2) {
33 return new AssertedStatements(r1, r2);
36 // final public static AssertedStatements queryEach(ReadGraphImpl graph, final int r1, final int r2, final QueryProcessor provider, final CacheEntry parent, final ListenerBase listener, final TripleIntProcedure procedure) throws DatabaseException {
41 // return QueryCache.runnerAssertedStatements(graph, r1, r2, parent, listener, procedure);
46 final public void removeEntry(QueryProcessor provider) {
47 provider.cache.remove(this);
50 static void computeInheritedAssertions(ReadGraphImpl graph, int type, final int predicate, final RelationInfo ri, final AssertedStatements entry, final TripleIntProcedure proc) throws DatabaseException {
52 QueryProcessor processor = graph.processor;
54 QueryCache.runnerDirectObjects(graph, type, processor.getInherits(), entry, null, new SyncIntProcedure() {
57 public void run(ReadGraphImpl graph) throws DatabaseException {
59 // if(ri.isFunctional && found.get() == 1) {
61 // ManyObjectsForFunctionalRelationException exception = new ManyObjectsForFunctionalRelationException("Functional relation has assertions from multiple inherited types.");
63 // proc.exception(graph, exception);
74 public void execute(ReadGraphImpl graph, int inh) throws DatabaseException {
76 // if(ri.isFunctional && found.get() == 1) return;
80 QueryCache.runnerAssertedStatements(graph, inh, predicate, entry, null, new TripleIntProcedureAdapter() {
83 public void execute(ReadGraphImpl graph, int s, int p, int o) throws DatabaseException {
85 // if(ri.isFunctional) {
87 //// if(found.get() == 1) return;
89 // if(found.compareAndSet(0, o)) {
90 if(addOrSet(s,p,o, entry))
91 proc.execute(graph, s, p, o);
93 // // If this was a duplicate, we can ignore this
94 // else if (found.compareAndSet(o, o)) {
95 // //System.err.println("duplicates!");
97 // // Otherwise we have error
104 // addOrSet(s, p, o);
105 // proc.execute(graph, s, p, o);
112 public void finished(ReadGraphImpl graph) throws DatabaseException {
117 public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
118 proc.exception(graph, t);
127 public void finished(ReadGraphImpl graph) throws DatabaseException {
135 static void computeLocalAssertions(ReadGraphImpl graph, final int type, final int predicate, final RelationInfo ri, final AssertedStatements entry, final TripleIntProcedure proc) throws DatabaseException {
141 public Object compute(ReadGraphImpl graph, final TripleIntProcedure procedure) throws DatabaseException {
142 computeForEach(graph, r1(), r2(), this, procedure);
146 public static void computeForEach(ReadGraphImpl graph, final int type, final int predicate, final AssertedStatements entry, final TripleIntProcedure procedure) throws DatabaseException {
148 RelationInfo ri = QueryCache.resultRelationInfoQuery(graph, predicate, entry, null);
150 final AtomicInteger found = new AtomicInteger(0);
152 QueryProcessor processor = graph.processor;
154 QueryCache.runnerDirectObjects(graph, type, processor.getAsserts(), entry, null, new SyncIntProcedure() {
157 public void run(ReadGraphImpl graph) throws DatabaseException {
159 if(ri.isFunctional && found.get() > 1) {
161 ManyObjectsForFunctionalRelationException exception = new ManyObjectsForFunctionalRelationException("Functional relation has more than one asserted statement.");
162 except(exception, entry);
163 procedure.exception(graph, exception);
168 if(ri.isFunctional && found.get() == 1) {
170 finish(graph, entry);
171 procedure.finished(graph);
176 computeInheritedAssertions(graph, type, predicate, ri, entry, procedure);
181 public void execute(ReadGraphImpl graph, final int ass) throws DatabaseException {
183 if(ri.isFunctional && found.get() > 1) return;
187 QueryCache.runnerDirectObjects(graph, ass, processor.getHasPredicate(), entry, null, new IntProcedure() {
190 public void execute(ReadGraphImpl graph, final int pred) throws DatabaseException {
192 if(ri.isFunctional) {
194 if(found.get() > 1) return;
198 QueryCache.runnerDirectObjects(graph, ass, processor.getHasObject(), entry, null, new IntProcedure() {
201 public void execute(ReadGraphImpl graph, final int object) throws DatabaseException {
203 if(found.get() > 1) return;
205 if(pred == predicate) {
207 if(found.getAndIncrement() == 0) {
208 if(addOrSet(type, pred, object, entry))
209 procedure.execute(graph, type, pred, object);
220 QueryCache.runnerSuperRelations(graph, pred, entry, null, new InternalProcedure<IntSet>() {
223 public void execute(ReadGraphImpl graph, IntSet result) throws DatabaseException {
225 if(found.get() > 1) {
230 if(result.contains(predicate)) {
232 if(found.getAndIncrement() == 0) {
233 if(addOrSet(type, pred, object, entry))
234 procedure.execute(graph, type, pred, object);
244 public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
246 procedure.exception(graph, t);
258 public void finished(ReadGraphImpl graph) throws DatabaseException {
263 public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
264 procedure.exception(graph, t);
274 QueryCache.runnerDirectObjects(graph, ass, processor.getHasObject(), entry, null, new IntProcedure() {
277 public void execute(ReadGraphImpl graph, final int object) throws DatabaseException {
279 if(pred == predicate) {
281 addOrSet(type, pred, object, entry);
282 procedure.execute(graph, type, pred, object);
291 QueryCache.runnerSuperRelations(graph, pred, entry, null, new InternalProcedure<IntSet>() {
294 public void execute(ReadGraphImpl graph, IntSet result) throws DatabaseException {
296 if(result.contains(predicate)) {
298 addOrSet(type, pred, object, entry);
299 procedure.execute(graph, type, pred, object);
308 public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
309 procedure.exception(graph, t);
320 public void finished(ReadGraphImpl graph) throws DatabaseException {
325 public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
326 procedure.exception(graph, t);
337 public void finished(ReadGraphImpl graph) throws DatabaseException {
342 public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
343 procedure.exception(graph, t);
352 public void finished(ReadGraphImpl graph) throws DatabaseException {
361 public String toString() {
362 return "AssertedStatements[" + r1() + " - " + r2() + "]";
365 private boolean addOrSet(int s, int p, int o) {
369 IntArray value = (IntArray)getResult();
370 if(value.data != null) {
371 for(int i = 0;i < value.sizeOrData ; i+=3) {
372 int existingP = value.data[i+1];
374 int existingO = value.data[i+2];
375 if(existingO == o) return false;
391 static boolean addOrSet(int s, int p, int o, AssertedStatements entry) {
393 return entry.addOrSet(s, p, o);
399 static void finish(ReadGraphImpl graph, AssertedStatements entry) {
401 assert(entry.isPending());
403 synchronized(entry) {
410 static void except(Throwable t, AssertedStatements entry) {
412 synchronized(entry) {
419 public Object performFromCache(ReadGraphImpl graph, final TripleIntProcedure procedure) throws DatabaseException {
423 if(handleException(graph, procedure)) return getResult();
425 final IntArray value = (IntArray)getResult();
426 for(int i=0;i<value.size();i+=3) {
427 procedure.execute(graph, value.data[i], value.data[i+1], value.data[i+2]);
430 procedure.finished(graph);
437 public void recompute(ReadGraphImpl graph) throws DatabaseException {
439 compute(graph, new TripleIntProcedureAdapter() {
442 public void finished(ReadGraphImpl graph) {
446 public void exception(ReadGraphImpl graph, Throwable t) {
447 throw new Error("Error in recompute", t);
456 return RequestFlags.IMMEDIATE_UPDATE;
461 boolean isImmutable(ReadGraphImpl graph) {
462 return graph.processor.isImmutable(r1());