]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Statements.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.db.impl / src / org / simantics / db / impl / query / Statements.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
3  * in Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.db.impl.query;\r
13 \r
14 import java.util.ArrayList;\r
15 import java.util.Collection;\r
16 import java.util.concurrent.Semaphore;\r
17 import java.util.concurrent.atomic.AtomicBoolean;\r
18 \r
19 import org.simantics.db.RelationInfo;\r
20 import org.simantics.db.common.exception.DebugException;\r
21 import org.simantics.db.exception.ManyObjectsForFunctionalRelationException;\r
22 import org.simantics.db.impl.graph.ReadGraphImpl;\r
23 import org.simantics.db.impl.procedure.InternalProcedure;\r
24 import org.simantics.db.impl.procedure.TripleIntProcedureAdapter;\r
25 import org.simantics.db.procedure.ListenerBase;\r
26 import org.simantics.db.request.RequestFlags;\r
27 \r
28 final public class Statements extends CollectionBinaryQuery<TripleIntProcedure> {\r
29         \r
30 //      public ArrayList<TripleIntProcedure> procs = null;\r
31         \r
32     public Statements(final int r1, final int r2) {\r
33         super(r1, r2);\r
34     }\r
35 \r
36     final static Statements entry(final QueryProcessor processor, final int r1, final int r2) {\r
37         \r
38         return (Statements)processor.statementsMap.get(id(r1,r2));\r
39 \r
40     }\r
41     \r
42         final static Collection<Statements> entries(final QueryProcessor processor, final int r1) {\r
43                 return processor.statementsMap.values(r1);\r
44         }\r
45     \r
46     final static void runner(ReadGraphImpl graph, final int r1, final int r2, CacheEntry parent, final ListenerBase listener, final TripleIntProcedure procedure) {\r
47         \r
48         QueryProcessor processor = graph.processor;\r
49 \r
50         Statements entry = (Statements)processor.statementsMap.get(id(r1,r2));\r
51         if(entry == null) {\r
52                 \r
53                 entry = new Statements(r1, r2);\r
54                 entry.setPending();\r
55                 entry.clearResult(processor.querySupport);\r
56                 entry.putEntry(processor);\r
57                 \r
58                 processor.performForEach(graph, entry, parent, listener, procedure);\r
59             \r
60         } else {\r
61                 \r
62             if(entry.isPending()) {\r
63                 synchronized(entry) {\r
64                     if(entry.isPending()) {\r
65                         throw new IllegalStateException();\r
66 //                        if(entry.procs == null) entry.procs = new ArrayList<TripleIntProcedure>();\r
67 //                      entry.procs.add(procedure);\r
68 //                      processor.registerDependencies(graph, entry, parent, listener, procedure, false);\r
69 //                      return;\r
70                     }\r
71                 }\r
72             }\r
73             \r
74             processor.performForEach(graph, entry, parent, listener, procedure);\r
75             \r
76         }\r
77 \r
78     }\r
79     \r
80     final public static void queryEach(ReadGraphImpl graph, final int r1, final int r2, final QueryProcessor provider, final CacheEntry parent, final ListenerBase listener, final TripleIntProcedure procedure) {\r
81         \r
82         assert(r1 != 0);\r
83         assert(r2 != 0);\r
84         \r
85         if(parent == null && listener == null) {\r
86                 Statements.computeForEach(graph, r1, r2, null, procedure);\r
87                 return;\r
88         }\r
89         \r
90         runner(graph, r1, r2, parent, listener, procedure);\r
91          \r
92     }\r
93 \r
94     @Override\r
95     public BinaryQuery<TripleIntProcedure> getEntry(QueryProcessor provider) {\r
96         return provider.statementsMap.get(id);\r
97     }\r
98         \r
99         @Override\r
100         public void putEntry(QueryProcessor provider) {\r
101             provider.statementsMap.put(id, this);\r
102         }\r
103 \r
104         @Override\r
105         final public void removeEntry(QueryProcessor provider) {\r
106         provider.statementsMap.remove(id);\r
107         }\r
108         \r
109     final static TripleIntProcedure NOPT = new TripleIntProcedure() {\r
110 \r
111 \r
112                 @Override\r
113                 public void exception(ReadGraphImpl graph, Throwable throwable) {\r
114                 }\r
115 \r
116                 @Override\r
117                 public void execute(ReadGraphImpl graph, int s, int p, int o) {\r
118                 }\r
119 \r
120                 @Override\r
121                 public void finished(ReadGraphImpl graph) {\r
122                 }\r
123         \r
124     };\r
125         \r
126     final static private IntArray getAssertionMap(ReadGraphImpl graph, final int r1, final int r2, final Statements entry) {\r
127         \r
128         class AssertionMapProc implements IntProcedure {\r
129                 \r
130                 boolean first = true;\r
131 \r
132                 private IntArray result;\r
133 \r
134                 public void addStatement(int s, int p, int o) {\r
135                         \r
136                         if(result.size() == 0) {\r
137                                 result.add(s);\r
138                                 result.add(p);\r
139                                 result.add(o);\r
140                         } else {\r
141                                 for(int i = 0;i < result.sizeOrData ; i+=3) {\r
142                                         int existingP = result.data[i+1];\r
143                                         if(p == existingP) {\r
144                                                 int existingO = result.data[i+2];\r
145                                                 if(existingO == o) return;\r
146                                         }\r
147                                 }\r
148                                 result.add(s);\r
149                                 result.add(p);\r
150                                 result.add(o);\r
151                         }\r
152                         \r
153                 }\r
154                 \r
155             @Override\r
156             public void execute(ReadGraphImpl graph, int type) {\r
157                 AssertedStatements stms = AssertedStatements.queryEach(graph, type, r2, graph.processor, entry, null, NOPT);\r
158                 if(result == null) {\r
159                         result = stms.getResult();\r
160                 } else {\r
161                         if (first) {\r
162                                 IntArray ia = result;\r
163                                 result = new IntArray();\r
164                                 if(ia.data != null) {\r
165                                         for(int i = 0;i < ia.sizeOrData ; i+=3) addStatement(ia.data[i],ia.data[i+1],ia.data[i+2]);\r
166                                 }\r
167                                 first = false;\r
168                         }\r
169                         IntArray ia = stms.getResult();\r
170                         if(ia.data != null) {\r
171                                 for(int i = 0;i < ia.sizeOrData ; i+=3) addStatement(ia.data[i],ia.data[i+1],ia.data[i+2]);\r
172                         }\r
173                 }\r
174             }\r
175 \r
176             @Override\r
177             public void finished(ReadGraphImpl graph) {\r
178             }\r
179 \r
180                 @Override\r
181                 public void exception(ReadGraphImpl graph, Throwable throwable) {\r
182                 }\r
183 \r
184         }\r
185         \r
186         AssertionMapProc amp = new AssertionMapProc();\r
187 \r
188         // This dependency could be cut\r
189         PrincipalTypes.queryEach(graph, r1, graph.processor, entry, null, amp);\r
190         \r
191         return amp.result;\r
192         \r
193     }\r
194         \r
195     final static private void forSingleAssertion(ReadGraphImpl graph, final int r1, final int r2, final Statements entry, final TripleIntProcedure procedure) {\r
196         \r
197         IntArray map = getAssertionMap(graph, r1, r2, entry);\r
198         if(map == null) {\r
199             if(entry != null) entry.finish(graph, procedure);\r
200                 else procedure.finished(graph);\r
201             return;\r
202         }\r
203         \r
204         int size = map.size();\r
205         if(size == 3) {\r
206 \r
207                 int s = map.data[0];\r
208                 int p = map.data[1];\r
209                 int o = map.data[2];\r
210                 \r
211             if(entry != null) {\r
212                 entry.addOrSetFunctional(s,p,o);\r
213                 entry.finish(graph, procedure);\r
214             } else {\r
215                         procedure.execute(graph, s,p,o);\r
216                         procedure.finished(graph);\r
217                 }\r
218 \r
219         } else if(size == 0) {\r
220 \r
221             if(entry != null) entry.finish(graph, procedure);\r
222                 else procedure.finished(graph);\r
223                 \r
224         } else {\r
225 \r
226                 int candidateS = map.data[0];\r
227                 int candidateP = map.data[1];\r
228                 int candidateO = map.data[2];\r
229 \r
230                         SuperTypes candidate = SuperTypes.queryEach(graph, candidateS, graph.processor, entry, null, NOP);\r
231                         if(candidate.isExcepted()) {\r
232                                 if(entry != null) entry.except((Throwable)candidate.getResult());\r
233                                 procedure.exception(graph, (Throwable)candidate.getResult());\r
234                                 return;\r
235                         }\r
236                         IntSet candidateIs = candidate.getResult();\r
237                 \r
238                         for(int i=3;i<map.size();i+=3) {\r
239 \r
240                                 int nextS = map.data[i];\r
241                                 int nextP = map.data[i+1];\r
242                                 int nextO = map.data[i+2];\r
243                         \r
244                                 if(nextS != candidateS) {\r
245 \r
246                                 if(candidateIs.contains(nextS)) {\r
247                                         \r
248                                         // Next is a super type of candidate => ignore next\r
249                                         \r
250                                 } else {\r
251                                 \r
252                                         SuperTypes next = SuperTypes.queryEach(graph, nextS, graph.processor, entry, null, NOP);\r
253                                         if(next.isExcepted()) {\r
254                                                 if(entry != null) entry.except((Throwable)next.getResult());\r
255                                                 procedure.exception(graph, (Throwable)next.getResult());\r
256                                                 return;\r
257                                         }\r
258                                         IntSet nextIs = next.getResult();\r
259                                         \r
260                                         if(nextIs.contains(candidateS)) {\r
261 \r
262                                                 // Candidate is a super type of next => next is the new candidate\r
263                                                 \r
264                                                 candidateS = nextS;\r
265                                                 candidateP = nextP;\r
266                                                 candidateO = nextO;\r
267                                                 candidateIs = nextIs;\r
268                                                 \r
269                                         } else {\r
270 \r
271                                                 // candidate and next are unrelated => error\r
272                                                 ManyObjectsForFunctionalRelationException exception = new ManyObjectsForFunctionalRelationException("Functional relation has conflicting assertions.", r1);\r
273                                                 \r
274                                                 if(entry != null) entry.except(exception);\r
275                                                 procedure.exception(graph, exception);\r
276                                                 return;                                         \r
277                                                 \r
278                                         }\r
279                                 \r
280                                 }\r
281                                 \r
282                         }\r
283                         \r
284                 }\r
285                 \r
286                 if(entry != null) {\r
287                 entry.addOrSetFunctional(candidateS, candidateP, candidateO);\r
288                 entry.finish(graph, procedure);\r
289             } else {\r
290                         procedure.execute(graph, candidateS, candidateP, candidateO);\r
291                         procedure.finished(graph);\r
292                 }\r
293                 \r
294         }\r
295         \r
296     }\r
297     \r
298     final static InternalProcedure<IntSet> NOP = new InternalProcedure<IntSet>() {\r
299 \r
300                 @Override\r
301                 public void execute(ReadGraphImpl graph, IntSet result) {\r
302                 }\r
303 \r
304                 @Override\r
305                 public void exception(ReadGraphImpl graph, Throwable throwable) {\r
306                 }\r
307         \r
308     };\r
309         \r
310         // Search for one statement\r
311         final static public void computeFunctionalIndex(ReadGraphImpl graph, final int r1, final int r2, final Statements entry, final RelationInfo ri, final TripleIntProcedure procedure) {\r
312         \r
313         if(ri.isFinal) {\r
314             \r
315                 int result = graph.processor.querySupport.getFunctionalObject(r1, r2);\r
316 \r
317                 if(result == 0) {\r
318 \r
319                 // Check for assertions\r
320                 forSingleAssertion(graph, r1, r2, entry, procedure);\r
321 \r
322                 } else if(result == -1) {\r
323 \r
324                 graph.processor.querySupport.getObjects(graph, r1, r2, new IntProcedure() {\r
325 \r
326                         @Override\r
327                         public void execute(ReadGraphImpl graph, int i) {\r
328                                 if(entry != null) entry.addOrSetFunctional(r1, r2, i);\r
329                                 else procedure.execute(graph, r1, r2, i);\r
330                         }\r
331 \r
332                         @Override\r
333                         public void exception(ReadGraphImpl graph, Throwable t) {\r
334                                 if(DebugException.DEBUG) new DebugException(t).printStackTrace();\r
335                         }\r
336 \r
337                         @Override\r
338                         public void finished(ReadGraphImpl graph) {\r
339                         }\r
340 \r
341                 });\r
342 \r
343                 // Check for assertions\r
344                 forSingleAssertion(graph, r1, r2, entry, procedure);\r
345                         \r
346                 } else {\r
347 \r
348                 // If functional relation was found there is no need to check assertions\r
349                         if(entry != null) {\r
350                                 entry.addOrSetFunctional(r1, r2, result);\r
351                                 entry.finish(graph, procedure);\r
352                         } else {\r
353                                 procedure.execute(graph, r1, r2, result);\r
354                                 procedure.finished(graph);\r
355                         }\r
356                         \r
357                 }\r
358 \r
359             \r
360         } else {\r
361             \r
362             final AtomicBoolean found = new AtomicBoolean(false);\r
363             \r
364             // Note! The dependency is intentionally cut!\r
365             DirectPredicates.queryEach(graph, r1, graph.processor, null, null, new SyncIntProcedure() {\r
366                 \r
367                 @Override\r
368                 public void run(ReadGraphImpl graph) {\r
369                     \r
370                     if(found.get()) {\r
371                         if(entry != null) entry.finish(graph, procedure);\r
372                         else procedure.finished(graph);\r
373                     } else {\r
374                     \r
375                             // Check for assertions\r
376                             forSingleAssertion(graph, r1, r2, entry, procedure);\r
377                             \r
378                     }\r
379                     \r
380                 }\r
381 \r
382                 @Override\r
383                 public void execute(ReadGraphImpl graph, final int pred) {\r
384                     \r
385                     if(found.get()) return;\r
386 \r
387                     if(pred == r2) {\r
388                         \r
389                         inc();\r
390                         \r
391                         // Note! The dependency is intentionally cut!\r
392                         DirectObjects.queryEach(graph, r1, pred, graph.processor, null, null, new IntProcedure() {\r
393 \r
394                             @Override\r
395                             public void execute(ReadGraphImpl graph, int i) {\r
396                                 \r
397                                 if(found.compareAndSet(false, true)) {\r
398                                     \r
399                                     if(entry != null) entry.addOrSetFunctional(r1, pred, i);\r
400                                     else procedure.execute(graph, r1, pred, i);\r
401                                         \r
402                                 } else {\r
403 \r
404                                         ManyObjectsForFunctionalRelationException exception = new ManyObjectsForFunctionalRelationException("Functional relation has more than one statement.", r1);\r
405                                         if(entry != null) entry.except(exception);\r
406                                         procedure.exception(graph, exception);\r
407                                         \r
408                                 }\r
409 \r
410                             }\r
411 \r
412                             @Override\r
413                             public void finished(ReadGraphImpl graph) {\r
414                                 dec(graph);\r
415                             }\r
416                                                 \r
417                                                 @Override\r
418                                                 public void exception(ReadGraphImpl graph, Throwable t) {\r
419                                                         procedure.exception(graph, t);\r
420                                 dec(graph);\r
421                                     }\r
422 \r
423                         });\r
424 \r
425                     } else {\r
426                         \r
427                         inc();\r
428                     \r
429                         SuperRelations.queryEach(graph, pred, graph.processor, entry, null, new InternalProcedure<IntSet>() {\r
430     \r
431                             @Override\r
432                             public void execute(ReadGraphImpl graph, IntSet result) {\r
433                                 \r
434                                 if(found.get()) {\r
435                                     dec(graph);\r
436                                     return;\r
437                                 }\r
438 \r
439                                 if(result.contains(r2)) {\r
440                                     \r
441                                     inc();\r
442                                     \r
443                                     // Note! The dependency is intentionally cut!\r
444                                     DirectObjects.queryEach(graph, r1, pred, graph.processor, null, null, new IntProcedure() {\r
445     \r
446                                         @Override\r
447                                         public void execute(ReadGraphImpl graph, int i) {\r
448                                             \r
449                                                 if(found.compareAndSet(false, true)) {\r
450                                                 \r
451                                                 if(entry != null) entry.addOrSetFunctional(r1, pred, i);\r
452                                                 else procedure.execute(graph, r1, pred, i);\r
453                                                         \r
454                                                 } else {\r
455 \r
456                                                 ManyObjectsForFunctionalRelationException exception = new ManyObjectsForFunctionalRelationException("Functional relation has more than one statement.", r1);\r
457                                                 if(entry != null) entry.except(exception);\r
458                                                 procedure.exception(graph, exception);\r
459                                                         \r
460                                                 }\r
461                                             \r
462                                         }\r
463     \r
464                                         @Override\r
465                                         public void finished(ReadGraphImpl graph) {\r
466                                             dec(graph);\r
467                                         }\r
468                                                         \r
469                                                         @Override\r
470                                                         public void exception(ReadGraphImpl graph, Throwable t) {\r
471                                                                 procedure.exception(graph, t);\r
472                                             dec(graph);\r
473                                             }\r
474 \r
475                                     });\r
476     \r
477                                 }\r
478                                 \r
479                                 dec(graph);\r
480                                 \r
481                             }\r
482                                                 \r
483                                                 @Override\r
484                                                 public void exception(ReadGraphImpl graph, Throwable t) {\r
485                                                         procedure.exception(graph, t);\r
486                                 dec(graph);\r
487                                     }\r
488 \r
489                         });\r
490                         \r
491                     }\r
492                     \r
493                 }\r
494 \r
495                 @Override\r
496                 public void finished(ReadGraphImpl graph) {\r
497                     \r
498                     dec(graph);\r
499                     \r
500                 }\r
501                 \r
502             });\r
503             \r
504         }\r
505 \r
506         }\r
507     \r
508     final static private void forAssertions(ReadGraphImpl graph, final int r1, final int r2, final Statements entry, final TripleIntProcedure procedure) {\r
509 \r
510         PrincipalTypes.queryEach(graph, r1, graph.processor, entry, null, new SyncIntProcedure() {\r
511             \r
512             @Override\r
513             public void run(ReadGraphImpl graph) {\r
514                 \r
515                 if(entry != null) entry.finish(graph, procedure);\r
516                 else procedure.finished(graph);\r
517                 \r
518             }\r
519             \r
520             TripleIntProcedure proc = new TripleIntProcedureAdapter() {\r
521 \r
522                 @Override\r
523                 public void execute(ReadGraphImpl graph, int s, int p, int o) {\r
524                         if(entry != null) entry.addOrSet(s, p, o);\r
525                         else procedure.execute(graph, s, p, o);\r
526                 }\r
527 \r
528                 @Override\r
529                 public void finished(ReadGraphImpl graph) {\r
530                     dec(graph);\r
531                 }\r
532                                 \r
533                                 @Override\r
534                                 public void exception(ReadGraphImpl graph, Throwable t) {\r
535                     dec(graph);\r
536                                         procedure.exception(graph, t);\r
537                     }\r
538 \r
539             }; \r
540 \r
541             @Override\r
542             public void execute(ReadGraphImpl graph, int type) {\r
543 \r
544                 inc();\r
545                 \r
546                 AssertedStatements.queryEach(graph, type, r2, graph.processor, entry, null, proc);\r
547                 \r
548             }\r
549             \r
550             @Override\r
551             public void finished(ReadGraphImpl graph) {\r
552                 dec(graph);       \r
553             }\r
554             \r
555             @Override\r
556             public void exception(ReadGraphImpl graph, Throwable t) {\r
557                 dec(graph);\r
558             }\r
559             \r
560         });\r
561         \r
562 \r
563     }\r
564 \r
565         final static public void computeNotFunctionalIndex(ReadGraphImpl graph, final int r1, final int r2, final Statements entry,  final RelationInfo ri, final TripleIntProcedure procedure) {\r
566 \r
567                 if(ri.isFinal) {\r
568 \r
569                         graph.processor.querySupport.getObjects(graph, r1, r2, new IntProcedure() {\r
570 \r
571                                 @Override\r
572                                 public void execute(ReadGraphImpl graph, int i) {\r
573                                         if(entry != null) entry.addOrSet(r1, r2, i);\r
574                                         else procedure.execute(graph, r1, r2, i);\r
575                                 }\r
576 \r
577                                 @Override\r
578                                 public void exception(ReadGraphImpl graph, Throwable t) {\r
579                                         if(DebugException.DEBUG) new DebugException(t).printStackTrace();\r
580                                         procedure.exception(graph, t);\r
581                                 }\r
582 \r
583                                 @Override\r
584                                 public void finished(ReadGraphImpl graph) {\r
585                                 }\r
586 \r
587                         });\r
588 \r
589                         if(ri.isAsserted) {\r
590                                 forAssertions(graph, r1, r2, entry, procedure);\r
591                         } else {\r
592                                 if(entry != null) entry.finish(graph, procedure);\r
593                                 else procedure.finished(graph);\r
594                         }\r
595 \r
596         } else {\r
597 \r
598             // Note! The dependency is intentionally cut!\r
599             DirectPredicates.queryEach(graph, r1, graph.processor, null, null, new SyncIntProcedure() {\r
600                 \r
601                 @Override\r
602                 public void run(ReadGraphImpl graph) {\r
603                     \r
604                     forAssertions(graph, r1, r2, entry, procedure);\r
605                     \r
606                 }\r
607 \r
608                 @Override\r
609                 public void execute(ReadGraphImpl graph, final int pred2) {\r
610 \r
611                     if(pred2 == r2) {\r
612                         \r
613                         inc();\r
614                         \r
615                         // Note! The dependency is intentionally cut!\r
616                         DirectObjects.queryEach(graph, r1, pred2, graph.processor, null, null, new IntProcedure() {\r
617 \r
618                             @Override\r
619                             public void execute(ReadGraphImpl graph, int i) {\r
620                                 if(entry != null) entry.addOrSet(r1, pred2, i);\r
621                                 else procedure.execute(graph, r1, pred2, i);\r
622                             }\r
623 \r
624                             @Override\r
625                             public void finished(ReadGraphImpl graph) {\r
626                                 dec(graph);\r
627                             }\r
628                                                 \r
629                                                 @Override\r
630                                                 public void exception(ReadGraphImpl graph, Throwable t) {\r
631                                                         procedure.exception(graph, t);\r
632                                 dec(graph);\r
633                                     }\r
634 \r
635                         });\r
636 \r
637                     } else {\r
638                     \r
639 //                        inc();\r
640 \r
641                         try {\r
642                             \r
643                             IntSet result = SuperRelations.queryEach2(graph, pred2, graph.processor, entry, null, null);\r
644                             if(result.contains(r2)) {\r
645 \r
646                                 inc();\r
647 \r
648                                 // Note! The dependency is intentionally cut!\r
649                                 DirectObjects.queryEach(graph, r1, pred2, graph.processor, null, null, new IntProcedure() {\r
650 \r
651                                     @Override\r
652                                     public void execute(ReadGraphImpl graph, int i) {\r
653                                         if(entry != null) entry.addOrSet(r1, pred2, i);\r
654                                         else procedure.execute(graph, r1, pred2, i);\r
655 \r
656                                     }\r
657 \r
658                                     @Override\r
659                                     public void finished(ReadGraphImpl graph) {\r
660                                         dec(graph);\r
661                                     }\r
662 \r
663                                     @Override\r
664                                     public void exception(ReadGraphImpl graph, Throwable t) {\r
665                                         procedure.exception(graph, t);\r
666                                         dec(graph);\r
667                                     }\r
668 \r
669                                 });\r
670 \r
671                             }\r
672                             \r
673                         } catch (Throwable e) {\r
674                             procedure.exception(graph, e);\r
675                         }\r
676 \r
677                     }\r
678                     \r
679                 }\r
680 \r
681                 @Override\r
682                 public void finished(ReadGraphImpl graph) {\r
683                     dec(graph);\r
684                 }\r
685                 \r
686             });\r
687             \r
688         }\r
689         \r
690     }\r
691     \r
692     @Override\r
693     public void computeForEach(ReadGraphImpl graph, final QueryProcessor provider, final TripleIntProcedure procedure, final boolean store) {\r
694         computeForEach(graph, r1(), r2(), this, procedure);\r
695     }\r
696         \r
697     public static void computeForEach(ReadGraphImpl graph, final int r1, final int r2, final Statements entry, final TripleIntProcedure procedure) {\r
698 \r
699         RelationInfoQuery riEntry = RelationInfoQuery.probe(graph, r2);\r
700         if(riEntry != null) {\r
701                 RelationInfo ri = riEntry.getResult();\r
702                 graph.ensureLoaded(r1, r2);       \r
703                 if(ri.isFunctional) {\r
704                         computeFunctionalIndex(graph, r1, r2, entry, ri, procedure);\r
705                 } else {\r
706                         computeNotFunctionalIndex(graph, r1, r2, entry, ri, procedure);\r
707                 }\r
708                 return;\r
709         }\r
710         \r
711         RelationInfoQuery.queryEach(graph, r2, graph.processor, entry, null, new InternalProcedure<RelationInfo>() {\r
712 \r
713             @Override\r
714             public void execute(ReadGraphImpl graph, final RelationInfo ri) {\r
715                 \r
716                 graph.ensureLoaded(r1, r2);\r
717                 if(ri.isFunctional) {\r
718                         computeFunctionalIndex(graph, r1, r2, entry, ri, procedure);\r
719                 } else {\r
720                         computeNotFunctionalIndex(graph, r1, r2, entry, ri, procedure);\r
721                 }\r
722                 \r
723             }\r
724                         \r
725                         @Override\r
726                         public void exception(ReadGraphImpl graph, Throwable t) {\r
727                                 procedure.exception(graph, t);\r
728             }\r
729 \r
730         });\r
731         \r
732     }\r
733     \r
734     @Override\r
735     public String toString() {\r
736         return "Statements[" + r1() + " - " + r2() + "]";\r
737     }\r
738 \r
739     final private void finish(ReadGraphImpl graph, TripleIntProcedure procedure) {\r
740         \r
741         assert(assertPending());\r
742 \r
743 //        ArrayList<TripleIntProcedure> p = null;\r
744 \r
745         synchronized(this) {\r
746 \r
747             setReady();\r
748 //            p = procs;\r
749 //            procs = null;\r
750 \r
751         }\r
752 \r
753         IntArray v = (IntArray)getResult();\r
754         final IntArray value = (IntArray)getResult();\r
755 \r
756 //        if(p != null) {\r
757 //\r
758 //              for(TripleIntProcedure proc : p) {\r
759 //                      for(int i=0;i<value.size();i+=3) {\r
760 //                              proc.execute(graph, value.data[i], value.data[i+1], value.data[i+2]);\r
761 //                      }\r
762 //              }\r
763 //              for(int i=0;i<value.size();i+=3) {\r
764 //                      procedure.execute(graph, value.data[i], value.data[i+1], value.data[i+2]);\r
765 //              }\r
766 //\r
767 //            for(TripleIntProcedure proc : p) proc.finished(graph);\r
768 //\r
769 //        }\r
770 \r
771         for(int i=0;i<value.size();i+=3) {\r
772                 procedure.execute(graph, value.data[i], value.data[i+1], value.data[i+2]);\r
773         }\r
774         \r
775         procedure.finished(graph);\r
776         \r
777     }\r
778 \r
779 //    final private void finish(ReadGraphImpl graph, QueryProcessor provider) {\r
780 //        \r
781 //      assert(isPending());\r
782 //\r
783 //        ArrayList<TripleIntProcedure> p = null;\r
784 //\r
785 //        synchronized(this) {\r
786 //              \r
787 //              setReady();\r
788 //            p = procs;\r
789 //            procs = null; \r
790 //        \r
791 //        }\r
792 //        \r
793 //        if(p != null) {\r
794 //              \r
795 //              final IntArray value = (IntArray)getResult();\r
796 //              for(TripleIntProcedure proc : p) {\r
797 //                      for(int i=0;i<value.size();i+=3) {\r
798 //                              proc.execute(graph, value.data[i], value.data[i+1], value.data[i+2]);\r
799 //                      }\r
800 //              }\r
801 //\r
802 //              for(TripleIntProcedure proc : p) proc.finished(graph);\r
803 //\r
804 //        }\r
805 //\r
806 //    }\r
807     \r
808     synchronized public void addOrSet(int s, int p, int o) {\r
809         \r
810         assert(assertPending());\r
811         \r
812         IntArray value = (IntArray)getResult();\r
813         value.add(s);\r
814         value.add(p);\r
815         value.add(o);\r
816         \r
817     }\r
818 \r
819     final static public int r1(long id) {\r
820         return (int)(id>>>32);\r
821     }\r
822     \r
823     final static public int r2(long id) {\r
824         return (int)id;\r
825     }\r
826     \r
827     final public void addOrSetFunctional(int s, long po) {\r
828         \r
829         addOrSetFunctional(s, r1(po), r2(po));\r
830         \r
831     }\r
832 \r
833     final public void addOrSetFunctional(int s, int p, int o) {\r
834         \r
835         assert(assertPending());\r
836         \r
837         IntArray value = (IntArray)getResult();\r
838         value.add(s);\r
839         value.add(p);\r
840         value.add(o);\r
841         \r
842     }\r
843     \r
844     @Override\r
845     public void performFromCache(ReadGraphImpl graph, QueryProcessor provider, final TripleIntProcedure procedure) {\r
846 \r
847         assert(isReady());\r
848 \r
849         if(handleException(graph, procedure)) return;\r
850         \r
851         final IntArray value = (IntArray)getResult();\r
852         for(int i=0;i<value.size();i+=3) {\r
853                 procedure.execute(graph, value.data[i], value.data[i+1], value.data[i+2]);\r
854         }\r
855 \r
856         procedure.finished(graph);\r
857         \r
858     }\r
859     \r
860     @Override\r
861     public void recompute(ReadGraphImpl graph, QueryProcessor provider) {\r
862         \r
863         final Semaphore s = new Semaphore(0);\r
864         \r
865         computeForEach(graph, provider, new TripleIntProcedureAdapter() {\r
866 \r
867             @Override\r
868             public void finished(ReadGraphImpl graph) {\r
869                 s.release();\r
870             }\r
871                         \r
872                         @Override\r
873                         public void exception(ReadGraphImpl graph, Throwable t) {\r
874                                 new Error("Error in recompute.", t).printStackTrace();\r
875                                 s.release();\r
876             }\r
877 \r
878         }, true);\r
879         \r
880         while(!s.tryAcquire()) {\r
881                 provider.resume(graph);\r
882         }\r
883         \r
884 //        try {\r
885 //            s.acquire();\r
886 //        } catch (InterruptedException e) {\r
887 //            throw new Error(e);\r
888 //        }\r
889         \r
890     }\r
891 \r
892     @Override\r
893     public int type() {\r
894         return RequestFlags.IMMEDIATE_UPDATE;\r
895     }\r
896     \r
897 \r
898     @Override\r
899     boolean isImmutable(ReadGraphImpl graph) {\r
900         return graph.processor.isImmutable(r1());\r
901     }\r
902     \r
903 }\r