]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Predicates.java
312522007e4f53483490e08554fb4773dd86e64a
[simantics/platform.git] / bundles / org.simantics.db.impl / src / org / simantics / db / impl / query / Predicates.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
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;
22
23 final public class Predicates extends UnaryQuery<IntProcedure> {
24
25         public Predicates(final int r) {
26         super(r);
27     }
28
29     public static Predicates newInstance(final int r) {
30         return new Predicates(r);
31     }
32     
33     final static Predicates entry(final QueryProcessor provider, final int r) {
34         
35         return (Predicates)provider.cache.predicatesMap.get(r);
36
37     }
38     
39     final static void runner(ReadGraphImpl graph, final int r, final QueryProcessor provider, Predicates cached, final CacheEntry parent, final ListenerBase listener, final IntProcedure procedure) {
40
41         Predicates entry = cached != null ? cached : (Predicates)provider.cache.predicatesMap.get(r); 
42         if(entry == null) {
43                 
44                 entry = new Predicates(r);
45                 entry.setPending();
46                 entry.clearResult(provider.querySupport);
47                 entry.putEntry(provider);
48                 
49             provider.performForEach(graph, entry, parent, listener, procedure);
50             
51         } else {
52                 
53             if(entry.isPending()) {
54                 synchronized(entry) {
55                     if(entry.isPending()) {
56                         throw new IllegalStateException();
57                     }
58                 }
59             }
60             provider.performForEach(graph, entry, parent, listener, procedure);
61         }
62
63     }
64
65     final static IntSet runner2(ReadGraphImpl graph, final int r, final QueryProcessor provider, final CacheEntry parent) throws Throwable {
66
67         Predicates entry = (Predicates)provider.cache.predicatesMap.get(r); 
68         if(entry == null) {
69                 
70                 entry = new Predicates(r);
71                 entry.setPending();
72                 entry.clearResult(provider.querySupport);
73                 entry.putEntry(provider);
74                 
75             return (IntSet)provider.performForEach2(graph, entry, parent, null, null);
76             
77         } else {
78                 
79             if(entry.isPending()) {
80                 synchronized(entry) {
81                     if(entry.isPending()) {
82                         throw new IllegalStateException();
83                     }
84                 }
85             }
86             return (IntSet)provider.performForEach(graph, entry, parent, null, null);
87             
88         }
89
90     }
91     
92     final public static void queryEach(ReadGraphImpl graph, final int r, final QueryProcessor provider, final CacheEntry parent, final ListenerBase listener, final IntProcedure procedure) {
93         
94         assert(r != 0);
95         
96         final Predicates entry = (Predicates)provider.cache.predicatesMap.get(r);
97         
98         if(parent == null && listener == null) {
99                 if(entry != null && entry.isReady()) { 
100                         entry.performFromCache(graph, provider, procedure);
101                         return;
102                 }
103         }
104
105         runner(graph, r, provider, entry, parent, listener, procedure);
106          
107     }
108
109     final public static IntSet queryEach2(ReadGraphImpl graph, final int r, final QueryProcessor provider, final CacheEntry parent) throws Throwable {
110         
111         if(parent == null) {
112                 final Predicates entry = (Predicates)provider.cache.predicatesMap.get(r);
113                 if(entry != null && entry.isReady()) {
114                         return (IntSet)entry.get(graph, provider, null);
115                 }
116         }
117
118         return runner2(graph, r, provider, parent);
119          
120     }
121     
122     @Override
123     public UnaryQuery<IntProcedure> getEntry(QueryProcessor provider) {
124         return provider.cache.predicatesMap.get(id);
125     }
126         
127         @Override
128         public void putEntry(QueryProcessor provider) {
129             provider.cache.predicatesMap.put(id, this);
130         }
131
132         @Override
133         final public void removeEntry(QueryProcessor provider) {
134         provider.cache.predicatesMap.remove(id);
135         }
136     
137     final private void forAssertions(ReadGraphImpl graph, final QueryProcessor queryProvider, final IntProcedure procedure, final boolean store) {
138
139         PrincipalTypes.queryEach(graph, id, queryProvider, store ? Predicates.this : null, null, new SyncIntProcedure() {
140             
141             @Override
142             public void run(ReadGraphImpl graph) {
143                 
144                 finish(graph, queryProvider);
145                 procedure.finished(graph);
146                 
147             }
148             
149             IntProcedure proc = new IntProcedure() {
150
151                 @Override
152                 public void execute(ReadGraphImpl graph, int i) {
153                     if(addOrSet(queryProvider, i))
154                         procedure.execute(graph, i);
155                 }
156
157                 @Override
158                 public void finished(ReadGraphImpl graph) {
159                     dec(graph);
160                 }
161                                 
162                                 @Override
163                                 public void exception(ReadGraphImpl graph, Throwable t) {
164                     if(DebugException.DEBUG) new DebugException(t).printStackTrace();
165                                         procedure.exception(graph, t);
166                     }
167
168             }; 
169
170             @Override
171             public void execute(ReadGraphImpl graph, int type) {
172
173                 inc();
174                 
175                 AssertedPredicates.queryEach(graph, type, queryProvider, store ? Predicates.this : null, null, proc);
176                 
177             }
178             
179             @Override
180             public void finished(ReadGraphImpl graph) {
181                 dec(graph);       
182             }
183             
184         });
185         
186
187     }
188
189     @Override
190     public Object computeForEach(ReadGraphImpl graph, final QueryProcessor provider, final IntProcedure procedure, final boolean store) {
191
192                 DirectPredicates.queryEach(graph, id, provider, store ? Predicates.this : null, null, new IntProcedure() {
193
194                         @Override
195                         public void execute(ReadGraphImpl graph, final int pred) {
196
197                                 if(addOrSet(provider, pred))
198                                         procedure.execute(graph, pred);
199
200                         }
201
202                         @Override
203                         public void finished(ReadGraphImpl graph) {
204
205                                 forAssertions(graph, provider, procedure, store);
206
207                         }
208
209                         @Override
210                         public void exception(ReadGraphImpl graph, Throwable t) {
211                                 procedure.exception(graph, t);
212                         }
213
214                 });
215                 
216                 return getResult();
217         
218     }
219     
220     @Override
221     public String toString() {
222         return "Predicates2[" + id + "]";
223     }
224
225     final public void finish(final ReadGraphImpl graph, QueryProcessor provider) {
226         
227 //        ArrayList<IntProcedure> p = null;
228
229         synchronized(this) {
230
231                 setReady();
232 //            p = procs;
233 //            procs = null; 
234         
235         }
236         
237 //        if(p != null) {
238 //        
239 //              final ArrayList<IntProcedure> finalP = p;
240 //
241 //              IntSet v = (IntSet)getResult();
242 //              v.forEach(new TIntProcedure() {
243 //
244 //                      @Override
245 //                      public boolean execute(int arg0) {
246 //                              for(IntProcedure proc : finalP) proc.execute(graph, arg0);
247 //                              return true;
248 //                      }
249 //
250 //              });
251 //
252 //              for(IntProcedure proc : p) proc.finished(graph);
253 //        
254 //        }
255
256     }
257
258     synchronized private boolean addOrSet(QueryProcessor processor, int add) {
259
260         if(!isPending()) {
261                 setResult(new IntSet(null));
262         }
263         
264         IntSet value = (IntSet)getResult();
265         return value.add(add);
266         
267     }
268
269     @Override
270     public void clearResult(QuerySupport support) {
271         setResult(new IntSet(support));
272     }
273     
274     @Override
275     public Object performFromCache(final ReadGraphImpl graph, QueryProcessor provider, final IntProcedure procedure) {
276         
277         assert(isReady());
278
279         if(handleException(graph, procedure)) return EXCEPTED;
280         
281         IntSet v = getResult();
282         if(procedure != null) {
283                 v.forEach(new TIntProcedure() {
284
285                         @Override
286                         public boolean execute(int arg0) {
287                                 procedure.execute(graph, arg0);                                         
288                                 return true;
289                         }
290                 });
291             procedure.finished(graph);
292         }
293         
294         return v;
295         
296     }
297     
298     @Override
299     public void recompute(ReadGraphImpl graph, QueryProcessor provider) {
300         
301         final Semaphore s = new Semaphore(0);
302         
303         computeForEach(graph, provider, new IntProcedure() {
304
305             @Override
306             public void finished(ReadGraphImpl graph) {
307                 s.release();
308             }
309                         
310                         @Override
311                         public void exception(ReadGraphImpl graph, Throwable t) {
312                                 throw new Error("Error in recompute.", t);
313             }
314
315                         @Override
316                         public void execute(ReadGraphImpl graph, int i) {
317                         }
318
319         }, true);
320         
321         while(!s.tryAcquire()) {
322                 provider.resume(graph);
323         }
324         
325     }
326     
327     @Override
328     public int type() {
329         return RequestFlags.IMMEDIATE_UPDATE;
330     }
331
332
333     @Override
334     boolean isImmutable(ReadGraphImpl graph) {
335         return graph.processor.isImmutable(id);
336     }
337     
338 }