]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/RelationInfoQuery.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.db.impl / src / org / simantics / db / impl / query / RelationInfoQuery.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.ArrayList;
15 import java.util.concurrent.Semaphore;
16 import java.util.concurrent.atomic.AtomicBoolean;
17
18 import org.simantics.db.RelationInfo;
19 import org.simantics.db.exception.DatabaseException;
20 import org.simantics.db.impl.graph.ReadGraphImpl;
21 import org.simantics.db.impl.procedure.InternalProcedure;
22 import org.simantics.db.procedure.ListenerBase;
23 import org.simantics.db.request.RequestFlags;
24
25 final public class RelationInfoQuery extends UnaryQuery<InternalProcedure<RelationInfo>> {
26     
27 //      public ArrayList<InternalProcedure<RelationInfo>> procs = null;
28
29         private RelationInfoQuery(final int resource) {
30         super(resource);
31     }
32     
33     final static RelationInfo runner(ReadGraphImpl graph, final int r, final QueryProcessor provider, final CacheEntry parent, final ListenerBase listener, final InternalProcedure<RelationInfo> procedure) {
34
35         RelationInfoQuery entry = (RelationInfoQuery)provider.relationInfoMap.get(r);
36         if(entry == null) {
37                 
38                 entry = new RelationInfoQuery(r);
39                 entry.setPending();
40                 entry.clearResult(provider.querySupport);
41                 entry.putEntry(provider);
42                 
43             provider.performForEach(graph, entry, parent, listener, procedure);
44             
45             return entry.getResult();
46             
47         } else {
48                 
49             if(!entry.isReady()) {
50                 synchronized(entry) {
51                     if(!entry.isReady()) {
52                         throw new IllegalStateException();
53 //                      if(entry.procs == null) entry.procs = new ArrayList<InternalProcedure<RelationInfo>>();
54 //                                      entry.procs.add(procedure);
55 //                        provider.registerDependencies(graph, entry, parent, listener, procedure, false);
56 //                                      return entry.getResult();
57                     }
58                 }
59             }
60             provider.performForEach(graph, entry, parent, listener, procedure);
61             
62             return entry.getResult();
63             
64         }
65
66     }
67     
68     final public static RelationInfo queryEach(ReadGraphImpl graph, final int r, final QueryProcessor provider, final CacheEntry parent, final ListenerBase listener, final InternalProcedure<RelationInfo> procedure) {
69         
70         RelationInfoQuery entry = (RelationInfoQuery)provider.relationInfoMap.get(r);
71         if(entry != null && entry.isReady()) {
72                 entry.performFromCache(graph, provider, procedure);
73                 return entry.getResult();
74         }
75
76         return runner(graph, r, provider, parent, listener, procedure);
77          
78     }
79      
80     final public static RelationInfoQuery probe(ReadGraphImpl graph, int resource) {
81         
82         final int thread = graph.thread(resource);
83         RelationInfoQuery entry = (RelationInfoQuery)graph.processor.relationInfoMap.get(resource);
84         if(entry != null && entry.isReady()) {
85                 return entry;
86         } else {
87                 return null;
88         }
89          
90     }
91
92     @Override
93         public UnaryQuery<InternalProcedure<RelationInfo>> getEntry(QueryProcessor provider) {
94         return provider.relationInfoMap.get(id);
95         }
96         
97         @Override
98         public void putEntry(QueryProcessor provider) {
99         provider.relationInfoMap.put(id, this);
100         }
101
102         @Override
103         final public void removeEntry(QueryProcessor provider) {
104                 provider.relationInfoMap.remove(id);
105         }
106
107         private void computeAssertions(ReadGraphImpl graph, final boolean isFinal, final boolean isFunctional, final QueryProcessor queryProvider, final InternalProcedure<RelationInfo> proc) {
108
109             final int isUsedInAssertion = queryProvider.getHasPredicateInverse();
110         assert(isUsedInAssertion != 0);
111                 
112         DirectObjects.queryEach(graph, id, isUsedInAssertion, queryProvider, this, null, new IntProcedure() {
113
114                         AtomicBoolean done = new AtomicBoolean(false);
115                         
116                         @Override
117                         public void execute(ReadGraphImpl graph, int i) {
118                                 if(done.compareAndSet(false, true)) {
119 //                                      System.err.println("Assertions for relation " + id);
120                                         RelationInfo result = new RelationInfo(id, isFunctional, isFinal, true);
121                                         addOrSet(graph, result, queryProvider);
122                                         proc.execute(graph, result);
123                                 }
124                         }
125
126                         @Override
127                         public void finished(ReadGraphImpl graph) {
128                                 if(done.compareAndSet(false, true)) {
129 //                                      System.err.println("No assertions for relation " + id);
130                                         RelationInfo result = new RelationInfo(id, isFunctional, isFinal, false);
131                                         addOrSet(graph, result, queryProvider);
132                                         proc.execute(graph, result);
133                                 }
134                         }
135
136                         @Override
137                         public void exception(ReadGraphImpl graph, Throwable throwable) {
138                                 if(done.compareAndSet(false, true)) {
139                                         DatabaseException e = new DatabaseException("Internal error in RelationInfoQuery");
140                                         except(e);
141                                         proc.exception(graph, e);
142                                 }
143                         }
144                         
145                 });
146                 
147 //          Types.queryEach(callerThread, id, queryProvider, this, null, new InternalProcedure<IntSet>() {
148 //              
149 //          @Override
150 //          public void execute(int callerThread, IntSet types) {
151 //                computeAssertions(callerThread, isFinal, isFunctional, queryProvider, proc);
152 ////              
153 ////              
154 //////              System.out.println("RelationInfoQuery: computeTypes execute " + types);
155 ////
156 ////              RelationInfo result = new RelationInfo(id, types.contains(queryProvider.getFunctionalRelation()), isFinal);
157 ////              
158 ////              addOrSet(callerThread, result, queryProvider);
159 ////              
160 ////              proc.execute(callerThread, result);
161 ////              
162 //          }
163 //                      
164 //                      @Override
165 //                      public void exception(int callerThread, Throwable t) {
166 //                              proc.exception(callerThread, t);
167 //          }
168 //
169 //      });
170
171         }
172         
173         private void computeTypes(ReadGraphImpl graph, final boolean isFinal, final QueryProcessor queryProvider, final InternalProcedure<RelationInfo> proc) {
174         
175 //        System.out.println("RelationInfoQuery: computeTypes " + id);
176
177             Types.queryEach(graph, id, queryProvider, this, null, new InternalProcedure<IntSet>() {
178                 
179             @Override
180             public void execute(ReadGraphImpl graph, IntSet types) {
181                 computeAssertions(graph, isFinal, types.contains(queryProvider.getFunctionalRelation()), queryProvider, proc);
182 //
183 ////                System.out.println("RelationInfoQuery: computeTypes execute " + types);
184 //
185 //                RelationInfo result = new RelationInfo(id, types.contains(queryProvider.getFunctionalRelation()), isFinal);
186 //                
187 //                addOrSet(callerThread, result, queryProvider);
188 //                
189 //                proc.execute(callerThread, result);
190 //                
191             }
192                         
193                         @Override
194                         public void exception(ReadGraphImpl graph, Throwable t) {
195                                 proc.exception(graph, t);
196             }
197
198         });
199
200         }
201         
202         @Override
203         public Object computeForEach(ReadGraphImpl graph, final QueryProcessor provider, final InternalProcedure<RelationInfo> procedure, boolean store) {
204             
205 //        System.out.println("RelationInfoQuery computeForEach begin " + id + " " + getResult() + " " + statusOrException);
206
207             final int superRelationOf = provider.getSuperrelationOf();
208         assert(superRelationOf != 0);
209         
210         DirectPredicates.queryEach(graph, id, provider, this, null, new IntProcedure() {
211             
212             boolean found = false;
213
214             @Override
215             public void execute(ReadGraphImpl graph, int i) {
216 //                System.out.println("RelationInfoQuery: execute " + i + " super = " + superRelationOf);
217                 if(i == superRelationOf) {
218                     computeTypes(graph, false, provider, procedure);
219                     found = true;
220                 }
221             }
222
223             @Override
224             public void finished(ReadGraphImpl graph) {
225 //                System.out.println("RelationInfoQuery: finished");
226                 if(!found) {
227                     computeTypes(graph, true, provider, procedure);
228                 }
229             }
230             
231             @Override
232             public void exception(ReadGraphImpl graph, Throwable t) {
233 //                System.out.println("RelationInfoQuery: exception");
234                 procedure.exception(graph, t);
235             }
236
237         });
238         
239         return getResult();
240         
241     }
242     
243     @Override
244     public String toString() {
245         return "RelationInfoQuery[" + id + "]";
246     }
247
248     public void addOrSet(ReadGraphImpl graph, final RelationInfo result, final QueryProcessor provider) {
249         
250         assert(isPending());
251         
252 //      ArrayList<InternalProcedure<RelationInfo>> p = null;
253         
254         synchronized(this) {
255
256             setResult(result);
257             setReady();
258         
259 //              p = procs;
260 //              procs = null;
261                 
262         }
263         
264 //      if(p != null) {
265 //          for(InternalProcedure<RelationInfo> proc : p) 
266 //              proc.execute(graph, (RelationInfo)result);
267 //      }
268         
269     }            
270
271     @Override
272     public Object performFromCache(ReadGraphImpl graph, QueryProcessor provider, InternalProcedure<RelationInfo> procedure) {
273
274         assert(isReady());
275         
276         if(handleException(graph, procedure)) return EXCEPTED;
277         
278         RelationInfo result = getResult();
279         
280         procedure.execute(graph, result);
281         
282         return result;
283
284     }
285     
286     @Override
287     public void recompute(ReadGraphImpl graph, QueryProcessor provider) {
288         
289         final Semaphore s = new Semaphore(0);
290         
291         computeForEach(graph, provider, new InternalProcedure<RelationInfo>() {
292
293             @Override
294             public void execute(ReadGraphImpl graph, RelationInfo result) {
295                 s.release();
296             }
297             
298             @Override
299             public void exception(ReadGraphImpl graph, Throwable t) {
300                 throw new Error("Error in recompute.", t);
301             }
302
303         }, true);
304         
305         while(!s.tryAcquire()) {
306                 provider.resume(graph);
307         }
308 //        try {
309 //            s.acquire();
310 //        } catch (InterruptedException e) {
311 //            throw new Error(e);
312 //        }
313
314     }
315     
316     @Override
317     public int type() {
318         return RequestFlags.IMMEDIATE_UPDATE;
319     }
320     
321 }