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 Predicates(final int r) {
29 public static Predicates newInstance(final int r) {
30 return new Predicates(r);
33 final static Predicates entry(final QueryProcessor provider, final int r) {
35 return (Predicates)provider.cache.predicatesMap.get(r);
39 final static void runner(ReadGraphImpl graph, final int r, final QueryProcessor provider, Predicates cached, final CacheEntry parent, final ListenerBase listener, final IntProcedure procedure) {
41 Predicates entry = cached != null ? cached : (Predicates)provider.cache.predicatesMap.get(r);
44 entry = new Predicates(r);
46 entry.clearResult(provider.querySupport);
47 entry.putEntry(provider);
49 provider.performForEach(graph, entry, parent, listener, procedure);
53 if(entry.isPending()) {
55 if(entry.isPending()) {
56 throw new IllegalStateException();
60 provider.performForEach(graph, entry, parent, listener, procedure);
65 final static IntSet runner2(ReadGraphImpl graph, final int r, final QueryProcessor provider, final CacheEntry parent) throws Throwable {
67 Predicates entry = (Predicates)provider.cache.predicatesMap.get(r);
70 entry = new Predicates(r);
72 entry.clearResult(provider.querySupport);
73 entry.putEntry(provider);
75 return (IntSet)provider.performForEach2(graph, entry, parent, null, null);
79 if(entry.isPending()) {
81 if(entry.isPending()) {
82 throw new IllegalStateException();
86 return (IntSet)provider.performForEach(graph, entry, parent, null, null);
92 final public static void queryEach(ReadGraphImpl graph, final int r, final QueryProcessor provider, final CacheEntry parent, final ListenerBase listener, final IntProcedure procedure) {
96 final Predicates entry = (Predicates)provider.cache.predicatesMap.get(r);
98 if(parent == null && listener == null) {
99 if(entry != null && entry.isReady()) {
100 entry.performFromCache(graph, provider, procedure);
105 runner(graph, r, provider, entry, parent, listener, procedure);
109 final public static IntSet queryEach2(ReadGraphImpl graph, final int r, final QueryProcessor provider, final CacheEntry parent) throws Throwable {
112 final Predicates entry = (Predicates)provider.cache.predicatesMap.get(r);
113 if(entry != null && entry.isReady()) {
114 return (IntSet)entry.get(graph, provider, null);
118 return runner2(graph, r, provider, parent);
123 public UnaryQuery<IntProcedure> getEntry(QueryProcessor provider) {
124 return provider.cache.predicatesMap.get(id);
128 public void putEntry(QueryProcessor provider) {
129 provider.cache.predicatesMap.put(id, this);
133 final public void removeEntry(QueryProcessor provider) {
134 provider.cache.predicatesMap.remove(id);
137 final private void forAssertions(ReadGraphImpl graph, final QueryProcessor queryProvider, final IntProcedure procedure, final boolean store) {
139 PrincipalTypes.queryEach(graph, id, queryProvider, store ? Predicates.this : null, null, new SyncIntProcedure() {
142 public void run(ReadGraphImpl graph) {
144 finish(graph, queryProvider);
145 procedure.finished(graph);
149 IntProcedure proc = new IntProcedure() {
152 public void execute(ReadGraphImpl graph, int i) {
153 if(addOrSet(queryProvider, i))
154 procedure.execute(graph, i);
158 public void finished(ReadGraphImpl graph) {
163 public void exception(ReadGraphImpl graph, Throwable t) {
164 if(DebugException.DEBUG) new DebugException(t).printStackTrace();
165 procedure.exception(graph, t);
171 public void execute(ReadGraphImpl graph, int type) {
175 AssertedPredicates.queryEach(graph, type, queryProvider, store ? Predicates.this : null, null, proc);
180 public void finished(ReadGraphImpl graph) {
190 public Object computeForEach(ReadGraphImpl graph, final QueryProcessor provider, final IntProcedure procedure, final boolean store) {
192 DirectPredicates.queryEach(graph, id, provider, store ? Predicates.this : null, null, new IntProcedure() {
195 public void execute(ReadGraphImpl graph, final int pred) {
197 if(addOrSet(provider, pred))
198 procedure.execute(graph, pred);
203 public void finished(ReadGraphImpl graph) {
205 forAssertions(graph, provider, procedure, store);
210 public void exception(ReadGraphImpl graph, Throwable t) {
211 procedure.exception(graph, t);
221 public String toString() {
222 return "Predicates2[" + id + "]";
225 final public void finish(final ReadGraphImpl graph, QueryProcessor provider) {
227 // ArrayList<IntProcedure> p = null;
239 // final ArrayList<IntProcedure> finalP = p;
241 // IntSet v = (IntSet)getResult();
242 // v.forEach(new TIntProcedure() {
245 // public boolean execute(int arg0) {
246 // for(IntProcedure proc : finalP) proc.execute(graph, arg0);
252 // for(IntProcedure proc : p) proc.finished(graph);
258 synchronized private boolean addOrSet(QueryProcessor processor, int add) {
261 setResult(new IntSet(null));
264 IntSet value = (IntSet)getResult();
265 return value.add(add);
270 public void clearResult(QuerySupport support) {
271 setResult(new IntSet(support));
275 public Object performFromCache(final ReadGraphImpl graph, QueryProcessor provider, final IntProcedure procedure) {
279 if(handleException(graph, procedure)) return EXCEPTED;
281 IntSet v = getResult();
282 if(procedure != null) {
283 v.forEach(new TIntProcedure() {
286 public boolean execute(int arg0) {
287 procedure.execute(graph, arg0);
291 procedure.finished(graph);
299 public void recompute(ReadGraphImpl graph, QueryProcessor provider) {
301 final Semaphore s = new Semaphore(0);
303 computeForEach(graph, provider, new IntProcedure() {
306 public void finished(ReadGraphImpl graph) {
311 public void exception(ReadGraphImpl graph, Throwable t) {
312 throw new Error("Error in recompute.", t);
316 public void execute(ReadGraphImpl graph, int i) {
321 while(!s.tryAcquire()) {
322 provider.resume(graph);
329 return RequestFlags.IMMEDIATE_UPDATE;
334 boolean isImmutable(ReadGraphImpl graph) {
335 return graph.processor.isImmutable(id);