1 /*******************************************************************************
2 * Copyright (c) 2007, 2018 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.request.RequestFlags;
25 final public class AssertedStatements extends CollectionBinaryQuery<TripleIntProcedure> {
27 public AssertedStatements(final int r1, final int r2) {
31 public static AssertedStatements newInstance(final int r1, final int r2) {
32 return new AssertedStatements(r1, r2);
36 final public void removeEntry(QueryProcessor provider) {
37 provider.cache.remove(this);
40 static void computeInheritedAssertions(ReadGraphImpl graph, int type, final int predicate, final RelationInfo ri, final AssertedStatements entry, final TripleIntProcedure proc) throws DatabaseException {
42 QueryProcessor processor = graph.processor;
44 QueryCache.runnerDirectObjects(graph, type, processor.getInherits(), entry, null, new SyncIntProcedure() {
47 public void run(ReadGraphImpl graph) throws DatabaseException {
49 // if(ri.isFunctional && found.get() == 1) {
51 // ManyObjectsForFunctionalRelationException exception = new ManyObjectsForFunctionalRelationException("Functional relation has assertions from multiple inherited types.");
53 // proc.exception(graph, exception);
64 public void execute(ReadGraphImpl graph, int inh) throws DatabaseException {
66 // if(ri.isFunctional && found.get() == 1) return;
70 QueryCache.runnerAssertedStatements(graph, inh, predicate, entry, null, new TripleIntProcedureAdapter() {
73 public void execute(ReadGraphImpl graph, int s, int p, int o) throws DatabaseException {
75 // if(ri.isFunctional) {
77 //// if(found.get() == 1) return;
79 // if(found.compareAndSet(0, o)) {
80 if(addOrSet(s,p,o, entry))
81 proc.execute(graph, s, p, o);
83 // // If this was a duplicate, we can ignore this
84 // else if (found.compareAndSet(o, o)) {
85 // //System.err.println("duplicates!");
87 // // Otherwise we have error
95 // proc.execute(graph, s, p, o);
102 public void finished(ReadGraphImpl graph) throws DatabaseException {
107 public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
108 proc.exception(graph, t);
117 public void finished(ReadGraphImpl graph) throws DatabaseException {
125 static void computeLocalAssertions(ReadGraphImpl graph, final int type, final int predicate, final RelationInfo ri, final AssertedStatements entry, final TripleIntProcedure proc) throws DatabaseException {
131 public Object compute(ReadGraphImpl graph, final TripleIntProcedure procedure) throws DatabaseException {
132 computeForEach(graph, r1(), r2(), this, procedure);
136 public static void computeForEach(ReadGraphImpl graph, final int type, final int predicate, final AssertedStatements entry, final TripleIntProcedure procedure) throws DatabaseException {
138 RelationInfo ri = QueryCache.resultRelationInfoQuery(graph, predicate, entry, null);
140 final AtomicInteger found = new AtomicInteger(0);
142 QueryProcessor processor = graph.processor;
144 QueryCache.runnerDirectObjects(graph, type, processor.getAsserts(), entry, null, new SyncIntProcedure() {
147 public void run(ReadGraphImpl graph) throws DatabaseException {
149 if(ri.isFunctional && found.get() > 1) {
151 ManyObjectsForFunctionalRelationException exception = new ManyObjectsForFunctionalRelationException("Functional relation has more than one asserted statement.");
152 except(exception, entry);
153 procedure.exception(graph, exception);
158 if(ri.isFunctional && found.get() == 1) {
160 finish(graph, entry);
161 procedure.finished(graph);
166 computeInheritedAssertions(graph, type, predicate, ri, entry, procedure);
171 public void execute(ReadGraphImpl graph, final int ass) throws DatabaseException {
173 if(ri.isFunctional && found.get() > 1) return;
177 QueryCache.runnerDirectObjects(graph, ass, processor.getHasPredicate(), entry, null, new IntProcedure() {
180 public void execute(ReadGraphImpl graph, final int pred) throws DatabaseException {
182 if(ri.isFunctional) {
184 if(found.get() > 1) return;
188 QueryCache.runnerDirectObjects(graph, ass, processor.getHasObject(), entry, null, new IntProcedure() {
191 public void execute(ReadGraphImpl graph, final int object) throws DatabaseException {
193 if(found.get() > 1) return;
195 if(pred == predicate) {
197 if(found.getAndIncrement() == 0) {
198 if(addOrSet(type, pred, object, entry))
199 procedure.execute(graph, type, pred, object);
210 QueryCache.runnerSuperRelations(graph, pred, entry, null, new InternalProcedure<IntSet>() {
213 public void execute(ReadGraphImpl graph, IntSet result) throws DatabaseException {
215 if(found.get() > 1) {
220 if(result.contains(predicate)) {
222 if(found.getAndIncrement() == 0) {
223 if(addOrSet(type, pred, object, entry))
224 procedure.execute(graph, type, pred, object);
234 public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
236 procedure.exception(graph, t);
248 public void finished(ReadGraphImpl graph) throws DatabaseException {
253 public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
254 procedure.exception(graph, t);
264 QueryCache.runnerDirectObjects(graph, ass, processor.getHasObject(), entry, null, new IntProcedure() {
267 public void execute(ReadGraphImpl graph, final int object) throws DatabaseException {
269 if(pred == predicate) {
271 addOrSet(type, pred, object, entry);
272 procedure.execute(graph, type, pred, object);
281 QueryCache.runnerSuperRelations(graph, pred, entry, null, new InternalProcedure<IntSet>() {
284 public void execute(ReadGraphImpl graph, IntSet result) throws DatabaseException {
286 if(result.contains(predicate)) {
288 addOrSet(type, pred, object, entry);
289 procedure.execute(graph, type, pred, object);
298 public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
299 procedure.exception(graph, t);
310 public void finished(ReadGraphImpl graph) throws DatabaseException {
315 public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
316 procedure.exception(graph, t);
327 public void finished(ReadGraphImpl graph) throws DatabaseException {
332 public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
333 procedure.exception(graph, t);
342 public void finished(ReadGraphImpl graph) throws DatabaseException {
351 public String toString() {
352 return "AssertedStatements[" + r1() + " - " + r2() + "]";
355 private boolean addOrSet(int s, int p, int o) {
359 IntArray value = (IntArray)getResult();
360 if(value.data != null) {
361 for(int i = 0;i < value.sizeOrData ; i+=3) {
362 int existingP = value.data[i+1];
364 int existingO = value.data[i+2];
365 if(existingO == o) return false;
381 static boolean addOrSet(int s, int p, int o, AssertedStatements entry) {
383 return entry.addOrSet(s, p, o);
389 static void finish(ReadGraphImpl graph, AssertedStatements entry) {
391 assert(entry.isPending());
393 synchronized(entry) {
400 static void except(Throwable t, AssertedStatements entry) {
402 synchronized(entry) {
409 public Object performFromCache(ReadGraphImpl graph, final TripleIntProcedure procedure) throws DatabaseException {
413 if(handleException(graph, procedure)) return getResult();
415 final IntArray value = (IntArray)getResult();
416 for(int i=0;i<value.size();i+=3) {
417 procedure.execute(graph, value.data[i], value.data[i+1], value.data[i+2]);
420 procedure.finished(graph);
427 public void recompute(ReadGraphImpl graph) throws DatabaseException {
429 compute(graph, new TripleIntProcedureAdapter() {
432 public void finished(ReadGraphImpl graph) {
436 public void exception(ReadGraphImpl graph, Throwable t) {
437 throw new Error("Error in recompute", t);
446 return RequestFlags.IMMEDIATE_UPDATE;
451 boolean isImmutable(ReadGraphImpl graph) {
452 return graph.processor.isImmutable(r1());