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 gnu.trove.procedure.TIntProcedure;
16 import java.util.concurrent.Semaphore;
18 import org.simantics.db.common.exception.DebugException;
19 import org.simantics.db.impl.graph.ReadGraphImpl;
20 import org.simantics.db.procedure.ListenerBase;
21 import org.simantics.db.request.RequestFlags;
23 final public class Predicates extends UnaryQuery<IntProcedure> {
25 // public ArrayList<IntProcedure> procs;
27 public Predicates(final int r) {
31 public static Predicates newInstance(final int r) {
32 return new Predicates(r);
35 final static Predicates entry(final QueryProcessor provider, final int r) {
37 return (Predicates)provider.predicatesMap.get(r);
41 final static void runner(ReadGraphImpl graph, final int r, final QueryProcessor provider, Predicates cached, final CacheEntry parent, final ListenerBase listener, final IntProcedure procedure) {
43 Predicates entry = cached != null ? cached : (Predicates)provider.predicatesMap.get(r);
46 entry = new Predicates(r);
48 entry.clearResult(provider.querySupport);
49 entry.putEntry(provider);
51 provider.performForEach(graph, entry, parent, listener, procedure);
55 if(entry.isPending()) {
57 if(entry.isPending()) {
58 throw new IllegalStateException();
62 provider.performForEach(graph, entry, parent, listener, procedure);
67 final static IntSet runner2(ReadGraphImpl graph, final int r, final QueryProcessor provider, final CacheEntry parent) throws Throwable {
69 Predicates entry = (Predicates)provider.predicatesMap.get(r);
72 entry = new Predicates(r);
74 entry.clearResult(provider.querySupport);
75 entry.putEntry(provider);
77 return (IntSet)provider.performForEach2(graph, entry, parent, null, null);
81 if(entry.isPending()) {
83 if(entry.isPending()) {
84 throw new IllegalStateException();
88 return (IntSet)provider.performForEach(graph, entry, parent, null, null);
94 final public static void queryEach(ReadGraphImpl graph, final int r, final QueryProcessor provider, final CacheEntry parent, final ListenerBase listener, final IntProcedure procedure) {
98 final Predicates entry = (Predicates)provider.predicatesMap.get(r);
100 if(parent == null && listener == null) {
101 if(entry != null && entry.isReady()) {
102 entry.performFromCache(graph, provider, procedure);
107 runner(graph, r, provider, entry, parent, listener, procedure);
111 final public static IntSet queryEach2(ReadGraphImpl graph, final int r, final QueryProcessor provider, final CacheEntry parent) throws Throwable {
114 final Predicates entry = (Predicates)provider.predicatesMap.get(r);
115 if(entry != null && entry.isReady()) {
116 return (IntSet)entry.get(graph, provider, null);
120 return runner2(graph, r, provider, parent);
125 public UnaryQuery<IntProcedure> getEntry(QueryProcessor provider) {
126 return provider.predicatesMap.get(id);
130 public void putEntry(QueryProcessor provider) {
131 provider.predicatesMap.put(id, this);
135 final public void removeEntry(QueryProcessor provider) {
136 provider.predicatesMap.remove(id);
139 final private void forAssertions(ReadGraphImpl graph, final QueryProcessor queryProvider, final IntProcedure procedure, final boolean store) {
141 PrincipalTypes.queryEach(graph, id, queryProvider, store ? Predicates.this : null, null, new SyncIntProcedure() {
144 public void run(ReadGraphImpl graph) {
146 finish(graph, queryProvider);
147 procedure.finished(graph);
151 IntProcedure proc = new IntProcedure() {
154 public void execute(ReadGraphImpl graph, int i) {
155 if(addOrSet(queryProvider, i))
156 procedure.execute(graph, i);
160 public void finished(ReadGraphImpl graph) {
165 public void exception(ReadGraphImpl graph, Throwable t) {
166 if(DebugException.DEBUG) new DebugException(t).printStackTrace();
167 procedure.exception(graph, t);
173 public void execute(ReadGraphImpl graph, int type) {
177 AssertedPredicates.queryEach(graph, type, queryProvider, store ? Predicates.this : null, null, proc);
182 public void finished(ReadGraphImpl graph) {
192 public Object computeForEach(ReadGraphImpl graph, final QueryProcessor provider, final IntProcedure procedure, final boolean store) {
194 DirectPredicates.queryEach(graph, id, provider, store ? Predicates.this : null, null, new IntProcedure() {
197 public void execute(ReadGraphImpl graph, final int pred) {
199 if(addOrSet(provider, pred))
200 procedure.execute(graph, pred);
205 public void finished(ReadGraphImpl graph) {
207 forAssertions(graph, provider, procedure, store);
212 public void exception(ReadGraphImpl graph, Throwable t) {
213 procedure.exception(graph, t);
223 public String toString() {
224 return "Predicates2[" + id + "]";
227 final public void finish(final ReadGraphImpl graph, QueryProcessor provider) {
229 // ArrayList<IntProcedure> p = null;
241 // final ArrayList<IntProcedure> finalP = p;
243 // IntSet v = (IntSet)getResult();
244 // v.forEach(new TIntProcedure() {
247 // public boolean execute(int arg0) {
248 // for(IntProcedure proc : finalP) proc.execute(graph, arg0);
254 // for(IntProcedure proc : p) proc.finished(graph);
260 synchronized private boolean addOrSet(QueryProcessor processor, int add) {
263 setResult(new IntSet(null));
266 IntSet value = (IntSet)getResult();
267 return value.add(add);
272 public void clearResult(QuerySupport support) {
273 setResult(new IntSet(support));
277 public Object performFromCache(final ReadGraphImpl graph, QueryProcessor provider, final IntProcedure procedure) {
281 if(handleException(graph, procedure)) return EXCEPTED;
283 IntSet v = getResult();
284 if(procedure != null) {
285 v.forEach(new TIntProcedure() {
288 public boolean execute(int arg0) {
289 procedure.execute(graph, arg0);
293 procedure.finished(graph);
301 public void recompute(ReadGraphImpl graph, QueryProcessor provider) {
303 final Semaphore s = new Semaphore(0);
305 computeForEach(graph, provider, new IntProcedure() {
308 public void finished(ReadGraphImpl graph) {
313 public void exception(ReadGraphImpl graph, Throwable t) {
314 throw new Error("Error in recompute.", t);
318 public void execute(ReadGraphImpl graph, int i) {
323 while(!s.tryAcquire()) {
324 provider.resume(graph);
331 return RequestFlags.IMMEDIATE_UPDATE;
336 boolean isImmutable(ReadGraphImpl graph) {
337 return graph.processor.isImmutable(id);