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