]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/AssertedStatements.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.db.impl / src / org / simantics / db / impl / query / AssertedStatements.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.AtomicInteger;\r
17 \r
18 import org.simantics.db.RelationInfo;\r
19 import org.simantics.db.exception.ManyObjectsForFunctionalRelationException;\r
20 import org.simantics.db.impl.graph.ReadGraphImpl;\r
21 import org.simantics.db.impl.procedure.InternalProcedure;\r
22 import org.simantics.db.impl.procedure.TripleIntProcedureAdapter;\r
23 import org.simantics.db.procedure.ListenerBase;\r
24 import org.simantics.db.request.RequestFlags;\r
25 \r
26 \r
27 final public class AssertedStatements extends CollectionBinaryQuery<TripleIntProcedure> {\r
28     \r
29 //    public ArrayList<TripleIntProcedure> procs;\r
30     \r
31     public AssertedStatements(final int r1, final int r2) {\r
32         super(r1, r2);\r
33     }\r
34 \r
35     public static AssertedStatements newInstance(final int r1, final int r2) {\r
36         return new AssertedStatements(r1, r2);\r
37     }\r
38     \r
39     final static AssertedStatements runner(ReadGraphImpl graph, final int r1, final int r2, final QueryProcessor provider, final AssertedStatements cached, final CacheEntry parent, final ListenerBase listener, final TripleIntProcedure procedure) {\r
40         \r
41         AssertedStatements entry = cached != null ? cached : (AssertedStatements)provider.assertedStatementsMap.get(id(r1,r2)); \r
42         if(entry == null) {\r
43                 \r
44                 entry = new AssertedStatements(r1, r2);\r
45                 entry.setPending();\r
46                 entry.clearResult(provider.querySupport);\r
47                 entry.putEntry(provider);\r
48                 \r
49             provider.performForEach(graph, entry, parent, listener, procedure);\r
50             \r
51             return entry;\r
52             \r
53         } else {\r
54                 \r
55             if(entry.isPending()) {\r
56                 synchronized(entry) {\r
57                     if(entry.isPending()) {\r
58                         throw new IllegalStateException();\r
59 //                      if(entry.procs == null) entry.procs = new ArrayList<TripleIntProcedure>();\r
60 //                        entry.procs.add(procedure);\r
61 //                        provider.registerDependencies(graph, entry, parent, listener, procedure, false);\r
62 //                        return entry;\r
63                     }\r
64                 }\r
65             }\r
66             provider.performForEach(graph, entry, parent, listener, procedure);\r
67         }\r
68         \r
69         return entry;\r
70         \r
71     }\r
72     \r
73     final public static AssertedStatements queryEach(ReadGraphImpl graph, final int r1, final int r2, final QueryProcessor provider, final CacheEntry parent, final ListenerBase listener, final TripleIntProcedure procedure) {\r
74         \r
75         assert(r1 != 0);\r
76         assert(r2 != 0);\r
77         \r
78         final AssertedStatements entry = (AssertedStatements)provider.assertedStatementsMap.get(id(r1,r2));\r
79         \r
80         if(parent == null && !(listener != null)) {\r
81             if(entry != null && entry.isReady()) { \r
82                 entry.performFromCache(graph, provider, procedure);\r
83                 return entry;\r
84             }\r
85         }\r
86 \r
87         return runner(graph, r1, r2, provider, entry, parent, listener, procedure);\r
88          \r
89     }\r
90 \r
91     @Override\r
92     public BinaryQuery<TripleIntProcedure> getEntry(QueryProcessor provider) {\r
93         return provider.assertedStatementsMap.get(id);\r
94     }\r
95         \r
96         @Override\r
97         public void putEntry(QueryProcessor provider) {\r
98         provider.assertedStatementsMap.put(id, this);\r
99         }\r
100 \r
101         @Override\r
102         final public void removeEntry(QueryProcessor provider) {\r
103             provider.assertedStatementsMap.remove(id);\r
104         }\r
105         \r
106         void computeInheritedAssertions(ReadGraphImpl graph, int type, final int predicate, final RelationInfo ri, final QueryProcessor queryProvider, final TripleIntProcedure proc) {\r
107             \r
108 //        final AtomicBoolean found = new AtomicBoolean(0);\r
109 \r
110             DirectObjects.queryEach(graph, type, queryProvider.getInherits(), queryProvider, this, null, new SyncIntProcedure() {\r
111 \r
112             @Override\r
113             public void run(ReadGraphImpl graph) {\r
114 \r
115 //                if(ri.isFunctional && found.get() == 1) {\r
116 //\r
117 //                    ManyObjectsForFunctionalRelationException exception = new ManyObjectsForFunctionalRelationException("Functional relation has assertions from multiple inherited types.");\r
118 //                    except(exception);\r
119 //                    proc.exception(graph, exception);\r
120 //                    return;\r
121 //                    \r
122 //                }\r
123 \r
124                 finish(graph, queryProvider);\r
125                 proc.finished(graph);\r
126                 \r
127             }\r
128 \r
129             @Override\r
130             public void execute(ReadGraphImpl graph, int inh) {\r
131                 \r
132 //                if(ri.isFunctional && found.get() == 1) return;\r
133 \r
134                 inc();\r
135                 \r
136                 AssertedStatements.queryEach(graph, inh, predicate, queryProvider, AssertedStatements.this, null, new TripleIntProcedureAdapter() {\r
137 \r
138                     @Override\r
139                     public void execute(ReadGraphImpl graph, int s, int p, int o) {\r
140 \r
141 //                        if(ri.isFunctional) {\r
142 //                            \r
143 ////                            if(found.get() == 1) return;\r
144 //\r
145 //                            if(found.compareAndSet(0, o)) {\r
146                                 if(addOrSet(s,p,o))\r
147                                         proc.execute(graph, s, p, o);\r
148 //                            }\r
149 //                            // If this was a duplicate, we can ignore this\r
150 //                            else if (found.compareAndSet(o, o)) {\r
151 //                                //System.err.println("duplicates!");\r
152 //                            }\r
153 //                            // Otherwise we have error\r
154 //                            else {\r
155 //                                found.set(1);\r
156 //                            }\r
157 //                            \r
158 //                        } else {\r
159 //                            \r
160 //                            addOrSet(s, p, o);\r
161 //                            proc.execute(graph, s, p, o);\r
162 //                            \r
163 //                        }\r
164                         \r
165                     }\r
166 \r
167                     @Override\r
168                     public void finished(ReadGraphImpl graph) {\r
169                         dec(graph);\r
170                     }\r
171                                 \r
172                                 @Override\r
173                                 public void exception(ReadGraphImpl graph, Throwable t) {\r
174                                         proc.exception(graph, t);\r
175                                         dec(graph);\r
176                     }\r
177                     \r
178                 });\r
179                 \r
180             }\r
181 \r
182             @Override\r
183             public void finished(ReadGraphImpl graph) {\r
184                 dec(graph);\r
185             }\r
186             \r
187         });\r
188 \r
189         }\r
190 \r
191     void computeLocalAssertions(ReadGraphImpl graph, final int type, final int predicate, final RelationInfo ri, final QueryProcessor queryProvider, final TripleIntProcedure proc) {\r
192         \r
193         final AtomicInteger found = new AtomicInteger(0);\r
194 \r
195         DirectObjects.queryEach(graph, type, queryProvider.getAsserts(), queryProvider, this, null, new SyncIntProcedure() {\r
196 \r
197             @Override\r
198             public void run(ReadGraphImpl graph) {\r
199                 \r
200                 if(ri.isFunctional && found.get() > 1) {\r
201 \r
202                     ManyObjectsForFunctionalRelationException exception = new ManyObjectsForFunctionalRelationException("Functional relation has more than one asserted statement.");\r
203                     except(exception);\r
204                     proc.exception(graph, exception);\r
205                     return;\r
206                     \r
207                 }\r
208 \r
209                 if(ri.isFunctional && found.get() == 1) {\r
210                                         \r
211                     finish(graph, queryProvider);\r
212                     proc.finished(graph);\r
213                     return;\r
214                     \r
215                 }\r
216 \r
217                 computeInheritedAssertions(graph, type, predicate, ri, queryProvider, proc);\r
218                 \r
219             }\r
220 \r
221             @Override\r
222             public void execute(ReadGraphImpl graph, final int ass) {\r
223                 \r
224                 if(ri.isFunctional && found.get() > 1) return;\r
225                 \r
226                 inc();\r
227                 \r
228                 DirectObjects.queryEach(graph, ass, queryProvider.getHasPredicate(), queryProvider, AssertedStatements.this, null, new IntProcedure() {\r
229 \r
230                     @Override\r
231                     public void execute(ReadGraphImpl graph, final int pred) {\r
232                         \r
233                         if(ri.isFunctional) {\r
234                             \r
235                             if(found.get() > 1) return;\r
236 \r
237                             inc();\r
238 \r
239                             DirectObjects.queryEach(graph, ass, queryProvider.getHasObject(), queryProvider, AssertedStatements.this, null, new IntProcedure() {\r
240 \r
241                                 @Override\r
242                                 public void execute(ReadGraphImpl graph, final int object) {\r
243                                     \r
244                                     if(found.get() > 1) return;\r
245 \r
246                                     if(pred == predicate) {\r
247 \r
248                                         if(found.getAndIncrement() == 0) {\r
249                                                 if(addOrSet(type, pred, object))\r
250                                                         proc.execute(graph, type, pred, object);\r
251                                         }\r
252                                         \r
253                                         return;\r
254                                         \r
255                                     }\r
256                                     \r
257                                     if ( !ri.isFinal ) {\r
258 \r
259                                         inc();\r
260 \r
261                                         SuperRelations.queryEach(graph, pred, queryProvider, AssertedStatements.this, null, new InternalProcedure<IntSet>() {\r
262                                             \r
263                                             @Override\r
264                                             public void execute(ReadGraphImpl graph, IntSet result) {\r
265                                                 \r
266                                                 if(found.get() > 1) {\r
267                                                     dec(graph);\r
268                                                     return;\r
269                                                 }\r
270 \r
271                                                 if(result.contains(predicate)) {\r
272                     \r
273                                                     if(found.getAndIncrement() == 0) {\r
274                                                                 if(addOrSet(type, pred, object))\r
275                                                                         proc.execute(graph, type, pred, object);\r
276                                                         }\r
277                                                     \r
278                                                 }\r
279                                                 \r
280                                                 dec(graph);\r
281                                                 \r
282                                             }\r
283                                                         \r
284                                                         @Override\r
285                                                         public void exception(ReadGraphImpl graph, Throwable t) {\r
286                                                             \r
287                                                                 proc.exception(graph, t);\r
288                                                 dec(graph);\r
289                                                                 \r
290                                             }\r
291 \r
292                                         });\r
293 \r
294                                     }\r
295 \r
296                                 }\r
297                                 \r
298                                 @Override\r
299                                 public void finished(ReadGraphImpl graph) {\r
300                                     dec(graph);\r
301                                 }\r
302                                         \r
303                                         @Override\r
304                                         public void exception(ReadGraphImpl graph, Throwable t) {\r
305                                                 proc.exception(graph, t);\r
306                                     dec(graph);\r
307                                 }\r
308 \r
309                             });\r
310                             \r
311                         } else {\r
312 \r
313                             inc();\r
314 \r
315                             DirectObjects.queryEach(graph, ass, queryProvider.getHasObject(), queryProvider, AssertedStatements.this, null, new IntProcedure() {\r
316 \r
317                                 @Override\r
318                                 public void execute(ReadGraphImpl graph, final int object) {\r
319                                     \r
320                                     if(pred == predicate) {\r
321 \r
322                                         addOrSet(type, pred, object);\r
323                                         proc.execute(graph, type, pred, object);\r
324                                         return;\r
325                                         \r
326                                     }\r
327                                     \r
328                                     if ( !ri.isFinal ) {\r
329 \r
330                                         inc();\r
331 \r
332                                         SuperRelations.queryEach(graph, pred, queryProvider, AssertedStatements.this, null, new InternalProcedure<IntSet>() {\r
333                                             \r
334                                             @Override\r
335                                             public void execute(ReadGraphImpl graph, IntSet result) {\r
336                                                 \r
337                                                 if(result.contains(predicate)) {\r
338                     \r
339                                                     addOrSet(type, pred, object);\r
340                                                     proc.execute(graph, type, pred, object);\r
341 \r
342                                                 }\r
343                                                 \r
344                                                 dec(graph);\r
345                                                 \r
346                                             }\r
347                                                         \r
348                                                         @Override\r
349                                                         public void exception(ReadGraphImpl graph, Throwable t) {\r
350                                                                 proc.exception(graph, t);\r
351                                                 dec(graph);\r
352                                             }\r
353  \r
354                                         });\r
355 \r
356                                     }\r
357 \r
358                                 }\r
359                                 \r
360                                 @Override\r
361                                 public void finished(ReadGraphImpl graph) {\r
362                                     dec(graph);\r
363                                 }\r
364                                         \r
365                                         @Override\r
366                                         public void exception(ReadGraphImpl graph, Throwable t) {\r
367                                                 proc.exception(graph, t);\r
368                                     dec(graph);\r
369                                 }\r
370 \r
371                             });\r
372 \r
373                         }\r
374 \r
375                     }\r
376 \r
377                     @Override\r
378                     public void finished(ReadGraphImpl graph) {\r
379                         dec(graph);\r
380                     }\r
381                                 \r
382                                 @Override\r
383                                 public void exception(ReadGraphImpl graph, Throwable t) {\r
384                                         proc.exception(graph, t);\r
385                         dec(graph);\r
386                     }\r
387 \r
388                 });\r
389                 \r
390             }\r
391 \r
392             @Override\r
393             public void finished(ReadGraphImpl graph) {\r
394                 dec(graph);\r
395             }\r
396             \r
397         });\r
398         \r
399     }\r
400 \r
401         @Override\r
402     public void computeForEach(ReadGraphImpl graph, final QueryProcessor provider, final TripleIntProcedure procedure, boolean store) {\r
403         \r
404         RelationInfoQuery.queryEach(graph, r2(), provider, this, null, new InternalProcedure<RelationInfo>() {\r
405 \r
406             @Override\r
407             public void execute(ReadGraphImpl graph, RelationInfo ri) {\r
408                 \r
409                 computeLocalAssertions(graph, r1(), r2(), ri, provider, procedure);\r
410                 \r
411             }\r
412                         \r
413                         @Override\r
414                         public void exception(ReadGraphImpl graph, Throwable t) {\r
415                                 procedure.exception(graph, t);\r
416             }\r
417  \r
418         });\r
419         \r
420     }\r
421     \r
422     @Override\r
423     public String toString() {\r
424         return "AssertedStatements2[" + r1() + " - " + r2() + "]";\r
425     }\r
426 \r
427     private boolean addOrSet(int s, int p, int o) {\r
428         \r
429         assert(isPending());\r
430         \r
431         IntArray value = (IntArray)getResult();\r
432         if(value.data != null) {\r
433                         for(int i = 0;i < value.sizeOrData ; i+=3) {\r
434                                 int existingP = value.data[i+1];\r
435                                 if(p == existingP) {\r
436                                         int existingO = value.data[i+2];\r
437                                         if(existingO == o) return false;\r
438                                 }\r
439                         }\r
440                 value.add(s);\r
441                 value.add(p);\r
442                 value.add(o);\r
443         } else {\r
444                 value.add(s);\r
445                 value.add(p);\r
446                 value.add(o);\r
447         }\r
448         \r
449         return true;\r
450         \r
451     }\r
452     \r
453     final private void finish(ReadGraphImpl graph, QueryProcessor provider) {\r
454         \r
455         assert(isPending());\r
456 \r
457 //        ArrayList<TripleIntProcedure> p = null;\r
458 \r
459         synchronized(this) {\r
460                 \r
461                 setReady();\r
462 //            p = procs;\r
463 //            procs = null; \r
464         \r
465         }\r
466         \r
467 //        if(p != null) {\r
468 //              final IntArray value = (IntArray)getResult();\r
469 //              for(TripleIntProcedure proc : p) {\r
470 //                      for(int i=0;i<value.size();i+=3) {\r
471 //                              proc.execute(graph, value.data[i], value.data[i+1], value.data[i+2]);\r
472 //                      }\r
473 //              }\r
474 //\r
475 //              for(TripleIntProcedure proc : p) proc.finished(graph);\r
476 //        }\r
477 \r
478     }\r
479 \r
480     @Override\r
481     public void performFromCache(ReadGraphImpl graph, QueryProcessor provider, final TripleIntProcedure procedure) {\r
482         \r
483         assert(isReady());\r
484         \r
485         if(handleException(graph, procedure)) return;\r
486         \r
487         final IntArray value = (IntArray)getResult();\r
488         for(int i=0;i<value.size();i+=3) {\r
489                 procedure.execute(graph, value.data[i], value.data[i+1], value.data[i+2]);\r
490         }\r
491 \r
492         procedure.finished(graph);\r
493         \r
494     }\r
495     \r
496     @Override\r
497     public void recompute(ReadGraphImpl graph, QueryProcessor provider) {\r
498         \r
499         final Semaphore s = new Semaphore(0);\r
500 \r
501         computeForEach(graph, provider, new TripleIntProcedureAdapter() {\r
502 \r
503             @Override\r
504             public void finished(ReadGraphImpl graph) {\r
505                 s.release();\r
506             }\r
507                         \r
508                         @Override\r
509                         public void exception(ReadGraphImpl graph, Throwable t) {\r
510                                 throw new Error("Error in recompute", t);\r
511             }\r
512     \r
513         }, true);\r
514         \r
515         try {\r
516             s.acquire();\r
517         } catch (InterruptedException e) {\r
518             throw new Error(e);\r
519         }\r
520         \r
521     }\r
522     \r
523     @Override\r
524     public int type() {\r
525         return RequestFlags.IMMEDIATE_UPDATE;\r
526     }\r
527     \r
528 \r
529     @Override\r
530     boolean isImmutable(ReadGraphImpl graph) {\r
531         return graph.processor.isImmutable(r1());\r
532     }\r
533     \r
534 }\r