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