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
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.db.procore.cluster;
\r
14 import java.util.ArrayList;
\r
16 import org.simantics.db.Resource;
\r
17 import org.simantics.db.common.utils.Logger;
\r
18 import org.simantics.db.exception.DatabaseException;
\r
19 import org.simantics.db.exception.ExternalValueException;
\r
20 import org.simantics.db.exception.ValidationException;
\r
21 import org.simantics.db.impl.ClusterBase;
\r
22 import org.simantics.db.impl.ClusterI;
\r
23 import org.simantics.db.impl.ClusterI.CompleteTypeEnum;
\r
24 import org.simantics.db.impl.ClusterI.ObjectProcedure;
\r
25 import org.simantics.db.impl.ClusterI.PredicateProcedure;
\r
26 import org.simantics.db.impl.ClusterI.Procedure;
\r
27 import org.simantics.db.impl.ClusterSupport;
\r
28 import org.simantics.db.impl.ClusterTraitsBase;
\r
29 import org.simantics.db.impl.Modifier;
\r
30 import org.simantics.db.impl.ResourceImpl;
\r
31 import org.simantics.db.impl.Table;
\r
32 import org.simantics.db.impl.TableFactory;
\r
33 import org.simantics.db.impl.TableSizeListener;
\r
34 import org.simantics.db.impl.graph.ReadGraphImpl;
\r
35 import org.simantics.db.procedure.AsyncContextMultiProcedure;
\r
36 import org.simantics.db.procedure.AsyncMultiProcedure;
\r
37 import org.simantics.db.procore.cluster.PredicateTable.Status;
\r
40 final class ResourceElement {
\r
41 private static final boolean DEBUG = ClusterImpl.DEBUG;
\r
42 private static final int DESCRIPTOR_OFFSET = 0; // predicate descriptor
\r
43 private static final int VALUE_OFFSET = 1; // value descriptor
\r
44 private static final int STM_OFFSET = 2; // first statement
\r
45 private static final int SIZE_OF = 4;
\r
47 static void construct(long[] table, int index) {
\r
48 int i = DESCRIPTOR_OFFSET + index;
\r
49 table[i++] = 0; // predicate capacity & index
\r
50 table[i++] = 0; // value capacity & index
\r
51 table[i++] = 0; // stm1
\r
52 table[i++] = 0; // stm2
\r
55 static void destruct(long[] table, int index) {
\r
56 int i = DESCRIPTOR_OFFSET + index;
\r
57 table[i++] = 0; // predicate capacity & index
\r
58 table[i++] = 0; // value capacity & index
\r
59 table[i++] = 0; // stm1
\r
60 table[i++] = 0; // stm2
\r
63 static boolean isUsed(long[] table, int index) {
\r
64 int i = DESCRIPTOR_OFFSET + index;
\r
65 if (table[i++] != 0)
\r
67 if (table[i++] != 0)
\r
69 if (table[i++] != 0)
\r
71 if (table[i++] != 0)
\r
76 static int getSizeOf() {
\r
80 static int getCompleteObjectRef(long[] table, int index) {
\r
81 int i = DESCRIPTOR_OFFSET + index;
\r
82 return BitUtility.getHighInt(table[i]);
\r
85 static void setCompleteObjectRef(long[] table, int index, int ref) {
\r
86 int i = DESCRIPTOR_OFFSET + index;
\r
87 table[i] = BitUtility.setHighInt(table[i], ref);
\r
90 static int getPredicateIndex(long[] table, int index) {
\r
91 int i = DESCRIPTOR_OFFSET + index;
\r
92 int predicateIndex = BitUtility.getLowInt(table[i]);
\r
93 assert (predicateIndex >= 0);
\r
94 return predicateIndex;
\r
97 static void setPredicateIndex(long[] table, int index, int predicateIndex) {
\r
98 assert (predicateIndex >= 0);
\r
99 int i = DESCRIPTOR_OFFSET + index;
\r
100 table[i] = BitUtility.setLowInt(table[i], predicateIndex);
\r
103 static int copyValue(ValueTable valueTable, long[] table, int index, byte[] byteTable, int byteSize, int byteBase,
\r
105 int i = VALUE_OFFSET + index;
\r
106 if (0 == table[i] || -1 == table[i])
\r
107 return byteCurrent; // no value or external value
\r
108 // getValueCapacity call optimized away
\r
109 int capacity = BitUtility.getLowInt(table[i]);
\r
110 int valueIndex = getValueIndex(table, index);
\r
111 if (0 == valueIndex)
\r
112 return byteCurrent;
\r
113 valueTable.getValue(valueIndex, byteTable, byteCurrent, capacity);
\r
114 valueIndex = byteCurrent - byteBase;
\r
115 setValueIndex(table, index, valueIndex);
\r
116 byteCurrent += capacity;
\r
117 return byteCurrent;
\r
120 static byte[] getValue(ValueTable valueTable, long[] table, int index)
\r
121 throws DatabaseException {
\r
122 int i = VALUE_OFFSET + index;
\r
124 return null; // no value
\r
125 if (-1 == table[i])
\r
126 throw new ExternalValueException("Value stored externally.");
\r
127 // getValueCapacity call optimized away
\r
128 int capacity = BitUtility.getLowInt(table[i]);
\r
129 byte[] t = new byte[capacity];
\r
130 int valueIndex = getValueIndex(table, index);
\r
131 valueTable.getValue(valueIndex, t, 0, capacity);
\r
135 // static int getString(ValueTable valueTable, long[] table, int index, char[] t)
\r
136 // throws DatabaseException {
\r
137 // long l = table[index + VALUE_OFFSET];
\r
139 // throw new ExternalValueException("String stored externally.");
\r
140 // int capacity = (int)l;
\r
141 // int valueIndex = (int) (l >>> 32);
\r
142 //// char[] t = new char[capacity-1];
\r
143 // valueTable.getString(valueIndex, t, 0, capacity-1);
\r
144 // return capacity-1;
\r
148 static boolean hasValue(long[] table, int index) {
\r
149 int i = VALUE_OFFSET + index;
\r
150 return 0 != table[i];
\r
153 // static boolean hasValue(ValueTable valueTable, long[] table, int index, byte[] value) {
\r
154 // int i = VALUE_OFFSET + index;
\r
155 // if (0 == table[i])
\r
157 // // getValueCapacity call optimized away
\r
158 // int capacity = BitUtility.getLowInt(table[i]);
\r
159 // if (capacity != value.length)
\r
161 // int valueIndex = getValueIndex(table, index);
\r
162 // return valueTable.isEqual(valueIndex, value);
\r
165 static boolean removeValue(ValueTable valueTable, long[] table, int index) {
\r
166 int i = VALUE_OFFSET + index;
\r
169 else if (-1 != table[i]) {
\r
170 // getValueCapacity call optimized away
\r
171 int capacity = BitUtility.getLowInt(table[i]);
\r
172 int valueIndex = getValueIndex(table, index);
\r
173 valueTable.removeValue(valueIndex, capacity);
\r
175 //setValueCapacityAndIndex(table, index, 0, 0); optimized away
\r
180 public static void setValue(ValueTable valueTable, long[] table, int index, byte[] value, int length) {
\r
181 int i = VALUE_OFFSET + index;
\r
182 // getValueCapacity call optimized away
\r
183 int capacity = BitUtility.getLowInt(table[i]);
\r
184 int valueIndex = getValueIndex(table, index);
\r
185 if (length <= capacity) {
\r
186 valueTable.setValue(valueIndex, value, length);
\r
187 // we "leak" memory TODO: add value size member to
\r
188 // resource entry or value entry
\r
189 setValueCapacity(table, index, length);
\r
191 if (valueIndex != 0 && capacity > 0)
\r
192 valueTable.removeValue(valueIndex, capacity);
\r
193 valueIndex = valueTable.createValue(value, 0, length);
\r
195 setValueCapacityAndIndex(table, index, capacity, valueIndex);
\r
199 public static boolean isValueEx(ValueTable valueTable, long[] table, int index) {
\r
200 int i = VALUE_OFFSET + index;
\r
201 if (-1 == table[i])
\r
206 public static void setValueEx(ValueTable valueTable, long[] table, int index) {
\r
207 int i = VALUE_OFFSET + index;
\r
208 if (-1 == table[i])
\r
210 else if (0 != table[i]) {
\r
211 int capacity = BitUtility.getLowInt(table[i]);
\r
212 int valueIndex = getValueIndex(table, index);
\r
213 valueTable.removeValue(valueIndex, capacity);
\r
215 //setValueCapacityAndIndex(table, index, 0, 0); optimized away
\r
218 static class ValueData {
\r
221 // ValueData(int capacity, int index) {
\r
222 // this.capacity = capacity;
\r
223 // this.index = index;
\r
226 static void getValueCapacityAndIndex(ValueData vd, long[] table, int index) {
\r
227 int i = VALUE_OFFSET + index;
\r
228 // getValueCapacity call optimized away
\r
229 vd.capacity = BitUtility.getLowInt(table[i]);
\r
230 vd.index = getValueIndex(table, index);
\r
233 private static int getValueIndex(long[] table, int index) {
\r
234 int i = VALUE_OFFSET + index;
\r
235 return BitUtility.getHighInt(table[i]);
\r
238 private static void setValueIndex(long[] table, int index, int valueIndex) {
\r
239 int i = VALUE_OFFSET + index;
\r
240 table[i] = BitUtility.setHighInt(table[i], valueIndex);
\r
243 private static void setValueCapacity(long[] table, int index, int capacity) {
\r
244 int i = VALUE_OFFSET + index;
\r
245 table[i] = BitUtility.setLowInt(table[i], capacity);
\r
248 private static void setValueCapacityAndIndex(long[] table, int index, int capacity, int valueIndex) {
\r
249 int i = VALUE_OFFSET + index;
\r
250 table[i] = BitUtility.setLowAndHighInt(table[i], capacity, valueIndex);
\r
253 public static <Context> boolean foreachPredicate(long[] table, int index,
\r
254 ClusterI.PredicateProcedure<Context> procedure,
\r
255 Context context, ClusterSupport support, Modifier modifier,
\r
257 throws DatabaseException {
\r
259 System.out.println("ResourceElement.foreachPredicate: 1");
\r
260 int completeRef = ResourceElement.getCompleteObjectRef(table, index);
\r
261 if (0 != completeRef) {
\r
262 if (ClusterTraits.completeReferenceIsMultiple(completeRef)) { // multiple complete type elements
\r
263 boolean broken = ct.foreachPredicate(completeRef, procedure, context, support, modifier);
\r
265 System.out.println("ResourceElement.foreachPredicate: multi-complete ci=" + completeRef + " break=" + broken);
\r
267 return true; // loop broken by procedure
\r
269 ClusterI.CompleteTypeEnum completeType = ClusterTraits.completeReferenceGetType(completeRef);
\r
270 if (ClusterI.CompleteTypeEnum.NotComplete != completeType) {
\r
271 int key = ClusterTraitsBase.getCompleteTypeResourceKeyFromEnum(completeType);
\r
272 boolean broken = procedure.execute(context, key, 0);
\r
274 System.out.println("ResourceElement.foreachPredicate: complete rk=" + key + " break=" + broken);
\r
276 return true; // loop broken by procedure
\r
280 // If predicate set is in use it will contain also these statements.
\r
281 if (0 != ResourceElement.getPredicateIndex(table, index)) {
\r
283 System.out.println("ResourceElement.foreachPredicate: more than 2 objects");
\r
286 int i = STM_OFFSET + index;
\r
287 int p1 = BitUtility.getHighInt(table[i]);
\r
290 System.out.println("ResourceElement.foreachPredicate: empty cache");
\r
291 return false; // loop finished, no statements
\r
294 if (null == modifier)
\r
297 externalRef = modifier.execute(p1);
\r
299 System.out.println("ResourceElement.foreachPredicate: cache1 pk=" + externalRef);
\r
300 if (procedure.execute(context, externalRef, 0))
\r
301 return true; // loop broken by procedure
\r
302 int p2 = BitUtility.getHighInt(table[++i]);
\r
303 if (0 == p2 || p1 == p2) {
\r
305 System.out.println("ResourceElement.foreachPredicate: cache2 empty");
\r
306 return false; // loop finished, one statement
\r
307 } if (null == modifier)
\r
310 externalRef = modifier.execute(p2);
\r
312 System.out.println("ResourceElement.foreachPredicate: cache2 pk=" + externalRef);
\r
313 if (procedure.execute(context, externalRef, 0))
\r
314 return true; // loop broken by procedure
\r
316 System.out.println("ResourceElement.foreachPredicate: not in cache");
\r
317 return false; // loop finished, two statements
\r
320 public static int getSingleObject(long[] table, int index, ClusterSupport support, final int pRef, final ClusterI.CompleteTypeEnum pCompleteType, CompleteTable ct, final Modifier modifier)
\r
321 throws DatabaseException {
\r
323 System.out.println("ResourceElement.getSingleObject: index=" + index);
\r
324 if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType) {
\r
325 int completeRef = getCompleteObjectRef(table, index);
\r
326 if (0 == completeRef)
\r
327 return 0; // no objects for given complete type
\r
328 if (ClusterTraits.completeReferenceIsMultiple(completeRef)) {
\r
329 // Multiple complete type elements.
\r
331 System.out.println("ResourceElement.getSingleObject was complete 2");
\r
332 class ForeachObject
\r
333 implements ClusterI.ObjectProcedure<Integer> {
\r
335 public boolean execute(Integer context, int completeRef)
\r
336 throws DatabaseException {
\r
337 ClusterI.CompleteTypeEnum oCompleteType = ClusterTraits.completeReferenceGetType(completeRef);
\r
338 if (pCompleteType == oCompleteType) { // we have a match
\r
339 if (context != 0) { // we have an old match
\r
340 context = 0; // multiple objects for given type
\r
341 return true; // break loop
\r
343 int clusterIndex = ClusterTraits.completeReferenceGetForeignIndex(completeRef);
\r
344 int resourceIndex = ClusterTraits.completeReferenceGetResourceIndex(completeRef);
\r
345 if (0 == clusterIndex) {
\r
346 context = modifier.execute(resourceIndex);
\r
348 int externalRef = ClusterTraits.createForeignReference(clusterIndex, resourceIndex);
\r
349 context = modifier.execute(externalRef);
\r
352 return true; // continue looping
\r
356 ForeachObject t = new ForeachObject();
\r
357 // CompleteRef is complete object set index.
\r
359 ct.foreachComplete(completeRef, t, c, support, modifier);
\r
362 // one complete type element
\r
363 ClusterI.CompleteTypeEnum completeType = ClusterTraits.completeReferenceGetType(completeRef);
\r
364 if (pCompleteType != completeType)
\r
366 int clusterIndex = ClusterTraits.completeReferenceGetForeignIndex(completeRef);
\r
367 int resourceIndex = ClusterTraits.completeReferenceGetResourceIndex(completeRef);
\r
368 if (0 == clusterIndex) {
\r
369 return modifier.execute(resourceIndex);
\r
371 int externalRef = ClusterTraits.createForeignReference(clusterIndex, resourceIndex);
\r
372 return modifier.execute(externalRef);
\r
375 int i = STM_OFFSET + index;
\r
376 int p1 = BitUtility.getHighInt(table[i]);
\r
378 return 0; // loop finished, no statements
\r
381 int o1 = BitUtility.getLowInt(table[i]);
\r
382 result = modifier.execute(o1);
\r
383 // procedure.execute(graph, new ResourceImpl(null, modifier.execute(o1)));
\r
384 // int externalRef;
\r
385 // if (null == modifier)
\r
386 // externalRef = o1;
\r
388 // externalRef = modifier.execute(callerThread, o1);
\r
389 // if (procedure.execute(callerThread, context, externalRef))
\r
390 // return true; // loop broken by procedure
\r
392 int p2 = BitUtility.getHighInt(table[++i]);
\r
393 if (0 == p2 || pRef != p2)
\r
394 return result; // loop finished, one statements
\r
397 if (result != 0) return -1;
\r
399 int o2 = BitUtility.getLowInt(table[i]);
\r
400 return modifier.execute(o2);
\r
403 // int o2 = BitUtility.getLowInt(table[i]);
\r
404 // int externalRef;
\r
405 // if (null == modifier)
\r
406 // externalRef = o2;
\r
408 // externalRef = modifier.execute(callerThread, o2);
\r
409 // if (procedure.execute(callerThread, context, externalRef))
\r
410 // return true; // loop broken by procedure
\r
411 // return false; // loop finished
\r
412 // procedure.execute(graph, new ResourceImpl(null, modifier.execute(o2)));
\r
415 public static void foreachObject(long[] table, int index,
\r
416 final ReadGraphImpl graph, final AsyncMultiProcedure<Resource> procedure,
\r
417 final ClusterSupport support, final int pRef, final ClusterI.CompleteTypeEnum pCompleteType, CompleteTable ct, final Modifier modifier)
\r
418 throws DatabaseException {
\r
420 System.out.println("ResourceElement.foreachObject1: index=" + index);
\r
421 if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType) {
\r
422 int completeRef = getCompleteObjectRef(table, index);
\r
423 if (0 == completeRef) {
\r
424 procedure.finished(graph);
\r
425 // graph.state.dec(0);
\r
426 return; // no objects for given complete type
\r
428 if (ClusterTraits.completeReferenceIsMultiple(completeRef)) {
\r
429 // Multiple complete type statements.
\r
431 System.out.println("ResourceElement.was complete 2");
\r
432 class ForeachObject implements ClusterI.ObjectProcedure<Object> {
\r
434 public boolean execute(Object context, int completeRef) throws DatabaseException {
\r
435 ClusterI.CompleteTypeEnum oCompleteType = ClusterTraits.completeReferenceGetType(completeRef);
\r
436 if (pCompleteType == oCompleteType) {
\r
437 int clusterIndex = ClusterTraits.completeReferenceGetForeignIndex(completeRef);
\r
438 int resourceIndex = ClusterTraits.completeReferenceGetResourceIndex(completeRef);
\r
439 if (0 == clusterIndex) {
\r
440 procedure.execute(graph, new ResourceImpl(graph.getResourceSupport(), modifier.execute(resourceIndex)));
\r
442 int externalRef = ClusterTraits.createForeignReference(clusterIndex, resourceIndex);
\r
443 procedure.execute(graph, new ResourceImpl(graph.getResourceSupport(), modifier.execute(externalRef)));
\r
446 return false; // continue looping
\r
450 ForeachObject t = new ForeachObject();
\r
451 // CompleteRef is complete object set index.
\r
452 ct.foreachComplete(completeRef, t, null, support, modifier);
\r
453 procedure.finished(graph);
\r
454 // graph.state.dec(0);
\r
455 return; // loop finished
\r
457 // one complete type element
\r
458 ClusterI.CompleteTypeEnum completeType = ClusterTraits.completeReferenceGetType(completeRef);
\r
459 if (pCompleteType != completeType) {
\r
460 procedure.finished(graph);
\r
461 // graph.state.dec(0);
\r
464 int clusterIndex = ClusterTraits.completeReferenceGetForeignIndex(completeRef);
\r
465 int resourceIndex = ClusterTraits.completeReferenceGetResourceIndex(completeRef);
\r
466 if (0 == clusterIndex) {
\r
467 procedure.execute(graph, new ResourceImpl(graph.getResourceSupport(), modifier.execute(resourceIndex)));
\r
469 int externalRef = ClusterTraits.createForeignReference(clusterIndex, resourceIndex);
\r
470 procedure.execute(graph, new ResourceImpl(graph.getResourceSupport(), modifier.execute(externalRef)));
\r
472 procedure.finished(graph);
\r
473 // graph.state.dec(0);
\r
474 return; // loop finished
\r
476 int i = STM_OFFSET + index;
\r
478 int p1 = (int) (l >>> 32);
\r
480 procedure.finished(graph);
\r
481 // graph.state.dec(0);
\r
482 return; // loop finished, no statements
\r
486 procedure.execute(graph, new ResourceImpl(graph.getResourceSupport(), modifier.execute(o1)));
\r
487 // int externalRef;
\r
488 // if (null == modifier)
\r
489 // externalRef = o1;
\r
491 // externalRef = modifier.execute(callerThread, o1);
\r
492 // if (procedure.execute(callerThread, context, externalRef))
\r
493 // return true; // loop broken by procedure
\r
495 long l2 = table[++i];
\r
496 int p2 = (int) (l2 >>> 32);
\r
498 procedure.finished(graph);
\r
499 // graph.state.dec(0);
\r
500 return; // loop finished, one statements
\r
503 procedure.execute(graph, new ResourceImpl(graph.getResourceSupport(), modifier.execute(o2)));
\r
504 procedure.finished(graph);
\r
505 // graph.state.dec(0);
\r
508 public static <C> void foreachObject(long[] table, int index,
\r
509 final ReadGraphImpl graph, final C context, final AsyncContextMultiProcedure<C, Resource> procedure,
\r
510 final ClusterSupport support, final int pRef, final ClusterI.CompleteTypeEnum pCompleteType, CompleteTable ct, final Modifier modifier)
\r
511 throws DatabaseException {
\r
513 System.out.println("ResourceElement.foreachObject1: index=" + index);
\r
514 if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType) {
\r
515 int completeRef = getCompleteObjectRef(table, index);
\r
516 if (0 == completeRef) {
\r
517 procedure.finished(graph);
\r
518 // graph.state.dec(0);
\r
519 return; // no objects for given complete type
\r
521 if (ClusterTraits.completeReferenceIsMultiple(completeRef)) {
\r
522 // Multiple complete type statements.
\r
524 System.out.println("ResourceElement.was complete 2");
\r
525 class ForeachObject implements ClusterI.ObjectProcedure<Object> {
\r
527 public boolean execute(Object _context, int completeRef) throws DatabaseException {
\r
528 ClusterI.CompleteTypeEnum oCompleteType = ClusterTraits.completeReferenceGetType(completeRef);
\r
529 if (pCompleteType == oCompleteType) {
\r
530 int clusterIndex = ClusterTraits.completeReferenceGetForeignIndex(completeRef);
\r
531 int resourceIndex = ClusterTraits.completeReferenceGetResourceIndex(completeRef);
\r
532 if (0 == clusterIndex) {
\r
533 procedure.execute(graph, context, new ResourceImpl(graph.getResourceSupport(), modifier.execute(resourceIndex)));
\r
535 int externalRef = ClusterTraits.createForeignReference(clusterIndex, resourceIndex);
\r
536 procedure.execute(graph, context, new ResourceImpl(graph.getResourceSupport(), modifier.execute(externalRef)));
\r
539 return false; // continue looping
\r
543 ForeachObject t = new ForeachObject();
\r
544 // CompleteRef is complete object set index.
\r
545 ct.foreachComplete(completeRef, t, null, support, modifier);
\r
546 procedure.finished(graph);
\r
547 // graph.state.dec(0);
\r
548 return; // loop finished
\r
550 // one complete type element
\r
551 ClusterI.CompleteTypeEnum completeType = ClusterTraits.completeReferenceGetType(completeRef);
\r
552 if (pCompleteType != completeType) {
\r
553 procedure.finished(graph);
\r
554 // graph.state.dec(0);
\r
557 int clusterIndex = ClusterTraits.completeReferenceGetForeignIndex(completeRef);
\r
558 int resourceIndex = ClusterTraits.completeReferenceGetResourceIndex(completeRef);
\r
559 if (0 == clusterIndex) {
\r
560 procedure.execute(graph, context, new ResourceImpl(graph.getResourceSupport(), modifier.execute(resourceIndex)));
\r
562 int externalRef = ClusterTraits.createForeignReference(clusterIndex, resourceIndex);
\r
563 procedure.execute(graph, context, new ResourceImpl(graph.getResourceSupport(), modifier.execute(externalRef)));
\r
565 procedure.finished(graph);
\r
566 // graph.state.dec(0);
\r
567 return; // loop finished
\r
569 int i = STM_OFFSET + index;
\r
571 int p1 = (int) (l >>> 32);
\r
573 procedure.finished(graph);
\r
574 // graph.state.dec(0);
\r
575 return; // loop finished, no statements
\r
579 procedure.execute(graph, context, new ResourceImpl(graph.getResourceSupport(), modifier.execute(o1)));
\r
580 // int externalRef;
\r
581 // if (null == modifier)
\r
582 // externalRef = o1;
\r
584 // externalRef = modifier.execute(callerThread, o1);
\r
585 // if (procedure.execute(callerThread, context, externalRef))
\r
586 // return true; // loop broken by procedure
\r
588 long l2 = table[++i];
\r
589 int p2 = (int) (l2 >>> 32);
\r
591 procedure.finished(graph);
\r
592 // graph.state.dec(0);
\r
593 return; // loop finished, one statements
\r
596 procedure.execute(graph, context, new ResourceImpl(graph.getResourceSupport(), modifier.execute(o2)));
\r
597 procedure.finished(graph);
\r
598 // graph.state.dec(0);
\r
601 public static <Context> boolean foreachObject(long[] table, int index
\r
602 , ClusterI.ObjectProcedure<Context> procedure
\r
603 , Context context, ClusterSupport support, Modifier modifier
\r
604 , final int pRef, ClusterI.CompleteTypeEnum pCompleteType, CompleteTable ct)
\r
605 throws DatabaseException {
\r
607 System.out.println("ResourceElement.foreachObject2: 1 ");
\r
608 if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType) {
\r
609 int completeRef = getCompleteObjectRef(table, index);
\r
610 if (0 == completeRef) {
\r
612 System.out.println("ResourceElement.foreachObject2: no complete");
\r
613 return false; // no objects for given complete type
\r
615 if (ClusterTraits.completeReferenceIsMultiple(completeRef)) { // multiple complete type elements
\r
617 System.out.println("ResourceElement.foreachObject2: multi-complete ci=" + completeRef);
\r
618 return ct.foreachObject(completeRef, procedure, context, support, modifier, pCompleteType);
\r
620 // one complete type element
\r
621 ClusterI.CompleteTypeEnum completeType = ClusterTraits.completeReferenceGetType(completeRef);
\r
622 if (pCompleteType != completeType) {
\r
624 System.out.println("ResourceElement.foreachObject2: complete different predicate");
\r
627 int clusterIndex = ClusterTraits.completeReferenceGetForeignIndex(completeRef);
\r
628 int resourceIndex = ClusterTraits.completeReferenceGetResourceIndex(completeRef);
\r
629 if (0 == clusterIndex) {
\r
631 if (null == modifier)
\r
632 externalRef = resourceIndex;
\r
634 externalRef = modifier.execute(resourceIndex);
\r
636 System.out.println("ResourceElement.foreachObject2: complete ok=" + externalRef);
\r
637 if (procedure.execute(context, externalRef))
\r
638 return true; // loop broken by procedure
\r
640 int externalRef = ClusterTraits.createForeignReference(clusterIndex, resourceIndex);
\r
641 if (null != modifier)
\r
642 externalRef = modifier.execute(externalRef);
\r
644 System.out.println("ResourceElement.foreachObject2: complete ok=" + externalRef);
\r
645 if (procedure.execute(context, externalRef))
\r
646 return true; // loop broken by procedure
\r
648 return false; // loop finished
\r
650 int i = STM_OFFSET + index;
\r
651 int p1 = BitUtility.getHighInt(table[i]);
\r
654 System.out.println("ResourceElement.foreachObject2: empty cache=");
\r
655 return false; // loop finished, no statements
\r
658 int o1 = BitUtility.getLowInt(table[i]);
\r
660 if (null == modifier)
\r
663 externalRef = modifier.execute(o1);
\r
665 System.out.println("ResourceElement.foreachObject2: cache1 ok=" + externalRef);
\r
666 if (procedure.execute(context, externalRef))
\r
667 return true; // loop broken by procedure
\r
669 int p2 = BitUtility.getHighInt(table[++i]);
\r
670 if (0 == p2 || pRef != p2) {
\r
672 System.out.println("ResourceElement.foreachObject2: not in cache1");
\r
673 return false; // loop finished, one statements
\r
675 int o2 = BitUtility.getLowInt(table[i]);
\r
677 if (null == modifier)
\r
680 externalRef = modifier.execute(o2);
\r
682 System.out.println("ResourceElement.foreachObject2: cache2 ok=" + externalRef);
\r
683 return procedure.execute(context, externalRef);
\r
685 static boolean isEmpty(long[] table, int index) {
\r
686 return getStatementCount(table, index) == 0 && !hasValue(table, index);
\r
688 static int getStatementCount(long[] table, int index) {
\r
689 int i = STM_OFFSET + index;
\r
690 int p1 = BitUtility.getHighInt(table[i]);
\r
691 int p2 = BitUtility.getLowInt(table[++i]);
\r
696 int predicateIndex = getPredicateIndex(table, index);
\r
697 if (0 == predicateIndex)
\r
701 private static int makeCompleteObjectRef(int oRef, ClusterI.CompleteTypeEnum completeType) {
\r
704 int resourceIndex = oRef;
\r
705 int clusterIndex = 0;
\r
706 ref = ClusterTraits.completeReferenceMake(completeType.getValue(), resourceIndex, clusterIndex);
\r
709 assert(!ClusterTraits.isFlat(oRef));
\r
710 ref = (completeType.getValue() <<30) | (oRef & 0x3FFFFFFF);
\r
714 static int addStatement(long[] table, int index, int pRef, int oRef
\r
715 , PredicateTable pt, ObjectTable ot
\r
716 , ClusterI.CompleteTypeEnum completeType, CompleteTable ct)
\r
717 throws DatabaseException {
\r
718 assert (0 != pRef);
\r
719 assert (0 != oRef);
\r
720 if (ClusterI.CompleteTypeEnum.NotComplete != completeType) {
\r
721 int cRef = makeCompleteObjectRef(oRef, completeType);
\r
722 int ctr = getCompleteObjectRef(table, index);
\r
724 setCompleteObjectRef(table, index, cRef);
\r
728 return -1; // old complete
\r
729 else if (ClusterTraits.completeReferenceIsMultiple(ctr)) {
\r
730 nRef = ct.addComplete(ctr, cRef);
\r
732 return -1; // old complete
\r
734 nRef = ct.createCompleteArraySet(ctr, cRef);
\r
736 setCompleteObjectRef(table, index, nRef);
\r
738 return 0; // added to complete
\r
740 int i = STM_OFFSET + index;
\r
741 int p1 = BitUtility.getHighInt(table[i]);
\r
742 int o1 = BitUtility.getLowInt(table[i]);
\r
744 table[i] = BitUtility.setLowAndHighInt(table[i], oRef, pRef);
\r
745 return 0; // added to stm cache
\r
746 } else if (p1 == pRef && o1 == oRef)
\r
747 return -1; // same statement
\r
748 int p2 = BitUtility.getHighInt(table[++i]);
\r
749 int o2 = BitUtility.getLowInt(table[i]);
\r
751 table[i] = BitUtility.setLowAndHighInt(table[i], oRef, pRef);
\r
752 return 0; // added to stm cache
\r
753 } else if (p2 == pRef && o2 == oRef)
\r
754 return -1; // same statement
\r
755 int predicateIndex = getPredicateIndex(table, index);
\r
756 if (0 == predicateIndex) {
\r
758 int objectIndex = ot.createObjectSet(o1, o2);
\r
759 assert (0 != objectIndex);
\r
760 int[] os = new int[1];
\r
761 os[0] = ClusterTraits.statementIndexMake(objectIndex);
\r
762 int[] ps = new int[1];
\r
764 predicateIndex = pt.createPredicateSet(ps, os);
\r
766 int[] os = new int[2];
\r
769 int[] ps = new int[2];
\r
772 predicateIndex = pt.createPredicateSet(ps, os);
\r
774 assert (0 != predicateIndex);
\r
775 setPredicateIndex(table, index, predicateIndex);
\r
777 assert (0 != predicateIndex);
\r
778 return predicateIndex;
\r
781 static boolean removeStatement(long[] table, int index, int pRef, int oRef,
\r
782 ClusterI.CompleteTypeEnum completeType, CompleteTable ct)
\r
783 throws DatabaseException {
\r
784 assert (0 != pRef);
\r
785 assert (0 != oRef);
\r
786 if (completeType != ClusterI.CompleteTypeEnum.NotComplete) {
\r
787 int completeRef = ResourceElement.getCompleteObjectRef(table, index);
\r
788 if (0 != completeRef) {
\r
789 ClusterI.CompleteTypeEnum completeType2 = ClusterTraits.completeReferenceGetType(completeRef);
\r
790 if (completeType == completeType2) {
\r
791 int clusterIndex = ClusterTraits.completeReferenceGetForeignIndex(completeRef);
\r
792 int resourceIndex = ClusterTraits.completeReferenceGetResourceIndex(completeRef);
\r
793 if (0 == clusterIndex) {
\r
794 if (oRef == resourceIndex) {
\r
795 ResourceElement.setCompleteObjectRef(table, index, 0);
\r
796 return true; // statement removed
\r
799 int externalRef = ClusterTraits.createForeignReference(clusterIndex, resourceIndex);
\r
800 if (oRef == externalRef) {
\r
801 ResourceElement.setCompleteObjectRef(table, index, 0);
\r
802 return true; // statement removed
\r
805 } else if (completeType2 == ClusterI.CompleteTypeEnum.NotComplete) { // multiple complete type references
\r
806 int cRef = makeCompleteObjectRef(oRef, completeType);
\r
807 int oldSize = ct.getCompleteSetSize(completeRef);
\r
808 int newSize = ct.removeComplete(completeRef, cRef);
\r
809 if (oldSize == newSize)
\r
810 return false; // not removed
\r
811 else if (newSize == 1) {
\r
812 cRef = ct.removeLast(completeRef);
\r
813 ResourceElement.setCompleteObjectRef(table, index, cRef);
\r
819 int i = STM_OFFSET + index;
\r
820 int p1 = BitUtility.getHighInt(table[i]);
\r
821 int o1 = BitUtility.getLowInt(table[i]);
\r
823 return false; // no statements cached
\r
824 else if (p1 == pRef && o1 == oRef) {
\r
825 table[i] = table[i + 1];
\r
826 // BitUtility.setLowAndHighInt(table[i], 0, 0); optimized away
\r
828 return true; // statement removed
\r
830 int p2 = BitUtility.getHighInt(table[++i]);
\r
831 int o2 = BitUtility.getLowInt(table[i]);
\r
833 return false; // no match
\r
834 else if (p2 == pRef && o2 == oRef) {
\r
835 // BitUtility.setLowAndHighInt(table[i], 0, 0); optimized away
\r
837 return true; // statement removed
\r
843 public final class ResourceTable extends Table<long[]> {
\r
844 public ResourceTable(TableSizeListener sizeListener, int[] header, int headerBase) {
\r
845 super(TableFactory.getLongFactory(), sizeListener, header, headerBase);
\r
848 public ResourceTable(TableSizeListener sizeListener, int[] header, int headerBase, long[] longs) {
\r
849 super(TableFactory.getLongFactory(), sizeListener, header, headerBase, longs);
\r
852 public int getUsedSize() {
\r
853 return getTableCount();
\r
856 public short createResource() {
\r
857 final int INDEX = getTableCount();
\r
858 final int SIZE = ResourceElement.getSizeOf();
\r
859 int resourceIndex = createNewElement(SIZE);
\r
860 assert (0 != resourceIndex);
\r
861 final int REAL_INDEX = checkIndexAndGetRealIndex(resourceIndex, SIZE);
\r
862 ResourceElement.construct(getTable(), REAL_INDEX);
\r
863 incResourceCount();
\r
864 return (short)(INDEX + ZERO_SHIFT);
\r
867 void createResource(int resourceIndex) {
\r
868 final int tableCount = getTableCount();
\r
869 if (resourceIndex <= tableCount) { // old index
\r
870 int realIndex = checkIndexAndGetRealIndex(resourceIndex);
\r
871 if (ResourceElement.isEmpty(getTable(), realIndex))
\r
873 } if (resourceIndex == tableCount+1) {
\r
877 throw new InternalError("Trying to create resource with illegal index=" + resourceIndex);
\r
880 // void deleteResource(int resourceIndex) {
\r
881 // int realIndex = checkIndexAndGetRealIndex(resourceIndex);
\r
882 // ResourceElement.destruct(getTable(), realIndex);
\r
883 // decResourceCount();
\r
886 public int getCompleteObjectRef(int resourceIndex) {
\r
887 int realIndex = checkIndexAndGetRealIndex(resourceIndex);
\r
888 return ResourceElement.getCompleteObjectRef(getTable(), realIndex);
\r
891 public int getPredicateIndex(int resourceIndex) {
\r
892 int i = (resourceIndex<<2) - 3 + offset;
\r
893 return (int)table[i];
\r
896 public void setPredicateIndex(int resourceIndex, int predicateIndex) {
\r
897 int realIndex = checkIndexAndGetRealIndex(resourceIndex);
\r
898 ResourceElement.setPredicateIndex(getTable(), realIndex, predicateIndex);
\r
901 public byte[] getValue(ValueTable valueTable, int resourceIndex)
\r
902 throws DatabaseException {
\r
903 int realIndex = checkIndexAndGetRealIndex(resourceIndex);
\r
904 return ResourceElement.getValue(valueTable, getTable(), realIndex);
\r
908 // int getString(ValueTable valueTable, int resourceIndex, char[] chars)
\r
909 // throws DatabaseException {
\r
910 // //int realIndex = checkIndexAndGetRealIndex(resourceIndex);
\r
911 // return ResourceElement.getString(valueTable, getTable(), 4 * resourceIndex - 3 + offset, chars);
\r
914 public boolean hasValue(int resourceIndex) {
\r
915 int realIndex = checkIndexAndGetRealIndex(resourceIndex);
\r
916 return ResourceElement.hasValue(getTable(), realIndex);
\r
919 // boolean hasValue(ValueTable valueTable, int resourceIndex, byte[] value) {
\r
920 // int realIndex = checkIndexAndGetRealIndex(resourceIndex);
\r
921 // return ResourceElement.hasValue(valueTable, getTable(), realIndex, value);
\r
924 public boolean removeValue(ValueTable valueTable, int resourceIndex) {
\r
925 int realIndex = checkIndexAndGetRealIndex(resourceIndex);
\r
926 boolean ret = ResourceElement.removeValue(valueTable, getTable(), realIndex);
\r
927 // if (ret && !ResourceElement.isUsed(getTable(), realIndex))
\r
928 // decResourceCount();
\r
932 public void setValue(ValueTable valueTable, int resourceIndex, byte[] value, int length) {
\r
933 int realIndex = checkIndexAndGetRealIndex(resourceIndex);
\r
934 ResourceElement.setValue(valueTable, getTable(), realIndex, value, length);
\r
937 public boolean isValueEx(ValueTable valueTable, int resourceIndex) {
\r
938 int realIndex = checkIndexAndGetRealIndex(resourceIndex);
\r
939 return ResourceElement.isValueEx(valueTable, getTable(), realIndex);
\r
942 public void setValueEx(ValueTable valueTable, int resourceIndex) {
\r
943 int realIndex = checkIndexAndGetRealIndex(resourceIndex);
\r
944 ResourceElement.setValueEx(valueTable, getTable(), realIndex);
\r
947 static final int RESOURCE_COUNT_INDEX = 0;
\r
948 static final int FOREIGN_COUNT_INDEX = 1; // Reserved by server.
\r
949 static final int CLUSTER_STATUS_INDEX = 2;
\r
951 int incResourceCount() {
\r
952 int count = getExtra(RESOURCE_COUNT_INDEX) + 1;
\r
953 setExtra(RESOURCE_COUNT_INDEX, count);
\r
957 // int decResourceCount() {
\r
958 // int count = getExtra(RESOURCE_COUNT_INDEX) - 1;
\r
959 // setExtra(RESOURCE_COUNT_INDEX, count);
\r
963 public int getResourceCount() {
\r
964 return getExtra(RESOURCE_COUNT_INDEX);
\r
966 public int getClusterStatus() {
\r
967 return getExtra(CLUSTER_STATUS_INDEX);
\r
969 public void setClusterStatus(int value) {
\r
970 setExtra(CLUSTER_STATUS_INDEX, value);
\r
974 final int tsize = getTableSize();
\r
975 final int esize = ResourceElement.getSizeOf();
\r
976 long[] table = getTable();
\r
977 for (int i = getTableBase(); i < getTableBase() + tsize; i += esize) {
\r
978 if (ResourceElement.isUsed(getTable(), i)) {
\r
979 System.out.println(" -" + Long.toHexString(table[i]) + " " + Long.toHexString(table[i+1]) + " " + Long.toHexString(table[i+2]) + " " + Long.toHexString(table[i+3]));
\r
985 public <Context> boolean foreachResource(ClusterI.ObjectProcedure<Context> procedure, Context context,
\r
986 ClusterSupport support, Modifier modifier) throws DatabaseException {
\r
987 final int tsize = getTableSize();
\r
988 // final int rsize = getResourceCount();
\r
989 final int esize = ResourceElement.getSizeOf();
\r
991 int key = ZERO_SHIFT;
\r
992 for (int i = getTableBase(); i < getTableBase() + tsize; i += esize, ++key) {
\r
993 if (ResourceElement.isUsed(getTable(), i)) {
\r
995 if (null == modifier)
\r
998 ref = modifier.execute(key);
\r
999 if (procedure.execute(context, ref))
\r
1000 return true; // loop was broken by procedure
\r
1001 // if (rsize == ++count)
\r
1002 // return false; // loop finished
\r
1005 //assert(rsize == count);
\r
1006 return false; // loop finished
\r
1009 public <Context> boolean foreachPredicate(int resourceIndex
\r
1010 , ClusterI.PredicateProcedure<Context> procedure, Context context
\r
1011 , ClusterSupport support, Modifier modifier, CompleteTable ct)
\r
1012 throws DatabaseException {
\r
1013 int realIndex = checkIndexAndGetRealIndex(resourceIndex);
\r
1014 return ResourceElement.foreachPredicate(getTable(), realIndex
\r
1015 , procedure, context, support, modifier, ct);
\r
1018 public int getSingleObject(int resourceIndex, ClusterSupport support, int pRef, ClusterI.CompleteTypeEnum pCompleteType, CompleteTable ct, Modifier modifier) throws DatabaseException {
\r
1019 // return ResourceElement.getSingleObject(table, realIndex, support, pRef, pCompleteType, ct, modifier);
\r
1020 return ResourceElement.getSingleObject(table, 4 * resourceIndex - 3 + offset, support, pRef, pCompleteType, ct, modifier);
\r
1023 public void foreachObject(int resourceIndex, ReadGraphImpl graph,
\r
1024 AsyncMultiProcedure<Resource> procedure, ClusterSupport support, int pRef, ClusterI.CompleteTypeEnum pCompleteType, CompleteTable ct, Modifier modifier) throws DatabaseException {
\r
1025 int realIndex = checkIndexAndGetRealIndex(resourceIndex);
\r
1026 ResourceElement.foreachObject(table, realIndex, graph, procedure, support,
\r
1027 pRef, pCompleteType, ct, modifier);
\r
1030 public <C> void foreachObject(int resourceIndex, ReadGraphImpl graph, C context,
\r
1031 AsyncContextMultiProcedure<C, Resource> procedure, ClusterSupport support, int pRef, ClusterI.CompleteTypeEnum pCompleteType, CompleteTable ct, Modifier modifier) throws DatabaseException {
\r
1032 int realIndex = checkIndexAndGetRealIndex(resourceIndex);
\r
1033 ResourceElement.foreachObject(table, realIndex, graph, context, procedure, support,
\r
1034 pRef, pCompleteType, ct, modifier);
\r
1037 public <Context> boolean foreachObject(int resourceIndex
\r
1038 , ClusterI.ObjectProcedure<Context> procedure, Context context
\r
1039 , ClusterSupport support, Modifier modifier,
\r
1040 int pRef, ClusterI.CompleteTypeEnum completeType, CompleteTable ct)
\r
1041 throws DatabaseException {
\r
1042 int realIndex = checkIndexAndGetRealIndex(resourceIndex);
\r
1043 return ResourceElement.foreachObject(table, realIndex
\r
1044 , procedure, context, support, modifier
\r
1045 , pRef, completeType, ct);
\r
1047 public int addStatement(int resourceIndex, int pRef, int oRef, PredicateTable pt, ObjectTable ot
\r
1048 , ClusterI.CompleteTypeEnum pCompleteType, CompleteTable ct)
\r
1049 throws DatabaseException {
\r
1050 int realIndex = checkIndexAndGetRealIndex(resourceIndex);
\r
1051 return ResourceElement.addStatement(getTable(), realIndex, pRef, oRef, pt, ot, pCompleteType, ct);
\r
1054 public boolean removeStatementFromCache(int resourceIndex, int pRef, int oRef,
\r
1055 ClusterI.CompleteTypeEnum pCompleteType, CompleteTable ct)
\r
1056 throws DatabaseException {
\r
1057 int realIndex = checkIndexAndGetRealIndex(resourceIndex);
\r
1058 boolean ret = ResourceElement.removeStatement(getTable(), realIndex, pRef, oRef, pCompleteType, ct);
\r
1059 // if (ret && !ResourceElement.isUsed(getTable(), realIndex))
\r
1060 // decResourceCount();
\r
1064 public void removeStatement(int resourceIndex, int pRef, int oRef, ClusterI.CompleteTypeEnum pCompleteType, CompleteTable ct,
\r
1065 PredicateTable pt, ObjectTable ot, ClusterBase cluster, ClusterSupport support)
\r
1066 throws DatabaseException {
\r
1067 int realIndex = checkIndexAndGetRealIndex(resourceIndex);
\r
1068 boolean removed = ResourceElement.removeStatement(getTable(), realIndex,
\r
1069 pRef, oRef, pCompleteType, ct);
\r
1072 int predicateIndex = ResourceElement.getPredicateIndex(getTable(), realIndex);
\r
1073 if (0 == predicateIndex) {
\r
1074 // if (!ResourceElement.isUsed(getTable(), realIndex))
\r
1075 // decResourceCount();
\r
1078 GetStatements gs = new GetStatements(ot);
\r
1079 pt.foreachPredicate(predicateIndex, gs, null, null, null);
\r
1080 ArrayList<Statement> stms = gs.getStatements();
\r
1082 final int SIZE = stms.size();
\r
1084 for (int i = 0; i < SIZE; ++i) {
\r
1085 Statement stm = stms.get(i);
\r
1086 PredicateTable.Status ret = pt.removePredicate(predicateIndex,
\r
1087 stm.pRef, stm.oIndex, ot);
\r
1088 if (ret == Status.NothingRemoved)
\r
1089 throw new DatabaseException("Internal error during statement cache fix (2).");
\r
1090 int predicateKey = cluster.makeResourceKey(stm.pRef);
\r
1091 int completeTypeInt = ClusterTraitsBase.getCompleteTypeIntFromResourceKey(predicateKey);
\r
1092 ClusterI.CompleteTypeEnum completeType = CompleteTypeEnum.make(completeTypeInt);
\r
1093 int pi = ResourceElement.addStatement(getTable(), realIndex, stm.pRef, stm.oIndex,
\r
1094 pt, ot, completeType, ct);
\r
1097 assert(0 == pt.getPredicateSetSize(predicateIndex));
\r
1098 ResourceElement.setPredicateIndex(getTable(), realIndex, 0);
\r
1100 for (int i = 0; i < SIZE; ++i) {
\r
1101 Statement stm = stms.get(i);
\r
1102 int predicateKey = cluster.makeResourceKey(stm.pRef);
\r
1103 int completeTypeInt = ClusterTraitsBase.getCompleteTypeIntFromResourceKey(predicateKey);
\r
1104 ClusterI.CompleteTypeEnum completeType = CompleteTypeEnum.make(completeTypeInt);
\r
1105 int pIndex = ResourceElement.addStatement(getTable(), realIndex,
\r
1106 stm.pRef, stm.oIndex, pt, ot, completeType, ct);
\r
1108 return; // cache fixed and full, p and o sets in use
\r
1110 throw new DatabaseException("Internal error during statement cache fix (3).");
\r
1112 // if (!ResourceElement.isUsed(getTable(), realIndex))
\r
1113 // decResourceCount();
\r
1117 private int checkIndexAndGetRealIndex(final int INDEX) {
\r
1118 assert(INDEX > 0);
\r
1119 assert(INDEX <= getTableCount());
\r
1120 // final int TABLE_INDEX = (INDEX - ZERO_SHIFT) * ResourceElement.getSizeOf() + ZERO_SHIFT;
\r
1121 // final int TABLE_INDEX = (INDEX - ZERO_SHIFT) * ResourceElement.getSizeOf() + ZERO_SHIFT;
\r
1122 // return checkIndexAndGetRealIndex(TABLE_INDEX, ResourceElement.getSizeOf());
\r
1123 return 4 * INDEX - 3 + offset;
\r
1125 public void check(ClusterBase cluster)
\r
1126 throws DatabaseException {
\r
1128 cluster.checkValueInit();
\r
1129 long[] table = getTable();
\r
1130 int ps = getHeader().getOffset() + ZERO_SHIFT;
\r
1131 final int TABLE_SIZE = getTableSize();
\r
1132 int pe = ps + TABLE_SIZE;
\r
1133 for (int p=ps; p<pe; p+=ResourceElement.getSizeOf()) {
\r
1134 if (!ResourceElement.isUsed(table, p))
\r
1136 int cr = ResourceElement.getCompleteObjectRef(table, p);
\r
1138 if (ClusterTraits.completeReferenceIsMultiple(cr))
\r
1139 cluster.checkCompleteSetReference(cr);
\r
1141 int fi = ClusterTraits.completeReferenceGetForeignIndex(cr);
\r
1142 int ri = ClusterTraits.completeReferenceGetResourceIndex(cr);
\r
1144 cluster.checkForeingIndex(fi);
\r
1145 else if (ri < 1 || ri > TABLE_SIZE)
\r
1146 throw new ValidationException("Illegal resource index=" + ri);
\r
1149 int pi = ResourceElement.getPredicateIndex(table, p);
\r
1151 cluster.checkPredicateIndex(pi);
\r
1153 ResourceElement.ValueData vd = new ResourceElement.ValueData();
\r
1154 ResourceElement.getValueCapacityAndIndex(vd, table, p);
\r
1155 cluster.checkValue(vd.capacity, vd.index);
\r
1157 cluster.checkValueFini();
\r
1161 public <Context> boolean foreach(int setIndex, Procedure procedure, Context context,
\r
1162 ClusterSupport support, Modifier modifier) throws DatabaseException {
\r
1163 throw new UnsupportedOperationException();
\r
1168 Statement(int pRef, int oIndex) {
\r
1170 this.oIndex = oIndex;
\r
1176 class CalculateStatements
\r
1177 implements ClusterI.PredicateProcedure<CalculateStatements> {
\r
1178 private ObjectTable ot;
\r
1179 private final int sRef;
\r
1181 CalculateStatements(int sRef, ObjectTable ot) {
\r
1187 public boolean execute(final CalculateStatements context
\r
1188 , final int pKey, int oIndex) {
\r
1189 if (ClusterTraits.statementIndexIsDirect(oIndex))
\r
1190 return false; // osize = 1
\r
1192 oIndex = ClusterTraits.statementIndexGet(oIndex);
\r
1193 } catch (DatabaseException e) {
\r
1194 Logger.getDefault().logError("Missing object set for s="
\r
1195 + sRef + " p=" + pKey, null);
\r
1196 return false; // continue looping
\r
1198 int osize = ot.getObjectSetSize(oIndex);
\r
1199 if (osize == 3 || osize > 9)
\r
1200 System.out.println("Resource " + sRef + " predicate " + pKey + " has "
\r
1201 + osize + " objects.");
\r
1202 return true; // break loop
\r
1206 class GetStatements implements PredicateProcedure<Object>, ObjectProcedure<Integer> {
\r
1207 private ObjectTable ot;
\r
1208 private final ArrayList<Statement> stms = new ArrayList<Statement>();
\r
1209 GetStatements(ObjectTable ot) {
\r
1212 ArrayList<Statement> getStatements() {
\r
1216 public boolean execute(Object context, int pRef, int oIndex) {
\r
1218 ot.foreachObject(oIndex, this, pRef, null, null);
\r
1219 } catch (DatabaseException e) {
\r
1220 e.printStackTrace();
\r
1221 return false; // continue looping
\r
1223 if (stms.size() > 2)
\r
1224 return true; // break loop
\r
1225 return false; // continue looping
\r
1229 public boolean execute(Integer pRef, int oRef) {
\r
1230 stms.add(new Statement(pRef, oRef));
\r
1231 if (stms.size() > 2)
\r
1232 return true; // break loop
\r
1233 return false; // continue looping
\r