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