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