]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Types.java
49cb5c4c61ac0fabb59d01cf326d96c7ba1ad0b1
[simantics/platform.git] / bundles / org.simantics.db.impl / src / org / simantics / db / impl / query / Types.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management
3  * in Industry THTH ry.
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
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.db.impl.query;
13
14 import gnu.trove.procedure.TIntProcedure;
15
16 import java.util.concurrent.Semaphore;
17 import java.util.concurrent.atomic.AtomicInteger;
18
19 import org.simantics.db.impl.graph.ReadGraphImpl;
20 import org.simantics.db.impl.procedure.InternalProcedure;
21 import org.simantics.db.procedure.ListenerBase;
22
23 final public class Types extends UnaryQuery<InternalProcedure<IntSet>> {
24     
25 //      public ArrayList<InternalProcedure<IntSet>> procs;
26         
27     private Types(final int resource) {
28         super(resource);
29     }
30     
31     final static Types entry(final QueryProcessor provider, final int r) {
32         return (Types)provider.typesMap.get(r);
33     }
34     
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) {
36
37         Types entry = cached != null ? cached : (Types)provider.typesMap.get(r); 
38         if(entry == null) {
39                 
40                 entry = new Types(r);
41                 entry.setPending();
42                 entry.clearResult(provider.querySupport);
43                 entry.putEntry(provider);
44                 
45             provider.performForEach(graph, entry, parent, listener, procedure);
46             
47         } else {
48
49                 if(!entry.isReady()) {
50                     throw new IllegalStateException();
51             }
52             provider.performForEach(graph, entry, parent, listener, procedure);
53         }
54         
55     }
56     
57     final static IntSet runner2(ReadGraphImpl graph, final int r, final QueryProcessor provider, final CacheEntry parent) throws Throwable {
58
59         Types entry = (Types)provider.typesMap.get(r); 
60         if(entry == null) {
61                 
62                 entry = new Types(r);
63                 entry.setPending();
64                 entry.clearResult(provider.querySupport);
65                 entry.putEntry(provider);
66                 
67             return (IntSet)provider.performForEach2(graph, entry, parent, null, null);
68             
69         } else {
70
71                 if(!entry.isReady()) {
72                     throw new IllegalStateException();
73             }
74             return (IntSet)provider.performForEach2(graph, entry, parent, null, null);
75             
76         }
77         
78     }
79     
80     final public static void queryEach(ReadGraphImpl graph, final int r, final QueryProcessor provider, final CacheEntry parent, final ListenerBase listener, final InternalProcedure<IntSet> procedure) {
81         
82         final Types entry = (Types)provider.typesMap.get(r);
83         
84         if(parent == null && listener == null) {
85                 if(entry != null && entry.isReady()) { 
86                         entry.performFromCache(graph, provider, procedure);
87                         return;
88                 }
89         }
90         
91         runner(graph, r, provider, entry, parent, listener, procedure);
92          
93     }
94
95     final public static IntSet queryEach2(ReadGraphImpl graph, final int r, final QueryProcessor provider, final CacheEntry parent) throws Throwable {
96         
97         if(parent == null) {
98             Types entry = (Types)provider.typesMap.get(r);
99             if(entry != null && entry.isReady()) {
100                 return (IntSet)entry.get(graph, provider, null);
101             }
102         }
103         
104         return runner2(graph, r, provider, parent);
105          
106     }
107     
108         @Override
109         public UnaryQuery<InternalProcedure<IntSet>> getEntry(QueryProcessor provider) {
110         return provider.typesMap.get(id);
111         }
112         
113         @Override
114         public void putEntry(QueryProcessor provider) {
115         provider.typesMap.put(id, this);
116         }
117
118         @Override
119         final public void removeEntry(QueryProcessor provider) {
120                 provider.typesMap.remove(id);
121         }
122
123         @Override
124         public Object computeForEach(final ReadGraphImpl graph, final QueryProcessor queryProvider, final InternalProcedure<IntSet> procedure, final boolean store) {
125
126                 queryProvider.querySupport.ensureLoaded(graph, id);
127                 int ret = queryProvider.querySupport.getSingleInstance(id);
128                 if(ret > 0) {
129
130                         TypeHierarchy.queryEach(graph, ret, queryProvider, store ? Types.this : null, null, new InternalProcedure<IntSet>() {
131
132                                 @Override
133                                 public void execute(ReadGraphImpl graph, IntSet types) {
134
135                                         addOrSet(graph, types, queryProvider);
136                                         procedure.execute(graph, types);
137
138                                 }
139
140                                 @Override
141                                 public void exception(ReadGraphImpl graph, Throwable t) {
142                                         procedure.exception(graph, t);
143                                 }
144
145                         });
146
147                         return getResult();
148
149                 }
150                 
151                 final int instanceOf = queryProvider.getInstanceOf();
152         final int inherits = queryProvider.getInherits();
153         final int subrelationOf = queryProvider.getSubrelationOf();
154
155         final IntSet result = new IntSet(queryProvider.querySupport);
156         
157         final TIntProcedure addToResult = new TIntProcedure() {
158             @Override
159             public boolean execute(int r) {
160                 synchronized(result) {
161                         result.add(r);
162                 }
163                 return true;
164             }
165         };
166         
167         final AtomicInteger finishes = new AtomicInteger(0);
168         
169         SyncIntProcedure instanceOfProcedure = new SyncIntProcedure() {
170             
171             @Override
172             public void run(ReadGraphImpl graph) {
173                 
174                 if(finishes.addAndGet(1) == 3) {
175                     if(store) addOrSet(graph, result, queryProvider);
176                     procedure.execute(graph, result);
177                 }
178                 
179             }
180             
181             @Override
182             public void execute(ReadGraphImpl graph, int i) {
183                 
184                 synchronized(result) {
185                         result.add(i);
186                 }
187                 
188                 inc();
189
190                 SuperTypes.queryEach(graph, i, queryProvider, store ? Types.this : null, null, new InternalProcedure<IntSet>() {
191
192                     @Override
193                     public void execute(ReadGraphImpl graph, IntSet types) {
194                         types.forEach(addToResult);
195                         dec(graph);
196                     }
197                                 
198                                 @Override
199                                 public void exception(ReadGraphImpl graph, Throwable t) {
200                                         procedure.exception(graph, t);
201                         dec(graph);
202                     }
203
204                 });
205                 
206             }
207
208             @Override
209             public void finished(ReadGraphImpl graph) {
210                 dec(graph);
211             }
212             
213         }; 
214         
215         SyncIntProcedure inheritsProcedure = new SyncIntProcedure() {
216             
217             @Override
218             public void run(ReadGraphImpl graph) {
219
220                 int current = finishes.addAndGet(1);
221                 if(current == 3) {
222                     if(store) addOrSet(graph, result, queryProvider);
223                     procedure.execute(graph, result);
224                 }
225                 
226             }
227             
228             @Override
229             public void execute(ReadGraphImpl graph, int i) {
230                 
231                 inc();
232
233                 Types.queryEach(graph, i, queryProvider, store ? Types.this : null, null, new InternalProcedure<IntSet>() {
234
235                     @Override
236                     public void execute(ReadGraphImpl graph, IntSet types) {
237                         types.forEach(addToResult);
238                         dec(graph);
239                     }
240                                 
241                                 @Override
242                                 public void exception(ReadGraphImpl graph, Throwable t) {
243                                         procedure.exception(graph, t);
244                         dec(graph);
245                     }
246
247                 });
248                 
249             }
250
251             @Override
252             public void finished(ReadGraphImpl graph) {
253
254                 dec(graph);
255
256             }
257             
258         }; 
259
260         SyncIntProcedure subrelationOfProcedure = new SyncIntProcedure() {
261
262             @Override
263             public void run(ReadGraphImpl graph) {
264
265                 int current = finishes.addAndGet(1);
266                 if(current == 3) {
267                     if(store) addOrSet(graph, result, queryProvider);
268                     procedure.execute(graph, result);
269                 }
270                 
271             }
272             
273             @Override
274             public void execute(ReadGraphImpl graph, int i) {
275                 
276                 inc();
277                 
278                 Types.queryEach(graph, i, queryProvider, store ? Types.this : null, null, new InternalProcedure<IntSet>() {
279
280                     @Override
281                     public void execute(ReadGraphImpl graph, IntSet types) {
282
283                         types.forEach(addToResult);
284                         dec(graph);
285                         
286                     }
287                                 
288                                 @Override
289                                 public void exception(ReadGraphImpl graph, Throwable t) {
290                                         procedure.exception(graph, t);
291                         dec(graph);
292                     }
293
294                 });
295                 
296             }
297
298             @Override
299             public void finished(ReadGraphImpl graph) {
300                 
301                 dec(graph);
302
303             }
304             
305         }; 
306         
307         queryProvider.querySupport.getObjects(graph, id, instanceOf, instanceOfProcedure);
308         instanceOfProcedure.finished(graph);
309         queryProvider.querySupport.getObjects(graph, id, inherits, inheritsProcedure);
310         inheritsProcedure.finished(graph);
311         queryProvider.querySupport.getObjects(graph, id, subrelationOf, subrelationOfProcedure);
312         subrelationOfProcedure.finished(graph);
313         
314         return result;
315         
316     }
317     
318     @Override
319     public String toString() {
320         return "Types[" + id + "]";
321     }
322     
323     private void addOrSet(ReadGraphImpl graph, final IntSet value, QueryProcessor provider) {
324         
325         assert(!isReady());
326
327         synchronized(this) {
328         
329             value.trim();
330             setResult(value);
331             setReady();
332         
333         }
334         
335     }
336     
337     @Override
338     final public Object performFromCache(ReadGraphImpl graph, QueryProcessor provider, InternalProcedure<IntSet> procedure) {
339         
340         assert(isReady());
341         
342         if(handleException(graph, procedure)) return EXCEPTED;
343         
344         IntSet result = getResult();
345         
346         procedure.execute(graph, result);
347         
348         return result;
349         
350     }
351     
352     @Override
353     public void recompute(ReadGraphImpl graph, QueryProcessor provider) {
354         
355         final Semaphore s = new Semaphore(0);
356
357         computeForEach(graph, provider, new InternalProcedure<IntSet>() {
358
359                 @Override
360                 public void execute(ReadGraphImpl graph, IntSet result) {
361                 s.release();
362                 }
363
364             @Override
365             public void exception(ReadGraphImpl graph, Throwable t) {
366                 s.release();
367                 new Error("Error in recompute.", t).printStackTrace();
368             }
369
370         }, true);
371
372         while(!s.tryAcquire()) {
373                 provider.resume(graph);
374         }
375         
376     }
377
378     @Override
379     boolean isImmutable(ReadGraphImpl graph) {
380         return graph.processor.isImmutable(id);
381     }
382     
383 }