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