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