/*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
*******************************************************************************/
package org.simantics.db.impl.query;
-import java.util.ArrayList;
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.atomic.AtomicBoolean;
-
import org.simantics.db.RelationInfo;
import org.simantics.db.exception.DatabaseException;
import org.simantics.db.impl.graph.ReadGraphImpl;
import org.simantics.db.impl.procedure.InternalProcedure;
-import org.simantics.db.procedure.ListenerBase;
import org.simantics.db.request.RequestFlags;
-final public class RelationInfoQuery extends UnaryQuery<InternalProcedure<RelationInfo>> {
-
-// public ArrayList<InternalProcedure<RelationInfo>> procs = null;
-
- private RelationInfoQuery(final int resource) {
- super(resource);
- }
-
- final static RelationInfo runner(ReadGraphImpl graph, final int r, final QueryProcessor provider, final CacheEntry parent, final ListenerBase listener, final InternalProcedure<RelationInfo> procedure) {
+public final class RelationInfoQuery extends UnaryQueryP<RelationInfo> {
- RelationInfoQuery entry = (RelationInfoQuery)provider.relationInfoMap.get(r);
- if(entry == null) {
-
- entry = new RelationInfoQuery(r);
- entry.setPending();
- entry.clearResult(provider.querySupport);
- entry.putEntry(provider);
-
- provider.performForEach(graph, entry, parent, listener, procedure);
-
- return entry.getResult();
-
- } else {
-
- if(!entry.isReady()) {
- synchronized(entry) {
- if(!entry.isReady()) {
- throw new IllegalStateException();
-// if(entry.procs == null) entry.procs = new ArrayList<InternalProcedure<RelationInfo>>();
-// entry.procs.add(procedure);
-// provider.registerDependencies(graph, entry, parent, listener, procedure, false);
-// return entry.getResult();
- }
- }
- }
- provider.performForEach(graph, entry, parent, listener, procedure);
-
- return entry.getResult();
-
- }
+ RelationInfoQuery(int resource) {
+ super(resource);
+ }
- }
-
- final public static RelationInfo queryEach(ReadGraphImpl graph, final int r, final QueryProcessor provider, final CacheEntry parent, final ListenerBase listener, final InternalProcedure<RelationInfo> procedure) {
-
- RelationInfoQuery entry = (RelationInfoQuery)provider.relationInfoMap.get(r);
- if(entry != null && entry.isReady()) {
- entry.performFromCache(graph, provider, procedure);
- return entry.getResult();
- }
+ @Override
+ public final void removeEntry(QueryProcessor provider) {
+ provider.cache.remove(this);
+ }
- return runner(graph, r, provider, parent, listener, procedure);
-
- }
-
- final public static RelationInfoQuery probe(ReadGraphImpl graph, int resource) {
-
- final int thread = graph.thread(resource);
- RelationInfoQuery entry = (RelationInfoQuery)graph.processor.relationInfoMap.get(resource);
- if(entry != null && entry.isReady()) {
- return entry;
- } else {
- return null;
- }
-
- }
+ private static void computeAssertions(ReadGraphImpl graph, int r, final boolean isFinal, final boolean isFunctional, RelationInfoQuery parent, final InternalProcedure<RelationInfo> procedure) throws DatabaseException {
- @Override
- public UnaryQuery<InternalProcedure<RelationInfo>> getEntry(QueryProcessor provider) {
- return provider.relationInfoMap.get(id);
- }
-
- @Override
- public void putEntry(QueryProcessor provider) {
- provider.relationInfoMap.put(id, this);
- }
+ QueryProcessor processor = graph.processor;
- @Override
- final public void removeEntry(QueryProcessor provider) {
- provider.relationInfoMap.remove(id);
- }
+ final int isUsedInAssertion = processor.getHasPredicateInverse();
+ assert(isUsedInAssertion != 0);
- private void computeAssertions(ReadGraphImpl graph, final boolean isFinal, final boolean isFunctional, final QueryProcessor queryProvider, final InternalProcedure<RelationInfo> proc) {
+ QueryCache.runnerDirectObjects(graph, r, isUsedInAssertion, parent, null, new IntProcedure() {
- final int isUsedInAssertion = queryProvider.getHasPredicateInverse();
- assert(isUsedInAssertion != 0);
-
- DirectObjects.queryEach(graph, id, isUsedInAssertion, queryProvider, this, null, new IntProcedure() {
+ boolean done = false;
- AtomicBoolean done = new AtomicBoolean(false);
-
@Override
- public void execute(ReadGraphImpl graph, int i) {
- if(done.compareAndSet(false, true)) {
-// System.err.println("Assertions for relation " + id);
- RelationInfo result = new RelationInfo(id, isFunctional, isFinal, true);
- addOrSet(graph, result, queryProvider);
- proc.execute(graph, result);
- }
+ public void execute(ReadGraphImpl graph, int i) throws DatabaseException {
+ if(done) return;
+ done = true;
+ RelationInfo result = new RelationInfo(r, isFunctional, isFinal, true);
+ procedure.execute(graph, result);
}
@Override
- public void finished(ReadGraphImpl graph) {
- if(done.compareAndSet(false, true)) {
-// System.err.println("No assertions for relation " + id);
- RelationInfo result = new RelationInfo(id, isFunctional, isFinal, false);
- addOrSet(graph, result, queryProvider);
- proc.execute(graph, result);
- }
+ public void finished(ReadGraphImpl graph) throws DatabaseException {
+ if(done) return;
+ done = true;
+ RelationInfo result = new RelationInfo(r, isFunctional, isFinal, false);
+ procedure.execute(graph, result);
}
@Override
- public void exception(ReadGraphImpl graph, Throwable throwable) {
- if(done.compareAndSet(false, true)) {
- DatabaseException e = new DatabaseException("Internal error in RelationInfoQuery");
- except(e);
- proc.exception(graph, e);
- }
+ public void exception(ReadGraphImpl graph, Throwable throwable) throws DatabaseException {
+ if(done) return;
+ done = true;
+ DatabaseException e = new DatabaseException("Internal error in RelationInfoQuery");
+ procedure.exception(graph, e);
}
-
- });
-
-// Types.queryEach(callerThread, id, queryProvider, this, null, new InternalProcedure<IntSet>() {
-//
-// @Override
-// public void execute(int callerThread, IntSet types) {
-// computeAssertions(callerThread, isFinal, isFunctional, queryProvider, proc);
-////
-////
-////// System.out.println("RelationInfoQuery: computeTypes execute " + types);
-////
-//// RelationInfo result = new RelationInfo(id, types.contains(queryProvider.getFunctionalRelation()), isFinal);
-////
-//// addOrSet(callerThread, result, queryProvider);
-////
-//// proc.execute(callerThread, result);
-////
-// }
-//
-// @Override
-// public void exception(int callerThread, Throwable t) {
-// proc.exception(callerThread, t);
-// }
-//
-// });
- }
-
- private void computeTypes(ReadGraphImpl graph, final boolean isFinal, final QueryProcessor queryProvider, final InternalProcedure<RelationInfo> proc) {
-
-// System.out.println("RelationInfoQuery: computeTypes " + id);
-
- Types.queryEach(graph, id, queryProvider, this, null, new InternalProcedure<IntSet>() {
-
- @Override
- public void execute(ReadGraphImpl graph, IntSet types) {
- computeAssertions(graph, isFinal, types.contains(queryProvider.getFunctionalRelation()), queryProvider, proc);
-//
-//// System.out.println("RelationInfoQuery: computeTypes execute " + types);
-//
-// RelationInfo result = new RelationInfo(id, types.contains(queryProvider.getFunctionalRelation()), isFinal);
-//
-// addOrSet(callerThread, result, queryProvider);
-//
-// proc.execute(callerThread, result);
-//
- }
-
- @Override
- public void exception(ReadGraphImpl graph, Throwable t) {
- proc.exception(graph, t);
- }
+ });
- });
+ }
- }
-
- @Override
- public Object computeForEach(ReadGraphImpl graph, final QueryProcessor provider, final InternalProcedure<RelationInfo> procedure, boolean store) {
-
-// System.out.println("RelationInfoQuery computeForEach begin " + id + " " + getResult() + " " + statusOrException);
+ public static void computeForEach(ReadGraphImpl graph, int r, RelationInfoQuery entry, InternalProcedure<RelationInfo> procedure_) throws DatabaseException {
- final int superRelationOf = provider.getSuperrelationOf();
- assert(superRelationOf != 0);
-
- DirectPredicates.queryEach(graph, id, provider, this, null, new IntProcedure() {
-
- boolean found = false;
+ InternalProcedure<RelationInfo> procedure = entry != null ? entry : procedure_;
- @Override
- public void execute(ReadGraphImpl graph, int i) {
-// System.out.println("RelationInfoQuery: execute " + i + " super = " + superRelationOf);
- if(i == superRelationOf) {
- computeTypes(graph, false, provider, procedure);
- found = true;
- }
- }
+ QueryProcessor provider = graph.processor;
- @Override
- public void finished(ReadGraphImpl graph) {
-// System.out.println("RelationInfoQuery: finished");
- if(!found) {
- computeTypes(graph, true, provider, procedure);
- }
- }
-
- @Override
- public void exception(ReadGraphImpl graph, Throwable t) {
-// System.out.println("RelationInfoQuery: exception");
- procedure.exception(graph, t);
- }
+ final int superRelationOf = provider.getSuperrelationOf();
+ assert(superRelationOf != 0);
- });
-
- return getResult();
-
- }
-
- @Override
- public String toString() {
- return "RelationInfoQuery[" + id + "]";
- }
+ IntSet direct = QueryCache.resultDirectPredicates(graph, r, entry, null);
+ IntSet types = QueryCache.resultTypes(graph, r, entry, null);
- public void addOrSet(ReadGraphImpl graph, final RelationInfo result, final QueryProcessor provider) {
-
- assert(isPending());
-
-// ArrayList<InternalProcedure<RelationInfo>> p = null;
-
- synchronized(this) {
+ computeAssertions(graph, r, !direct.contains(superRelationOf), types.contains(graph.processor.getFunctionalRelation()), entry, procedure);
- setResult(result);
- setReady();
-
-// p = procs;
-// procs = null;
-
- }
-
-// if(p != null) {
-// for(InternalProcedure<RelationInfo> proc : p)
-// proc.execute(graph, (RelationInfo)result);
-// }
-
- }
+ if(entry != null) entry.performFromCache(graph, procedure_);
- @Override
- public Object performFromCache(ReadGraphImpl graph, QueryProcessor provider, InternalProcedure<RelationInfo> procedure) {
+ }
- assert(isReady());
-
- if(handleException(graph, procedure)) return EXCEPTED;
-
- RelationInfo result = getResult();
-
- procedure.execute(graph, result);
-
- return result;
+ @Override
+ public void compute(ReadGraphImpl graph, final InternalProcedure<RelationInfo> procedure) throws DatabaseException {
+ computeForEach(graph, id, this, procedure);
+ }
- }
-
- @Override
- public void recompute(ReadGraphImpl graph, QueryProcessor provider) {
-
- final Semaphore s = new Semaphore(0);
-
- computeForEach(graph, provider, new InternalProcedure<RelationInfo>() {
+ @Override
+ public String toString() {
+ return "RelationInfoQuery[" + id + "]";
+ }
- @Override
- public void execute(ReadGraphImpl graph, RelationInfo result) {
- s.release();
- }
-
- @Override
- public void exception(ReadGraphImpl graph, Throwable t) {
- throw new Error("Error in recompute.", t);
- }
+ @Override
+ public void setResult(Object result) {
+ super.setResult(result);
+ setReady();
+ }
- }, true);
-
- while(!s.tryAcquire()) {
- provider.resume(graph);
- }
-// try {
-// s.acquire();
-// } catch (InterruptedException e) {
-// throw new Error(e);
-// }
+ @Override
+ public int type() {
+ return RequestFlags.IMMEDIATE_UPDATE;
+ }
- }
-
- @Override
- public int type() {
- return RequestFlags.IMMEDIATE_UPDATE;
- }
-
}