1 /*******************************************************************************
\r
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
\r
3 * in Industry THTH ry.
\r
4 * All rights reserved. This program and the accompanying materials
\r
5 * are made available under the terms of the Eclipse Public License v1.0
\r
6 * which accompanies this distribution, and is available at
\r
7 * http://www.eclipse.org/legal/epl-v10.html
\r
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.db.impl.query;
\r
14 import gnu.trove.procedure.TIntProcedure;
\r
16 import java.util.concurrent.Semaphore;
\r
17 import java.util.concurrent.atomic.AtomicInteger;
\r
19 import org.simantics.db.impl.graph.ReadGraphImpl;
\r
20 import org.simantics.db.impl.procedure.InternalProcedure;
\r
21 import org.simantics.db.procedure.ListenerBase;
\r
23 final public class Types extends UnaryQuery<InternalProcedure<IntSet>> {
\r
25 // public ArrayList<InternalProcedure<IntSet>> procs;
\r
27 private Types(final int resource) {
\r
31 final static Types entry(final QueryProcessor provider, final int r) {
\r
32 return (Types)provider.typesMap.get(r);
\r
35 final static void runner(ReadGraphImpl graph, final int r, final QueryProcessor provider, Types cached, final CacheEntry parent, final ListenerBase listener, final InternalProcedure<IntSet> procedure) {
\r
37 Types entry = cached != null ? cached : (Types)provider.typesMap.get(r);
\r
40 entry = new Types(r);
\r
42 entry.clearResult(provider.querySupport);
\r
43 entry.putEntry(provider);
\r
45 provider.performForEach(graph, entry, parent, listener, procedure);
\r
49 if(!entry.isReady()) {
\r
50 throw new IllegalStateException();
\r
52 provider.performForEach(graph, entry, parent, listener, procedure);
\r
57 final static IntSet runner2(ReadGraphImpl graph, final int r, final QueryProcessor provider, final CacheEntry parent) throws Throwable {
\r
59 Types entry = (Types)provider.typesMap.get(r);
\r
62 entry = new Types(r);
\r
64 entry.clearResult(provider.querySupport);
\r
65 entry.putEntry(provider);
\r
67 return (IntSet)provider.performForEach2(graph, entry, parent, null, null);
\r
71 if(!entry.isReady()) {
\r
72 throw new IllegalStateException();
\r
74 return (IntSet)provider.performForEach2(graph, entry, parent, null, null);
\r
80 final public static void queryEach(ReadGraphImpl graph, final int r, final QueryProcessor provider, final CacheEntry parent, final ListenerBase listener, final InternalProcedure<IntSet> procedure) {
\r
82 final Types entry = (Types)provider.typesMap.get(r);
\r
84 if(parent == null && listener == null) {
\r
85 if(entry != null && entry.isReady()) {
\r
86 entry.performFromCache(graph, provider, procedure);
\r
91 runner(graph, r, provider, entry, parent, listener, procedure);
\r
95 final public static IntSet queryEach2(ReadGraphImpl graph, final int r, final QueryProcessor provider, final CacheEntry parent) throws Throwable {
\r
97 if(parent == null) {
\r
98 Types entry = (Types)provider.typesMap.get(r);
\r
99 if(entry != null && entry.isReady()) {
\r
100 return (IntSet)entry.get(graph, provider, null);
\r
104 return runner2(graph, r, provider, parent);
\r
109 public UnaryQuery<InternalProcedure<IntSet>> getEntry(QueryProcessor provider) {
\r
110 return provider.typesMap.get(id);
\r
114 public void putEntry(QueryProcessor provider) {
\r
115 provider.typesMap.put(id, this);
\r
119 final public void removeEntry(QueryProcessor provider) {
\r
120 provider.typesMap.remove(id);
\r
124 public Object computeForEach(final ReadGraphImpl graph, final QueryProcessor queryProvider, final InternalProcedure<IntSet> procedure, final boolean store) {
\r
126 queryProvider.querySupport.ensureLoaded(graph, id);
\r
127 int ret = queryProvider.querySupport.getSingleInstance(id);
\r
130 TypeHierarchy.queryEach(graph, ret, queryProvider, store ? Types.this : null, null, new InternalProcedure<IntSet>() {
\r
133 public void execute(ReadGraphImpl graph, IntSet types) {
\r
135 addOrSet(graph, types, queryProvider);
\r
136 procedure.execute(graph, types);
\r
141 public void exception(ReadGraphImpl graph, Throwable t) {
\r
142 procedure.exception(graph, t);
\r
147 return getResult();
\r
151 final int instanceOf = queryProvider.getInstanceOf();
\r
152 final int inherits = queryProvider.getInherits();
\r
153 final int subrelationOf = queryProvider.getSubrelationOf();
\r
155 final IntSet result = new IntSet(queryProvider.querySupport);
\r
157 final TIntProcedure addToResult = new TIntProcedure() {
\r
159 public boolean execute(int r) {
\r
160 synchronized(result) {
\r
167 final AtomicInteger finishes = new AtomicInteger(0);
\r
169 SyncIntProcedure instanceOfProcedure = new SyncIntProcedure() {
\r
172 public void run(ReadGraphImpl graph) {
\r
174 if(finishes.addAndGet(1) == 3) {
\r
175 if(store) addOrSet(graph, result, queryProvider);
\r
176 procedure.execute(graph, result);
\r
182 public void execute(ReadGraphImpl graph, int i) {
\r
184 synchronized(result) {
\r
190 SuperTypes.queryEach(graph, i, queryProvider, store ? Types.this : null, null, new InternalProcedure<IntSet>() {
\r
193 public void execute(ReadGraphImpl graph, IntSet types) {
\r
194 types.forEach(addToResult);
\r
199 public void exception(ReadGraphImpl graph, Throwable t) {
\r
200 procedure.exception(graph, t);
\r
209 public void finished(ReadGraphImpl graph) {
\r
215 SyncIntProcedure inheritsProcedure = new SyncIntProcedure() {
\r
218 public void run(ReadGraphImpl graph) {
\r
220 int current = finishes.addAndGet(1);
\r
222 if(store) addOrSet(graph, result, queryProvider);
\r
223 procedure.execute(graph, result);
\r
229 public void execute(ReadGraphImpl graph, int i) {
\r
233 Types.queryEach(graph, i, queryProvider, store ? Types.this : null, null, new InternalProcedure<IntSet>() {
\r
236 public void execute(ReadGraphImpl graph, IntSet types) {
\r
237 types.forEach(addToResult);
\r
242 public void exception(ReadGraphImpl graph, Throwable t) {
\r
243 procedure.exception(graph, t);
\r
252 public void finished(ReadGraphImpl graph) {
\r
260 SyncIntProcedure subrelationOfProcedure = new SyncIntProcedure() {
\r
263 public void run(ReadGraphImpl graph) {
\r
265 int current = finishes.addAndGet(1);
\r
267 if(store) addOrSet(graph, result, queryProvider);
\r
268 procedure.execute(graph, result);
\r
274 public void execute(ReadGraphImpl graph, int i) {
\r
278 Types.queryEach(graph, i, queryProvider, store ? Types.this : null, null, new InternalProcedure<IntSet>() {
\r
281 public void execute(ReadGraphImpl graph, IntSet types) {
\r
283 types.forEach(addToResult);
\r
289 public void exception(ReadGraphImpl graph, Throwable t) {
\r
290 procedure.exception(graph, t);
\r
299 public void finished(ReadGraphImpl graph) {
\r
307 queryProvider.querySupport.getObjects(graph, id, instanceOf, instanceOfProcedure);
\r
308 instanceOfProcedure.finished(graph);
\r
309 queryProvider.querySupport.getObjects(graph, id, inherits, inheritsProcedure);
\r
310 inheritsProcedure.finished(graph);
\r
311 queryProvider.querySupport.getObjects(graph, id, subrelationOf, subrelationOfProcedure);
\r
312 subrelationOfProcedure.finished(graph);
\r
319 public String toString() {
\r
320 return "Types[" + id + "]";
\r
323 private void addOrSet(ReadGraphImpl graph, final IntSet value, QueryProcessor provider) {
\r
325 assert(!isReady());
\r
327 synchronized(this) {
\r
338 final public Object performFromCache(ReadGraphImpl graph, QueryProcessor provider, InternalProcedure<IntSet> procedure) {
\r
342 if(handleException(graph, procedure)) return EXCEPTED;
\r
344 IntSet result = getResult();
\r
346 procedure.execute(graph, result);
\r
353 public void recompute(ReadGraphImpl graph, QueryProcessor provider) {
\r
355 final Semaphore s = new Semaphore(0);
\r
357 computeForEach(graph, provider, new InternalProcedure<IntSet>() {
\r
360 public void execute(ReadGraphImpl graph, IntSet result) {
\r
365 public void exception(ReadGraphImpl graph, Throwable t) {
\r
367 new Error("Error in recompute.", t).printStackTrace();
\r
372 while(!s.tryAcquire()) {
\r
373 provider.resume(graph);
\r
379 boolean isImmutable(ReadGraphImpl graph) {
\r
380 return graph.processor.isImmutable(id);
\r