1 package org.simantics.db.procore.cluster;
\r
3 import org.simantics.db.Resource;
\r
4 import org.simantics.db.exception.DatabaseException;
\r
5 import org.simantics.db.exception.ExternalValueException;
\r
6 import org.simantics.db.impl.ClusterI;
\r
7 import org.simantics.db.impl.ClusterSupport;
\r
8 import org.simantics.db.impl.ClusterTraitsBase;
\r
9 import org.simantics.db.impl.Modifier;
\r
10 import org.simantics.db.impl.ResourceImpl;
\r
11 import org.simantics.db.impl.graph.ReadGraphImpl;
\r
12 import org.simantics.db.procedure.AsyncContextMultiProcedure;
\r
13 import org.simantics.db.procedure.AsyncMultiProcedure;
\r
16 public final class ResourceElementSmall {
\r
17 private static final boolean DEBUG = ClusterImpl.DEBUG;
\r
18 // Descriptor = type & complete object reference & value index & predicate index.
\r
19 private static final int DESCRIPTOR_OFFSET = 0; // descriptor
\r
20 private static final int STM_OFFSET = 1; // two statements
\r
21 private static final int SIZE_OF = 2;
\r
23 static void construct(long[] table, int index) {
\r
24 int i = DESCRIPTOR_OFFSET + index;
\r
25 table[i++] = 0; // descriptor
\r
26 table[i++] = 0; // stm1 & 2
\r
29 static void destruct(long[] table, int index) {
\r
30 int i = DESCRIPTOR_OFFSET + index;
\r
31 table[i++] = 0; // descriptor
\r
32 table[i++] = 0; // stm1 & 2
\r
35 static boolean isUsed(long[] table, int index) {
\r
36 int i = DESCRIPTOR_OFFSET + index;
\r
37 if (table[i++] != 0)
\r
39 if (table[i++] != 0)
\r
44 static int getSizeOf() {
\r
48 static ClusterI.CompleteTypeEnum getCompleteType(long[] table, int index) {
\r
49 int i = DESCRIPTOR_OFFSET + index;
\r
50 byte bits = (byte)BitUtility.getMiddle(table[i], 62, 2);
\r
51 return ClusterI.CompleteTypeEnum.make(bits);
\r
54 static void setCompleteType(long[] table, int index, byte data) {
\r
55 int i = DESCRIPTOR_OFFSET + index;
\r
56 table[i] = BitUtility.setMiddle(table[i], 62, 2, data);
\r
59 static short getCompleteObjectRef(long[] table, int index) {
\r
60 int i = DESCRIPTOR_OFFSET + index;
\r
61 return (short)BitUtility.getMiddle(table[i], 46, 16);
\r
64 static void setCompleteObjectRef(long[] table, int index, int ref) {
\r
65 if (ref > (1<<16)-1)
\r
66 throw new IllegalArgumentException();
\r
67 int i = DESCRIPTOR_OFFSET + index;
\r
68 table[i] = BitUtility.setMiddle(table[i], 46, 16, ref);
\r
71 static boolean completeHasMultiple(long[] table, int index) {
\r
72 int i = DESCRIPTOR_OFFSET + index;
\r
73 int completeRefAndType= BitUtility.getMiddle(table[i], 46, 18);
\r
74 boolean complete = (completeRefAndType >>> 16) != 0;
\r
75 return !complete && (completeRefAndType != 0);
\r
78 static boolean completeIsFirstStatement(long[] table, int index) {
\r
79 int i = DESCRIPTOR_OFFSET + index;
\r
80 int completeRefAndType = BitUtility.getMiddle(table[i], 46, 18);
\r
81 return completeRefAndType == 0;
\r
84 static boolean completeIsSameStatement(long[] table, int index, int refAndType) {
\r
85 int i = DESCRIPTOR_OFFSET + index;
\r
86 int completeRefAndType = BitUtility.getMiddle(table[i], 46, 18);
\r
87 return completeRefAndType == refAndType;
\r
90 static int completeGetRefAndType(long[] table, int index) {
\r
91 int i = DESCRIPTOR_OFFSET + index;
\r
92 return BitUtility.getMiddle(table[i], 46, 18);
\r
95 static void completeSetRefAndType(long[] table, int index, int refAndType) {
\r
96 int i = DESCRIPTOR_OFFSET + index;
\r
97 table[i] = BitUtility.setMiddle(table[i], 46, 18, refAndType);
\r
100 static int completeMakeObjectRefAndType(short oRef, ClusterI.CompleteTypeEnum completeType) {
\r
101 return oRef & (1<<16)-1 | completeType.getValue()<<16;
\r
104 static short completeGetObjectSetIndex(long[] table, int index) {
\r
105 int i = DESCRIPTOR_OFFSET + index;
\r
106 return (short)BitUtility.getMiddle(table[i], 46, 16);
\r
109 static int completeGetStatementCountApproximation(long[] table, int index) {
\r
110 int i = DESCRIPTOR_OFFSET + index;
\r
111 int cType = BitUtility.getMiddle(table[i], 62, 2);
\r
114 int cRef = BitUtility.getMiddle(table[i], 46, 16);
\r
116 return 2; // Can be bigger, hence the approximation.
\r
120 static int getValueIndex(long[] table, int index) {
\r
121 int i = DESCRIPTOR_OFFSET + index;
\r
122 int valueIndex = BitUtility.getMiddle(table[i], 24, 22);
\r
126 static void setValueIndex(long[] table, int index, int valueIndex) {
\r
127 int i = DESCRIPTOR_OFFSET + index;
\r
128 table[i] = BitUtility.setMiddle(table[i], 24, 22, valueIndex);
\r
131 static int getPredicateIndex(long[] table, int index) {
\r
132 int i = DESCRIPTOR_OFFSET + index;
\r
133 int predicateIndex = BitUtility.getMiddle(table[i], 0, 24);
\r
134 return predicateIndex;
\r
137 static void setPredicateIndex(long[] table, int index, int predicateIndex) {
\r
138 int i = DESCRIPTOR_OFFSET + index;
\r
139 table[i] = BitUtility.setMiddle(table[i], 0, 24, predicateIndex);
\r
142 static short getStm1Predicate(long[] table, int index) {
\r
143 int i = STM_OFFSET + index;
\r
144 short predicateIndex = BitUtility.getLowShort(table[i]);
\r
145 return predicateIndex;
\r
148 static void setStm1Predicate(long[] table, int index, short predicateIndex) {
\r
149 int i = STM_OFFSET + index;
\r
150 table[i] = BitUtility.setLowShort(table[i], predicateIndex);
\r
153 static short getStm1Object(long[] table, int index) {
\r
154 int i = STM_OFFSET + index;
\r
155 short objectIndex = (short)BitUtility.getMiddle(table[i], 16, 16);
\r
156 return objectIndex;
\r
159 static void setStm1Object(long[] table, int index, short objectIndex) {
\r
160 int i = STM_OFFSET + index;
\r
161 table[i] = BitUtility.setMiddle(table[i], 16, 16, objectIndex);
\r
164 static short getStm2Predicate(long[] table, int index) {
\r
165 int i = STM_OFFSET + index;
\r
166 short predicateIndex = (short)BitUtility.getMiddle(table[i], 32, 16);
\r
167 return predicateIndex;
\r
170 static void setStm2Predicate(long[] table, int index, short predicateIndex) {
\r
171 int i = STM_OFFSET + index;
\r
172 table[i] = BitUtility.setMiddle(table[i], 32, 16, predicateIndex);
\r
175 static short getStm2Object(long[] table, int index) {
\r
176 int i = STM_OFFSET + index;
\r
177 short objectIndex = (short)BitUtility.getMiddle(table[i], 48, 16);
\r
178 return objectIndex;
\r
181 static void setStm2Object(long[] table, int index, short objectIndex) {
\r
182 int i = STM_OFFSET + index;
\r
183 table[i] = BitUtility.setMiddle(table[i], 48, 16, objectIndex);
\r
186 public static byte[] getValue(ValueTableSmall valueTable, long[] table, int index)
\r
187 throws DatabaseException {
\r
188 int valueIndex = getValueIndex(table, index);
\r
189 if (0 == valueIndex)
\r
190 return null; // no value
\r
191 else if (ClusterTraitsSmall.VALUE_INDEX_EX == valueIndex)
\r
192 throw new ExternalValueException("Value stored externally. index=" + index);
\r
193 return valueTable.getValue(valueIndex);
\r
196 // static char[] getString(ValueTableSmall valueTable, long[] table, int index) {
\r
197 // int valueIndex = getValueIndex(table, index);
\r
198 // if (0 == valueIndex)
\r
199 // return null; // no value
\r
200 //// else if (ClusterTraitsSmall.VALUE_INDEX_MAX == valueIndex)
\r
201 //// throw new Error("Not implemented! //KRAA:");
\r
202 // return valueTable.getString(valueIndex);
\r
205 static boolean hasValue(long[] table, int index) {
\r
206 int valueIndex = getValueIndex(table, index);
\r
207 return 0 != valueIndex;
\r
210 // static boolean hasValue(ValueTable valueTable, long[] table, int index, byte[] value) {
\r
211 // int valueIndex = getValueIndex(table, index);
\r
212 // if (0 == valueIndex)
\r
214 // return valueTable.isEqual(valueIndex, value, 0, value.length);
\r
217 static boolean removeValue(ValueTableSmall valueTable, long[] table, int index) {
\r
218 int valueIndex = getValueIndex(table, index);
\r
219 if (0 == valueIndex)
\r
220 return false; // not removed
\r
221 else if (ClusterTraitsSmall.VALUE_INDEX_EX != valueIndex)
\r
222 valueTable.removeValue(valueIndex);
\r
223 setValueIndex(table, index, 0);
\r
227 public static void setValue(ValueTableSmall valueTable, long[] table, int index, byte[] value, int length)
\r
228 throws OutOfSpaceException {
\r
229 int oldIndex = getValueIndex(table, index);
\r
230 if (ClusterTraitsSmall.VALUE_INDEX_EX == oldIndex)
\r
232 if (length > ClusterTraitsSmall.VALUE_SIZE_MAX)
\r
233 throw new OutOfSpaceException("Out of space for value. size=" + length);
\r
234 int newIndex = valueTable.setValue(oldIndex, value, 0, length);
\r
235 if (newIndex != oldIndex) {
\r
236 if (newIndex > ClusterTraitsSmall.VALUE_INDEX_MAX) {
\r
237 setValueIndex(table, index, 0);
\r
238 throw new OutOfSpaceException("Out of space for values. index=" + newIndex);
\r
240 setValueIndex(table, index, newIndex);
\r
245 public static boolean isValueEx(ValueTableSmall valueTable, long[] table, int index) {
\r
246 int vIndex = getValueIndex(table, index);
\r
247 if (ClusterTraitsSmall.VALUE_INDEX_EX == vIndex)
\r
253 public static void setValueEx(ValueTableSmall valueTable, long[] table, int index) {
\r
254 setValueIndex(table, index, ClusterTraitsSmall.VALUE_INDEX_EX);
\r
257 public static <Context> boolean foreachPredicate(long[] table, int index,
\r
258 ClusterI.PredicateProcedure<Context> procedure,
\r
259 Context context, ClusterSupport support, Modifier modifier,
\r
261 throws DatabaseException {
\r
263 System.out.println("ResourceElement.foreachPredicate: 1");
\r
264 int completeRef = ResourceElementSmall.getCompleteObjectRef(table, index);
\r
265 if (0 != completeRef) {
\r
266 if (ResourceElementSmall.completeHasMultiple(table, index)) { // multiple complete objects
\r
267 // CompleteRef is a complete object set index.
\r
268 boolean broken = ct.foreachPredicate(completeRef, procedure, context, support, modifier);
\r
270 System.out.println("ResourceElement.foreachPredicate: multi-complete ci=" + completeRef + " break=" + broken);
\r
272 return true; // loop broken by procedure
\r
273 } else { // We have zero or one complete statement.
\r
274 ClusterI.CompleteTypeEnum completeType = ResourceElementSmall.getCompleteType(table, index);
\r
275 if (ClusterI.CompleteTypeEnum.NotComplete != completeType) {
\r
276 int key = ClusterTraitsBase.getCompleteTypeResourceKeyFromEnum(completeType);
\r
277 boolean broken = procedure.execute(context, key, 0);
\r
279 System.out.println("ResourceElement.foreachPredicate: complete rk=" + key + " break=" + broken);
\r
281 return true; // loop broken by procedure
\r
285 // If predicate set is in use it will contain also these statements.
\r
286 if (0 != ResourceElementSmall.getPredicateIndex(table, index)) {
\r
288 System.out.println("ResourceElement.foreachPredicate: more than 2 objects");
\r
291 int p1 = getStm1Predicate(table, index);
\r
294 System.out.println("ResourceElement.foreachPredicate: empty cache");
\r
295 return false; // loop finished, no statements
\r
298 if (null == modifier)
\r
301 externalRef = modifier.execute(p1);
\r
303 System.out.println("ResourceElement.foreachPredicate: cache1 pk=" + externalRef);
\r
304 if (procedure.execute(context, externalRef, 0))
\r
305 return true; // loop broken by procedure
\r
306 int p2 = getStm2Predicate(table, index);
\r
307 if (0 == p2 || p1 == p2) {
\r
309 System.out.println("ResourceElement.foreachPredicate: cache2 empty");
\r
310 return false; // loop finished, one predicate
\r
312 if (null == modifier)
\r
315 externalRef = modifier.execute(p2);
\r
317 System.out.println("ResourceElement.foreachPredicate: cache2 pk=" + externalRef);
\r
318 return procedure.execute(context, externalRef, 0);
\r
321 public static int getSingleObject(long[] table, int index, ClusterSupport support, final short pRef,
\r
322 final ClusterI.CompleteTypeEnum pCompleteType, CompleteTable ct, Modifier modifier)
\r
323 throws DatabaseException {
\r
325 System.out.println("ResourceElement.getSingleObject: index=" + index);
\r
326 if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType) {
\r
327 int completeRef = getCompleteObjectRef(table, index);
\r
328 if (0 == completeRef)
\r
329 return 0; // no objects for given complete type
\r
330 if (ResourceElementSmall.completeHasMultiple(table, index)) {
\r
331 // Multiple complete type statements.
\r
333 System.out.println("ResourceElement.was complete 2");
\r
334 ClusterI.ObjectProcedure<Short> proc = new ClusterI.ObjectProcedure<Short>() {
\r
336 public boolean execute(Short context, int completeRefAndType)
\r
337 throws DatabaseException {
\r
338 ClusterI.CompleteTypeEnum ct = ClusterTraitsSmall.completeRefAndTypeGetType(completeRefAndType);
\r
339 if (ct == pCompleteType) { // we have a match
\r
340 if (context != 0) { // we have an old match
\r
341 context = 0; // multiple objects for given type
\r
342 return true; // break loop
\r
344 context = ClusterTraitsSmall.completeRefAndTypeGetRef(completeRefAndType);
\r
346 return true; // continue looping
\r
349 Short objectRef = 0;
\r
350 // CompleteRef is complete object set index.
\r
351 ct.foreachComplete(completeRef, proc, objectRef, support, modifier);
\r
352 return modifier.execute(objectRef);
\r
353 } // One complete type statement.
\r
354 ClusterI.CompleteTypeEnum rCompleteType = ResourceElementSmall.getCompleteType(table, index);
\r
355 if (pCompleteType != rCompleteType)
\r
356 return 0; // no objects for given complete type
\r
357 // CompleteRef is object resource reference.
\r
358 return modifier.execute(completeRef);
\r
360 int p1 = getStm1Predicate(table, index);
\r
362 return 0; // loop finished, no statements
\r
365 short o1 = getStm1Object(table, index);
\r
366 result = modifier.execute(o1);
\r
367 // procedure.execute(graph, new ResourceImpl(null, modifier.execute(o1)));
\r
368 // int externalRef;
\r
369 // if (null == modifier)
\r
370 // externalRef = o1;
\r
372 // externalRef = modifier.execute(callerThread, o1);
\r
373 // if (procedure.execute(callerThread, context, externalRef))
\r
374 // return true; // loop broken by procedure
\r
376 int p2 = getStm2Predicate(table, index);
\r
377 if (0 == p2 || pRef != p2)
\r
378 return result; // loop finished, one statements
\r
381 if (result != 0) return -1;
\r
383 short o2 = getStm2Object(table, index);
\r
384 return modifier.execute(o2);
\r
385 // int externalRef;
\r
386 // if (null == modifier)
\r
387 // externalRef = o2;
\r
389 // externalRef = modifier.execute(callerThread, o2);
\r
390 // if (procedure.execute(callerThread, context, externalRef))
\r
391 // return true; // loop broken by procedure
\r
392 // return false; // loop finished
\r
393 // procedure.execute(graph, new ResourceImpl(null, modifier.execute(o2)));
\r
396 public static void foreachObject(long[] table, int index,
\r
397 final ReadGraphImpl graph, final AsyncMultiProcedure<Resource> procedure,
\r
398 ClusterSupport support, final int pRef, ClusterI.CompleteTypeEnum pCompleteType, CompleteTable ct, final Modifier modifier)
\r
399 throws DatabaseException {
\r
401 System.out.println("ResourceElement.foreachObject1: index=" + index);
\r
402 if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType) {
\r
403 int completeRef = getCompleteObjectRef(table, index);
\r
404 if (0 == completeRef) {
\r
405 procedure.finished(graph);
\r
406 // graph.state.dec(0);
\r
407 return; // no objects for given complete type
\r
409 if (ResourceElementSmall.completeHasMultiple(table, index)) {// multiple objects
\r
410 ClusterI.ObjectProcedure<Object> proc = new ClusterI.ObjectProcedure<Object>() {
\r
412 public boolean execute(Object _context, int objectRef)
\r
413 throws DatabaseException {
\r
414 procedure.execute(graph, new ResourceImpl(graph.getResourceSupport(), modifier.execute(objectRef)));
\r
415 return false; // continue looping
\r
419 // CompleteRef is complete object set index.
\r
420 ct.foreachComplete(completeRef, proc, null, support, modifier);
\r
421 } else { // One complete type element. CompleteRef is resource reference.
\r
422 ClusterI.CompleteTypeEnum rCompleteType = ResourceElementSmall.getCompleteType(table, index);
\r
423 if (pCompleteType != rCompleteType) {
\r
424 procedure.finished(graph);
\r
425 // graph.state.dec(0);
\r
426 return; // Complete predicate does not match.
\r
428 procedure.execute(graph, new ResourceImpl(graph.getResourceSupport(), modifier.execute(completeRef)));
\r
430 procedure.finished(graph);
\r
431 // graph.state.dec(0);
\r
432 return; // loop finished
\r
434 short p1 = getStm1Predicate(table, index);
\r
436 procedure.finished(graph);
\r
437 // graph.state.dec(0);
\r
438 return; // loop finished, no statements
\r
441 short o1 = getStm1Object(table, index);
\r
442 procedure.execute(graph, new ResourceImpl(graph.getResourceSupport(), modifier.execute(o1)));
\r
443 // int externalRef;
\r
444 // if (null == modifier)
\r
445 // externalRef = o1;
\r
447 // externalRef = modifier.execute(callerThread, o1);
\r
448 // if (procedure.execute(callerThread, context, externalRef))
\r
449 // return true; // loop broken by procedure
\r
451 short p2 = getStm2Predicate(table, index);
\r
452 if (0 == p2 || pRef != p2) {
\r
453 procedure.finished(graph);
\r
454 // graph.state.dec(0);
\r
455 return; // loop finished, one statements
\r
457 int o2 = getStm2Object(table, index);
\r
458 // int externalRef;
\r
459 // if (null == modifier)
\r
460 // externalRef = o2;
\r
462 // externalRef = modifier.execute(callerThread, o2);
\r
463 // if (procedure.execute(callerThread, context, externalRef))
\r
464 // return true; // loop broken by procedure
\r
465 // return false; // loop finished
\r
466 procedure.execute(graph, new ResourceImpl(graph.getResourceSupport(), modifier.execute(o2)));
\r
467 procedure.finished(graph);
\r
468 // graph.state.dec(0);
\r
471 public static <C> void foreachObject(long[] table, int index,
\r
472 final ReadGraphImpl graph, final C context, final AsyncContextMultiProcedure<C, Resource> procedure,
\r
473 ClusterSupport support, final int pRef, ClusterI.CompleteTypeEnum pCompleteType, CompleteTable ct, final Modifier modifier)
\r
474 throws DatabaseException {
\r
476 System.out.println("ResourceElement.foreachObject1: index=" + index);
\r
477 if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType) {
\r
478 int completeRef = getCompleteObjectRef(table, index);
\r
479 if (0 == completeRef) {
\r
480 procedure.finished(graph);
\r
481 // graph.state.dec(0);
\r
482 return; // no objects for given complete type
\r
484 if (ResourceElementSmall.completeHasMultiple(table, index)) {// multiple objects
\r
485 ClusterI.ObjectProcedure<Object> proc = new ClusterI.ObjectProcedure<Object>() {
\r
487 public boolean execute(Object _context, int objectRef)
\r
488 throws DatabaseException {
\r
489 procedure.execute(graph, context, new ResourceImpl(graph.getResourceSupport(), modifier.execute(objectRef)));
\r
490 return false; // continue looping
\r
494 // CompleteRef is complete object set index.
\r
495 ct.foreachComplete(completeRef, proc, null, support, modifier);
\r
496 } else { // One complete type element. CompleteRef is resource reference.
\r
497 ClusterI.CompleteTypeEnum rCompleteType = ResourceElementSmall.getCompleteType(table, index);
\r
498 if (pCompleteType != rCompleteType) {
\r
499 procedure.finished(graph);
\r
500 // graph.state.dec(0);
\r
501 return; // Complete predicate does not match.
\r
503 procedure.execute(graph, context, new ResourceImpl(graph.getResourceSupport(), modifier.execute(completeRef)));
\r
505 procedure.finished(graph);
\r
506 // graph.state.dec(0);
\r
507 return; // loop finished
\r
509 short p1 = getStm1Predicate(table, index);
\r
511 procedure.finished(graph);
\r
512 // graph.state.dec(0);
\r
513 return; // loop finished, no statements
\r
516 short o1 = getStm1Object(table, index);
\r
517 procedure.execute(graph, context, new ResourceImpl(graph.getResourceSupport(), modifier.execute(o1)));
\r
518 // int externalRef;
\r
519 // if (null == modifier)
\r
520 // externalRef = o1;
\r
522 // externalRef = modifier.execute(callerThread, o1);
\r
523 // if (procedure.execute(callerThread, context, externalRef))
\r
524 // return true; // loop broken by procedure
\r
526 short p2 = getStm2Predicate(table, index);
\r
527 if (0 == p2 || pRef != p2) {
\r
528 procedure.finished(graph);
\r
529 // graph.state.dec(0);
\r
530 return; // loop finished, one statements
\r
532 int o2 = getStm2Object(table, index);
\r
533 // int externalRef;
\r
534 // if (null == modifier)
\r
535 // externalRef = o2;
\r
537 // externalRef = modifier.execute(callerThread, o2);
\r
538 // if (procedure.execute(callerThread, context, externalRef))
\r
539 // return true; // loop broken by procedure
\r
540 // return false; // loop finished
\r
541 procedure.execute(graph, context, new ResourceImpl(graph.getResourceSupport(), modifier.execute(o2)));
\r
542 procedure.finished(graph);
\r
543 // graph.state.dec(0);
\r
546 public static <Context> boolean foreachObject(long[] table, int index
\r
547 , ClusterI.ObjectProcedure<Context> procedure
\r
548 , Context context, ClusterSupport support, Modifier modifier
\r
549 , final short pRef, ClusterI.CompleteTypeEnum pCompleteType, CompleteTable ct)
\r
550 throws DatabaseException {
\r
552 System.out.println("ResourceElementSmall.foreachObject2: 1");
\r
553 if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType) {
\r
554 int completeRef = getCompleteObjectRef(table, index);
\r
555 if (0 == completeRef) {
\r
557 System.out.println("ResourceElementSmall.foreachObject2: no complete");
\r
558 return false; // no objects for given complete type
\r
559 } if (ResourceElementSmall.completeHasMultiple(table, index)) {
\r
561 System.out.println("ResourceElementSmall.foreachObject2: multi-complete ci=" + completeRef);
\r
562 // CompleteRef is complete object set index.
\r
563 return ct.foreachObject(completeRef, procedure, context, support, modifier, pCompleteType);
\r
565 // One complete type statement at most.
\r
566 ClusterI.CompleteTypeEnum completeType = ResourceElementSmall.getCompleteType(table, index);
\r
567 if (pCompleteType != completeType) {
\r
569 System.out.println("ResourceElementSmall.foreachObject2: complete different predicate");
\r
570 return false; // Loop finished. No objects for given complete predicate type.
\r
572 int externalRef = completeRef;
\r
573 if (null != modifier)
\r
574 externalRef = modifier.execute(externalRef);
\r
576 System.out.println("ResourceElementSmall.foreachObject2: complete ok=" + externalRef);
\r
577 return procedure.execute(context, externalRef);
\r
579 int p1 = getStm1Predicate(table, index);
\r
582 System.out.println("ResourceElementSmall.foreachObject2: empty cache=");
\r
583 return false; // loop finished, no statements
\r
586 int o1 = getStm1Object(table, index);
\r
588 if (null == modifier)
\r
591 externalRef = modifier.execute(o1);
\r
593 System.out.println("ResourceElementSmall.foreachObject2: cache1 ok=" + externalRef);
\r
594 if (procedure.execute(context, externalRef))
\r
595 return true; // loop broken by procedure
\r
597 int p2 = getStm2Predicate(table, index);
\r
598 if (0 == p2 || pRef != p2) {
\r
600 System.out.println("ResourceElementSmall.foreachObject2: not in cache1");
\r
601 return false; // loop finished, one statements
\r
603 int o2 = getStm2Object(table, index);
\r
605 if (null == modifier)
\r
608 externalRef = modifier.execute(o2);
\r
610 System.out.println("ResourceElementSmall.foreachObject2: cache2 ok=" + externalRef);
\r
611 return procedure.execute(context, externalRef);
\r
613 static boolean isEmpty(long[] table, int index) {
\r
614 return getStatementCountApproximation(table, index) == 0 && !hasValue(table, index);
\r
616 static int getStatementCountApproximation(long[] table, int index) {
\r
617 int n = ResourceElementSmall.completeGetStatementCountApproximation(table, index);
\r
618 short p1 = getStm1Predicate(table, index);
\r
621 short p2 = getStm2Predicate(table, index);
\r
624 int predicateIndex = getPredicateIndex(table, index);
\r
625 if (0 == predicateIndex)
\r
627 return n + 3; // Can be bigger, hence the approximation.
\r
629 static int addStatement(long[] table, int index, short pRef, short oRef
\r
630 , PredicateTable pt, ObjectTable ot
\r
631 , ClusterI.CompleteTypeEnum completeType, CompleteTable ct)
\r
632 throws DatabaseException {
\r
633 assert (0 != pRef);
\r
634 assert (0 != oRef);
\r
635 if (ClusterI.CompleteTypeEnum.NotComplete != completeType) { // predicate is complete type
\r
636 int coRefAndType = completeMakeObjectRefAndType(oRef, completeType);
\r
637 if (completeIsFirstStatement(table, index))
\r
638 completeSetRefAndType(table, index, coRefAndType);
\r
639 else { // old complete statements exist
\r
640 if (completeIsSameStatement(table, index, coRefAndType))
\r
641 return -1; // old complete
\r
643 if (completeHasMultiple(table, index)) { // nth statement
\r
644 int coSetIndex = completeGetObjectSetIndex(table, index) & 0xFFFF;
\r
645 nRef = ct.addComplete(coSetIndex, coRefAndType);
\r
647 return -1; // old complete
\r
648 else if (nRef >= 1<<16) {
\r
649 ct.removeComplete(coSetIndex, coRefAndType);
\r
650 throw new OutOfSpaceException("Out of space for complete objects. index=" + nRef);
\r
652 } else { // second statement
\r
653 int coRefAndTypeOld = ResourceElementSmall.completeGetRefAndType(table, index);
\r
654 nRef = ct.createCompleteArraySet(coRefAndTypeOld, coRefAndType);
\r
656 throw new OutOfSpaceException("Out of space for complete objects. index=" + nRef);
\r
657 ResourceElementSmall.setCompleteType(table, index, (byte)0);
\r
659 setCompleteObjectRef(table, index, nRef);
\r
661 return 0; // added to complete
\r
663 short p1 = getStm1Predicate(table, index);
\r
664 short o1 = getStm1Object(table, index);
\r
666 setStm1Predicate(table, index, pRef);
\r
667 setStm1Object(table, index, oRef);
\r
668 return 0; // added to stm cache
\r
669 } else if (p1 == pRef && o1 == oRef)
\r
670 return -1; // same statement
\r
671 short p2 = getStm2Predicate(table, index);
\r
672 short o2 = getStm2Object(table, index);
\r
674 setStm2Predicate(table, index, pRef);
\r
675 setStm2Object(table, index, oRef);
\r
676 return 0; // added to stm cache
\r
677 } else if (p2 == pRef && o2 == oRef)
\r
678 return -1; // same statement
\r
679 int predicateIndex = getPredicateIndex(table, index);
\r
680 if (0 == predicateIndex) {
\r
682 int objectIndex = ot.createObjectSet(o1 & 0xFFFF, o2 & 0xFFFF);
\r
683 assert (0 != objectIndex);
\r
684 int[] os = new int[1];
\r
685 os[0] = ClusterTraits.statementIndexMake(objectIndex);
\r
686 int[] ps = new int[1];
\r
687 ps[0] = p1 & 0xFFFF;
\r
688 predicateIndex = pt.createPredicateSet(ps, os);
\r
690 int[] os = new int[2];
\r
691 os[0] = o1 & 0xFFFF;
\r
692 os[1] = o2 & 0xFFFF;
\r
693 int[] ps = new int[2];
\r
694 ps[0] = p1 & 0xFFFF;
\r
695 ps[1] = p2 & 0xFFFF;
\r
696 predicateIndex = pt.createPredicateSet(ps, os);
\r
698 assert (0 != predicateIndex);
\r
699 setPredicateIndex(table, index, predicateIndex);
\r
701 assert (0 != predicateIndex);
\r
702 return predicateIndex;
\r
705 static boolean removeStatement(long[] table, int index, short pRef, short oRef,
\r
706 ClusterI.CompleteTypeEnum completeType, CompleteTable ct)
\r
707 throws DatabaseException {
\r
708 assert (0 != pRef);
\r
709 assert (0 != oRef);
\r
710 if (completeType != ClusterI.CompleteTypeEnum.NotComplete) {
\r
711 int completeRef = ResourceElementSmall.getCompleteObjectRef(table, index);
\r
712 if (0 == completeRef)
\r
713 return false; // Statement not removed because it doesn't exist.
\r
714 int refAndType = ResourceElementSmall.completeMakeObjectRefAndType(oRef, completeType);
\r
715 if (ResourceElementSmall.completeIsSameStatement(table, index, refAndType)) {
\r
716 ResourceElementSmall.completeSetRefAndType(table, index, 0);
\r
717 return true; // statement removed
\r
718 } else if (ResourceElementSmall.completeHasMultiple(table, index)) {
\r
719 // CompleteRef is index to complete table.
\r
720 int oldSize = ct.getCompleteSetSize(completeRef);
\r
721 int newSize = ct.removeComplete(completeRef, refAndType);
\r
722 if (oldSize == newSize)
\r
723 return false; // not removed
\r
724 else if (newSize == 1) {
\r
725 int cRef = ct.removeLast(completeRef);
\r
726 ResourceElementSmall.completeSetRefAndType(table, index, cRef);
\r
730 return false; // Statement not removed because it doesn't exist.
\r
732 short p1 = getStm1Predicate(table, index);
\r
733 short o1 = getStm1Object(table, index);
\r
735 return false; // no statements cached
\r
736 short p2 = getStm2Predicate(table, index);
\r
737 short o2 = getStm2Object(table, index);
\r
738 if (p1 == pRef && o1 == oRef) {
\r
739 setStm1Predicate(table, index, p2);
\r
740 setStm1Object(table, index, o2);
\r
741 setStm2Predicate(table, index, (short)0);
\r
742 setStm2Object(table, index, (short)0);
\r
743 return true; // statement removed
\r
746 return false; // no match
\r
747 else if (p2 == pRef && o2 == oRef) {
\r
748 setStm2Predicate(table, index, (short)0);
\r
749 setStm2Object(table, index, (short)0);
\r
750 return true; // statement removed
\r