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