]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/DirectStatements.java
Fixed multiple issues causing dangling references to discarded queries
[simantics/platform.git] / bundles / org.simantics.db.impl / src / org / simantics / db / impl / query / DirectStatements.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 org.simantics.db.impl.graph.ReadGraphImpl;
15 import org.simantics.db.procedure.AsyncProcedure;
16 import org.simantics.db.procedure.ListenerBase;
17 import org.simantics.db.procedure.Procedure;
18
19
20 final public class DirectStatements /*extends CollectionBinaryQuery<TripleIntProcedure>*/ {
21
22         /*
23         public DirectStatements(final int r1, final int r2) {
24                 super(r1, r2);
25         }
26
27         public static DirectStatements newInstance(final int r1, final int r2) {
28                 return new DirectStatements(r1, r2);
29         }
30
31         final static DirectStatements entry(final QueryProcessor provider, final int r1, final int r2) {
32
33                 return (DirectStatements)provider.statementsMap[provider.resourceThread(r1)].get(id(r1,r2));
34
35         }
36
37         final static Collection<DirectStatements> entries(final QueryProcessor processor, final int r1) {
38                 BinaryQueryHashMap<TripleIntProcedure> hash = processor.statementsMap[processor.resourceThread(r1)];
39                 return hash.values(r1);
40         }
41         */
42         
43         final public static void queryEach(ReadGraphImpl graph, final int r, final QueryProcessor provider, final CacheEntry parent, final ListenerBase listener, final AsyncProcedure<org.simantics.db.DirectStatements> procedure, boolean ignoreVirtual) {
44
45                 assert(r != 0);
46
47                 org.simantics.db.DirectStatements result = provider.querySupport.getStatements(graph, r, provider, ignoreVirtual);
48                 procedure.execute(graph, result);
49
50         }
51
52         final public static void queryEach(ReadGraphImpl graph, final int r, final QueryProcessor provider, final CacheEntry parent, final ListenerBase listener, final Procedure<org.simantics.db.DirectStatements> procedure) {
53
54                 assert(r != 0);
55
56                 try {
57
58                         org.simantics.db.DirectStatements result = provider.querySupport.getStatements(graph, r, provider, true);
59                         procedure.execute(result);
60                         
61 //                      provider.querySupport.getStatements(graph, r, procedure);
62
63                 } catch (Throwable t) {
64
65                         t.printStackTrace();
66
67                 }
68
69         }
70
71         /*
72         @Override
73         public BinaryQuery<TripleIntProcedure> getEntry(int callerThread, QueryProcessor provider) {
74                 return provider.statementsMap[callerThread].get(id);
75         }
76
77         @Override
78         public void putEntry(int callerThread, QueryProcessor provider) {
79                 provider.statementsMap[callerThread].put(id, this);
80         }
81
82         @Override
83         final public void removeEntry(int callerThread, QueryProcessor provider) {
84                 provider.statementsMap[callerThread].remove(id);
85         }
86
87         final private void forSingleAssertion(ReadGraphImpl graph, final QueryProcessor queryProvider, final TripleIntProcedure procedure) {
88
89                 final AtomicInteger results = new AtomicInteger();
90
91                 PrincipalTypes.queryEach(graph, r1(), queryProvider, this, null, new SyncIntProcedure() {
92
93                         @Override
94                         public void run(ReadGraphImpl graph) {
95
96                                 int rc = results.get();
97
98                                 if(isExcepted()) {
99
100                                         procedure.exception(graph, (Throwable)getResult());
101
102                                 } else {
103
104                                         // No result or single result
105                                         if(rc == 0 || rc == 1) {
106
107                                                 finish(graph, queryProvider);
108                                                 procedure.finished(graph);
109
110                                         } else {
111
112                                                 ManyObjectsForFunctionalRelationException exception = new ManyObjectsForFunctionalRelationException("Functional relation has more than one statement.", r1());
113                                                 except(exception);
114                                                 procedure.exception(graph, exception);
115
116                                         }
117
118                                 }
119
120                         }
121
122                         @Override
123                         public void execute(ReadGraphImpl graph, int type) {
124
125                                 inc();
126
127                                 AssertedStatements.queryEach(graph, type, r2(), queryProvider, DirectStatements.this, null, new TripleIntProcedureAdapter() {
128
129                                         @Override
130                                         public void execute(ReadGraphImpl graph, int s, int p, int o) {
131
132                                                 int event = results.getAndIncrement();
133                                                 if(event == 0) {
134
135                                                         addOrSet(s, p, o);
136                                                         procedure.execute(graph, s, p, o);
137
138                                                 }
139
140                                         }
141
142                                         @Override
143                                         public void finished(ReadGraphImpl graph) {
144
145                                                 dec(graph);
146
147                                         }
148
149                                         @Override
150                                         public void exception(ReadGraphImpl graph, Throwable t) {
151
152                                                 except(t);
153                                                 dec(graph);
154
155                                         }
156
157                                 });
158
159                         }
160
161                         @Override
162                         public void finished(ReadGraphImpl graph) {
163
164                                 dec(graph);
165
166                         }
167
168                 });
169
170         }
171
172         // Search for one statement
173         final public void computeFunctionalIndex(ReadGraphImpl graph, final QueryProcessor provider, final RelationInfo ri, final TripleIntProcedure procedure, final boolean store) {
174
175                 if(ri.isFinal) {
176
177                         boolean found = provider.querySupport.getObjects(graph, r1(), r2(), new IntProcedure() {
178
179                                 @Override
180                                 public void execute(ReadGraphImpl graph, int i) {
181                                         addOrSet(r1(), r2(), i);
182                                 }
183
184                                 @Override
185                                 public void exception(ReadGraphImpl graph, Throwable t) {
186                                         if(DebugException.DEBUG) new DebugException(t).printStackTrace();
187                                 }
188
189                                 @Override
190                                 public void finished(ReadGraphImpl graph) {
191                                 }
192
193                         });
194
195                         // If functional relation was found there is no need to check assertions
196                         if(found) {
197
198                                 final IntArray array = (IntArray)getResult();
199                                 if(array.size() > 3) {
200                                         Throwable exception = new ManyObjectsForFunctionalRelationException("Functional relation " + r2() + " has multiple objects " + Arrays.toString(array.toArray()) + " for subject " + r1());
201                                         except(exception);
202                                         procedure.exception(graph, exception);
203                                         return;
204                                 }
205                                 procedure.execute(graph, array.data[0], array.data[1], array.data[2]);
206                                 finish(graph, provider);
207                                 procedure.finished(graph);
208                                 return;
209
210                         }
211
212                         // Check for assertions
213                         forSingleAssertion(graph, provider, procedure);
214
215
216                 } else {
217
218                         final AtomicBoolean found = new AtomicBoolean(false);
219
220                         DirectPredicates.queryEach(graph, r1(), provider, DirectStatements.this, null, new SyncIntProcedure() {
221
222                                 @Override
223                                 public void run(ReadGraphImpl graph) {
224
225                                         if(found.get()) return;
226
227                                         // Check for assertions
228                                         forSingleAssertion(graph, provider, procedure);
229
230                                 }
231
232                                 @Override
233                                 public void execute(ReadGraphImpl graph, final int pred) {
234
235                                         if(found.get()) return;
236
237                                         if(pred == r2()) {
238
239                                                 inc();
240
241                                                 DirectObjects.queryEach(graph, r1(), pred, provider, DirectStatements.this, null, new IntProcedure() {
242
243                                                         @Override
244                                                         public void execute(ReadGraphImpl graph, int i) {
245
246                                                                 if(found.compareAndSet(false, true)) {
247
248                                                                         addOrSet(r1(), pred, i);
249                                                                         finish(graph, provider);
250                                                                         procedure.execute(graph, r1(), pred, i);
251                                                                         procedure.finished(graph);
252
253                                                                 } else {
254
255                                                                         ManyObjectsForFunctionalRelationException exception = new ManyObjectsForFunctionalRelationException("Functional relation has more than one statement.", r1());
256                                                                         except(exception);
257                                                                         procedure.exception(graph, exception);
258
259                                                                 }
260
261                                                         }
262
263                                                         @Override
264                                                         public void finished(ReadGraphImpl graph) {
265
266                                                                 dec(graph);
267
268                                                         }
269
270                                                         @Override
271                                                         public void exception(ReadGraphImpl graph, Throwable t) {
272                                                                 procedure.exception(graph, t);
273                                                         }
274
275                                                 });
276
277                                         } else {
278
279                                                 inc();
280
281                                                 SuperRelations.queryEach(graph, pred, provider, DirectStatements.this, null, new InternalProcedure<IntSet>() {
282
283                                                         @Override
284                                                         public void execute(ReadGraphImpl graph, IntSet result) {
285
286                                                                 if(found.get()) {
287                                                                         dec(graph);
288                                                                         return;
289                                                                 }
290
291                                                                 if(result.contains(r2())) {
292
293                                                                         inc();
294
295                                                                         DirectObjects.queryEach(graph, r1(), pred, provider, DirectStatements.this, null, new IntProcedure() {
296
297                                                                                 @Override
298                                                                                 public void execute(ReadGraphImpl graph, int i) {
299
300                                                                                         if(found.compareAndSet(false, true)) {
301
302                                                                                                 addOrSet(r1(), pred, i);
303                                                                                                 finish(graph, provider);
304                                                                                                 procedure.execute(graph, r1(), pred, i);
305                                                                                                 procedure.finished(graph);
306
307                                                                                         } else {
308
309                                                                                                 ManyObjectsForFunctionalRelationException exception = new ManyObjectsForFunctionalRelationException("Functional relation has more than one statement.", r1());
310                                                                                                 except(exception);
311                                                                                                 procedure.exception(graph, exception);
312
313                                                                                         }
314
315                                                                                 }
316
317                                                                                 @Override
318                                                                                 public void finished(ReadGraphImpl graph) {
319
320                                                                                         dec(graph);
321
322                                                                                 }
323
324                                                                                 @Override
325                                                                                 public void exception(ReadGraphImpl graph, Throwable t) {
326                                                                                         procedure.exception(graph, t);
327                                                                                 }
328
329                                                                         });
330
331                                                                 }
332
333                                                                 dec(graph);
334
335                                                         }
336
337                                                         @Override
338                                                         public void exception(ReadGraphImpl graph, Throwable t) {
339                                                                 procedure.exception(graph, t);
340                                                         }
341
342                                                 });
343
344                                         }
345
346                                 }
347
348                                 @Override
349                                 public void finished(ReadGraphImpl graph) {
350
351                                         dec(graph);
352
353                                 }
354
355                         });
356
357                 }
358
359         }
360
361         final private void forAssertions(ReadGraphImpl graph, final QueryProcessor queryProvider, final TripleIntProcedure procedure) {
362
363                 PrincipalTypes.queryEach(graph, r1(), queryProvider, this, null, new SyncIntProcedure() {
364
365                         @Override
366                         public void run(ReadGraphImpl graph) {
367
368                                 finish(graph, queryProvider);
369                                 procedure.finished(graph);
370
371                         }
372
373                         TripleIntProcedure proc = new TripleIntProcedureAdapter() {
374
375                                 @Override
376                                 public void execute(ReadGraphImpl graph, int s, int p, int o) {
377                                         addOrSet(s, p, o);
378                                         procedure.execute(graph, s, p, o);
379                                 }
380
381                                 @Override
382                                 public void finished(ReadGraphImpl graph) {
383                                         dec(graph);
384                                 }
385
386                                 @Override
387                                 public void exception(ReadGraphImpl graph, Throwable t) {
388                                         procedure.exception(graph, t);
389                                 }
390
391                         }; 
392
393                         @Override
394                         public void execute(ReadGraphImpl graph, int type) {
395
396                                 inc();
397
398                                 AssertedStatements.queryEach(graph, type, r2(), queryProvider, DirectStatements.this, null, proc);
399
400                         }
401
402                         @Override
403                         public void finished(ReadGraphImpl graph) {
404                                 dec(graph);       
405                         }
406
407                 });
408
409
410         }
411
412         final public void computeNotFunctionalIndex(ReadGraphImpl graph, final QueryProcessor provider, RelationInfo ri, final TripleIntProcedure procedure, final boolean store) {
413
414                 if(ri.isFinal) {
415
416                         provider.querySupport.getObjects(graph, r1(), r2(), new IntProcedure() {
417
418                                 @Override
419                                 public void execute(ReadGraphImpl graph, int i) {
420                                         addOrSet(r1(), r2(), i);
421                                 }
422
423                                 @Override
424                                 public void exception(ReadGraphImpl graph, Throwable t) {
425                                         if(DebugException.DEBUG) new DebugException(t).printStackTrace();
426                                         procedure.exception(graph, t);
427                                 }
428
429                                 @Override
430                                 public void finished(ReadGraphImpl graph) {
431                                 }
432
433                         });
434
435                         final IntArray value = (IntArray)getResult();
436                         for(int i=0;i<value.size();i+=3) {
437                                 procedure.execute(graph, value.data[i], value.data[i+1], value.data[i+2]);
438                         }
439
440                         forAssertions(graph, provider, procedure);
441
442                 } else {
443
444                         DirectPredicates.queryEach(graph, r1(), provider, DirectStatements.this, null, new SyncIntProcedure() {
445
446                                 @Override
447                                 public void run(ReadGraphImpl graph) {
448
449                                         forAssertions(graph, provider, procedure);
450
451                                 }
452
453                                 @Override
454                                 public void execute(ReadGraphImpl graph, final int pred) {
455
456                                         //                      System.out.println("directpredicates execute " + pred);
457
458                                         if(pred == r2()) {
459
460                                                 inc();
461
462                                                 DirectObjects.queryEach(graph, r1(), pred, provider, DirectStatements.this, null, new IntProcedure() {
463
464                                                         @Override
465                                                         public void execute(ReadGraphImpl graph, int i) {
466                                                                 //                              System.out.println("pred=" + pred + " object=" + i);
467                                                                 addOrSet(r1(), pred, i);
468                                                                 procedure.execute(graph, r1(), pred, i);
469                                                         }
470
471                                                         @Override
472                                                         public void finished(ReadGraphImpl graph) {
473                                                                 dec(graph);
474                                                         }
475
476                                                         @Override
477                                                         public void exception(ReadGraphImpl graph, Throwable t) {
478                                                                 procedure.exception(graph, t);
479                                                         }
480
481                                                 });
482
483                                         } else {
484
485                                                 inc();
486
487                                                 SuperRelations.queryEach(graph, pred, provider, DirectStatements.this, null, new InternalProcedure<IntSet>() {
488
489                                                         @Override
490                                                         public void execute(ReadGraphImpl graph, IntSet result) {
491
492                                                                 if(result.contains(r2())) {
493
494                                                                         inc();
495
496                                                                         DirectObjects.queryEach(graph, r1(), pred, provider, DirectStatements.this, null, new IntProcedure() {
497
498                                                                                 @Override
499                                                                                 public void execute(ReadGraphImpl graph, int i) {
500
501                                                                                         //                                              if(pred == 65548)
502                                                                                         //                                                      System.out.println("s=" + r1() + "p=" + pred + " o=" + i);
503
504                                                                                         addOrSet(r1(), pred, i);
505                                                                                         procedure.execute(graph, r1(), pred, i);
506
507                                                                                 }
508
509                                                                                 @Override
510                                                                                 public void finished(ReadGraphImpl graph) {
511                                                                                         dec(graph);
512                                                                                 }
513
514                                                                                 @Override
515                                                                                 public void exception(ReadGraphImpl graph, Throwable t) {
516                                                                                         procedure.exception(graph, t);
517                                                                                 }
518
519                                                                         });
520
521                                                                 }
522
523                                                                 dec(graph);
524
525                                                         }
526
527                                                         @Override
528                                                         public void exception(ReadGraphImpl graph, Throwable t) {
529                                                                 procedure.exception(graph, t);
530                                                         }
531
532                                                 });
533
534                                         }
535
536                                 }
537
538                                 @Override
539                                 public void finished(ReadGraphImpl graph) {
540                                         dec(graph);
541                                 }
542
543                         });
544
545                 }
546
547         }
548
549
550         @Override
551         public void computeForEach(ReadGraphImpl graph, final QueryProcessor provider, final TripleIntProcedure procedure, final boolean store) {
552
553                 RelationInfoQuery.queryEach(graph, r2(), provider, this, null, new InternalProcedure<RelationInfo>() {
554
555                         @Override
556                         public void execute(ReadGraphImpl graph, final RelationInfo ri) {
557
558                                 provider.querySupport.ensureLoaded(graph, r1(), r2());
559                                 if(ri.isFunctional) {
560                                         computeFunctionalIndex(graph, provider, ri, procedure, store);
561                                 } else {
562                                         computeNotFunctionalIndex(graph, provider, ri, procedure, store);
563                                 }
564                                 
565                         }
566
567                         @Override
568                         public void exception(ReadGraphImpl graph, Throwable t) {
569                                 procedure.exception(graph, t);
570                         }
571
572                 });
573
574         }
575
576         @Override
577         public String toString() {
578                 return "Statements[" + r1() + " - " + r2() + "]";
579         }
580
581         final private void finish(ReadGraphImpl graph, QueryProcessor provider) {
582
583                 assert(isPending());
584
585                 synchronized(this) {
586                         setReady();
587                 }
588
589         }
590
591         synchronized public void addOrSet(int s, int p, int o) {
592
593                 assert(isPending());
594
595                 IntArray value = (IntArray)getResult();
596                 value.add(s);
597                 value.add(p);
598                 value.add(o);
599
600         }
601
602         @Override
603         public void performFromCache(ReadGraphImpl graph, QueryProcessor provider, final TripleIntProcedure procedure) {
604
605                 assert(isReady());
606
607         if(handleException(graph, procedure)) return;
608                 
609                 final IntArray value = (IntArray)getResult();
610                 for(int i=0;i<value.size();i+=3) {
611                         procedure.execute(graph, value.data[i], value.data[i+1], value.data[i+2]);
612                 }
613
614                 procedure.finished(graph);
615
616         }
617
618         @Override
619         public void recompute(ReadGraphImpl graph, QueryProcessor provider) {
620
621                 final Semaphore s = new Semaphore(0);
622
623                 computeForEach(graph, provider, new TripleIntProcedureAdapter() {
624
625                         @Override
626                         public void finished(ReadGraphImpl graph) {
627                                 s.release();
628                         }
629
630                         @Override
631                         public void exception(ReadGraphImpl graph, Throwable t) {
632                                 new Error("Error in recompute.", t).printStackTrace();
633                                 s.release();
634                         }
635
636                 }, true);
637
638         while(!s.tryAcquire()) {
639                 provider.resume(graph);
640         }
641
642         }
643
644         @Override
645         public int type() {
646                 return RequestFlags.IMMEDIATE_UPDATE;
647         }
648         */
649
650 }