]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Types.java
Multiple readers and variable optimization
[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 java.util.concurrent.atomic.AtomicInteger;
15
16 import org.simantics.db.exception.DatabaseException;
17 import org.simantics.db.impl.graph.ReadGraphImpl;
18 import org.simantics.db.impl.procedure.InternalProcedure;
19
20 import gnu.trove.procedure.TIntProcedure;
21
22 final public class Types extends UnaryQuery<InternalProcedure<IntSet>> {
23         
24     Types(final int resource) {
25         super(resource);
26     }
27
28         @Override
29         final public void removeEntry(QueryProcessor provider) {
30                 provider.cache.remove(this);
31         }
32
33         @Override
34         public Object compute(final ReadGraphImpl graph, final InternalProcedure<IntSet> procedure) throws DatabaseException {
35                 computeForEach(graph, id, this, procedure);
36                 return getResult();
37         }
38
39         public static void computeForEach(final ReadGraphImpl graph, int id, Types entry, final InternalProcedure<IntSet> procedure) throws DatabaseException {
40
41                 assert(procedure != null);
42
43                 QueryProcessor processor = graph.processor;
44
45                 processor.querySupport.ensureLoaded(graph, id);
46                 
47                 int ret = processor.querySupport.getSingleInstance(id);
48                 if(ret > 0) {
49
50                         TypeHierarchy.queryEach(graph, ret, processor, entry, null, new InternalProcedure<IntSet>() {
51
52                                 @Override
53                                 public void execute(ReadGraphImpl graph, IntSet types) throws DatabaseException {
54
55                                         if(entry != null) {
56                                                 entry.addOrSet(graph, types, processor);
57                                                 entry.finish();
58                                         }
59                                         procedure.execute(graph, types);
60
61                                 }
62
63                                 @Override
64                                 public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
65                                         procedure.exception(graph, t);
66                                 }
67
68                         });
69                         
70                         return;
71
72                 }
73                 
74                 final int instanceOf = processor.getInstanceOf();
75         final int inherits = processor.getInherits();
76         final int subrelationOf = processor.getSubrelationOf();
77
78         final IntSet result = new IntSet(processor.querySupport);
79         
80         final TIntProcedure addToResult = new TIntProcedure() {
81             @Override
82             public boolean execute(int r) {
83                 synchronized(result) {
84                         result.add(r);
85                 }
86                 return true;
87             }
88         };
89         
90         final AtomicInteger finishes = new AtomicInteger(0);
91         
92         SyncIntProcedure instanceOfProcedure = new SyncIntProcedure() {
93             
94             @Override
95             public void run(ReadGraphImpl graph) throws DatabaseException {
96                 
97                 if(finishes.addAndGet(1) == 3) {
98                     if(entry != null) entry.addOrSet(graph, result, processor);
99                     procedure.execute(graph, result);
100                 }
101                 
102             }
103             
104             @Override
105             public void execute(ReadGraphImpl graph, int i) throws DatabaseException {
106                 
107                 result.add(i);
108                 
109                 inc();
110
111                 QueryCache.runnerSuperTypes(graph, i, entry, null, new InternalProcedure<IntSet>() {
112
113                     @Override
114                     public void execute(ReadGraphImpl graph, IntSet types) throws DatabaseException {
115                         types.forEach(addToResult);
116                         dec(graph);
117                     }
118                                 
119                                 @Override
120                                 public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
121                                         procedure.exception(graph, t);
122                         dec(graph);
123                     }
124
125                 });
126                 
127             }
128
129             @Override
130             public void finished(ReadGraphImpl graph) throws DatabaseException {
131                 dec(graph);
132             }
133             
134         }; 
135         
136         SyncIntProcedure inheritsProcedure = new SyncIntProcedure() {
137             
138             @Override
139             public void run(ReadGraphImpl graph) throws DatabaseException {
140
141                 int current = finishes.addAndGet(1);
142                 if(current == 3) {
143                     if(entry != null) entry.addOrSet(graph, result, processor);
144                     procedure.execute(graph, result);
145                 }
146                 
147             }
148             
149             @Override
150             public void execute(ReadGraphImpl graph, int i) throws DatabaseException {
151                 
152                 inc();
153
154                 QueryCache.runnerTypes(graph, i, entry, null, new InternalProcedure<IntSet>() {
155
156                     @Override
157                     public void execute(ReadGraphImpl graph, IntSet types) throws DatabaseException {
158                         types.forEach(addToResult);
159                         dec(graph);
160                     }
161                                 
162                                 @Override
163                                 public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
164                                         procedure.exception(graph, t);
165                         dec(graph);
166                     }
167
168                 });
169                 
170             }
171
172             @Override
173             public void finished(ReadGraphImpl graph) throws DatabaseException {
174
175                 dec(graph);
176
177             }
178             
179         }; 
180
181         SyncIntProcedure subrelationOfProcedure = new SyncIntProcedure() {
182
183             @Override
184             public void run(ReadGraphImpl graph) throws DatabaseException {
185
186                 int current = finishes.addAndGet(1);
187                 if(current == 3) {
188                     if(entry != null) entry.addOrSet(graph, result, processor);
189                     procedure.execute(graph, result);
190                 }
191                 
192             }
193             
194             @Override
195             public void execute(ReadGraphImpl graph, int i) throws DatabaseException {
196                 
197                 inc();
198                 
199                 QueryCache.runnerTypes(graph, i, entry, null, new InternalProcedure<IntSet>() {
200
201                     @Override
202                     public void execute(ReadGraphImpl graph, IntSet types) throws DatabaseException {
203
204                         types.forEach(addToResult);
205                         dec(graph);
206                         
207                     }
208                                 
209                                 @Override
210                                 public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException {
211                                         procedure.exception(graph, t);
212                         dec(graph);
213                     }
214
215                 });
216                 
217             }
218
219             @Override
220             public void finished(ReadGraphImpl graph) throws DatabaseException {
221                 
222                 dec(graph);
223
224             }
225             
226         }; 
227         
228         processor.querySupport.getObjects(graph, id, instanceOf, instanceOfProcedure);
229         instanceOfProcedure.finished(graph);
230         processor.querySupport.getObjects(graph, id, inherits, inheritsProcedure);
231         inheritsProcedure.finished(graph);
232         processor.querySupport.getObjects(graph, id, subrelationOf, subrelationOfProcedure);
233         subrelationOfProcedure.finished(graph);
234         
235         if(entry != null) entry.finish();
236         
237     }
238     
239     @Override
240     public String toString() {
241         return "Types[" + id + "]";
242     }
243     
244     private void addOrSet(ReadGraphImpl graph, final IntSet value, QueryProcessor provider) {
245         
246         assert(!isReady());
247
248         setResult(value);
249         
250     }
251     
252     void finish() {
253
254         IntSet result = getResult(); 
255         result.trim();
256         setReady();
257         
258     }
259     
260     @Override
261     final public Object performFromCache(ReadGraphImpl graph, InternalProcedure<IntSet> procedure) throws DatabaseException {
262         
263         assert(isReady());
264         
265         if(handleException(graph, procedure)) return EXCEPTED;
266         
267         IntSet result = getResult();
268         
269         procedure.execute(graph, result);
270         
271         return result;
272         
273     }
274     
275     @Override
276     public void recompute(ReadGraphImpl graph) throws DatabaseException {
277
278         compute(graph, new InternalProcedure<IntSet>() {
279
280                 @Override
281                 public void execute(ReadGraphImpl graph, IntSet result) {
282                 }
283
284             @Override
285             public void exception(ReadGraphImpl graph, Throwable t) {
286                 new Error("Error in recompute.", t).printStackTrace();
287             }
288
289         });
290         
291     }
292
293     @Override
294     boolean isImmutable(ReadGraphImpl graph) {
295         return graph.processor.isImmutable(id);
296     }
297     
298 }