X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.db.procore%2Fsrc%2Forg%2Fsimantics%2Fdb%2Fprocore%2Fcluster%2FResourceElementSmall.java;h=90519a36c3f6cb5916c7429c5af8e8ca41414deb;hp=71c4c53507f71baff5eae4fc04d66f79d1bdca1c;hb=e19c37f84fd1ce2d946578f7c05f3e45444ba67a;hpb=969bd23cab98a79ca9101af33334000879fb60c5 diff --git a/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ResourceElementSmall.java b/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ResourceElementSmall.java index 71c4c5350..90519a36c 100644 --- a/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ResourceElementSmall.java +++ b/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ResourceElementSmall.java @@ -1,754 +1,754 @@ -package org.simantics.db.procore.cluster; - -import org.simantics.db.Resource; -import org.simantics.db.exception.DatabaseException; -import org.simantics.db.exception.ExternalValueException; -import org.simantics.db.impl.ClusterI; -import org.simantics.db.impl.ClusterSupport; -import org.simantics.db.impl.ClusterTraitsBase; -import org.simantics.db.impl.Modifier; -import org.simantics.db.impl.ResourceImpl; -import org.simantics.db.impl.graph.ReadGraphImpl; -import org.simantics.db.procedure.AsyncContextMultiProcedure; -import org.simantics.db.procedure.AsyncMultiProcedure; - - -public final class ResourceElementSmall { - private static final boolean DEBUG = ClusterImpl.DEBUG; - // Descriptor = type & complete object reference & value index & predicate index. - private static final int DESCRIPTOR_OFFSET = 0; // descriptor - private static final int STM_OFFSET = 1; // two statements - private static final int SIZE_OF = 2; - - static void construct(long[] table, int index) { - int i = DESCRIPTOR_OFFSET + index; - table[i++] = 0; // descriptor - table[i++] = 0; // stm1 & 2 - } - - static void destruct(long[] table, int index) { - int i = DESCRIPTOR_OFFSET + index; - table[i++] = 0; // descriptor - table[i++] = 0; // stm1 & 2 - } - - static boolean isUsed(long[] table, int index) { - int i = DESCRIPTOR_OFFSET + index; - if (table[i++] != 0) - return true; - if (table[i++] != 0) - return true; - return false; - } - - static int getSizeOf() { - return SIZE_OF; - } - - static ClusterI.CompleteTypeEnum getCompleteType(long[] table, int index) { - int i = DESCRIPTOR_OFFSET + index; - byte bits = (byte)BitUtility.getMiddle(table[i], 62, 2); - return ClusterI.CompleteTypeEnum.make(bits); - } - - static void setCompleteType(long[] table, int index, byte data) { - int i = DESCRIPTOR_OFFSET + index; - table[i] = BitUtility.setMiddle(table[i], 62, 2, data); - } - - static short getCompleteObjectRef(long[] table, int index) { - int i = DESCRIPTOR_OFFSET + index; - return (short)BitUtility.getMiddle(table[i], 46, 16); - } - - static void setCompleteObjectRef(long[] table, int index, int ref) { - if (ref > (1<<16)-1) - throw new IllegalArgumentException(); - int i = DESCRIPTOR_OFFSET + index; - table[i] = BitUtility.setMiddle(table[i], 46, 16, ref); - } - - static boolean completeHasMultiple(long[] table, int index) { - int i = DESCRIPTOR_OFFSET + index; - int completeRefAndType= BitUtility.getMiddle(table[i], 46, 18); - boolean complete = (completeRefAndType >>> 16) != 0; - return !complete && (completeRefAndType != 0); - } - - static boolean completeIsFirstStatement(long[] table, int index) { - int i = DESCRIPTOR_OFFSET + index; - int completeRefAndType = BitUtility.getMiddle(table[i], 46, 18); - return completeRefAndType == 0; - } - - static boolean completeIsSameStatement(long[] table, int index, int refAndType) { - int i = DESCRIPTOR_OFFSET + index; - int completeRefAndType = BitUtility.getMiddle(table[i], 46, 18); - return completeRefAndType == refAndType; - } - - static int completeGetRefAndType(long[] table, int index) { - int i = DESCRIPTOR_OFFSET + index; - return BitUtility.getMiddle(table[i], 46, 18); - } - - static void completeSetRefAndType(long[] table, int index, int refAndType) { - int i = DESCRIPTOR_OFFSET + index; - table[i] = BitUtility.setMiddle(table[i], 46, 18, refAndType); - } - - static int completeMakeObjectRefAndType(short oRef, ClusterI.CompleteTypeEnum completeType) { - return oRef & (1<<16)-1 | completeType.getValue()<<16; - } - - static short completeGetObjectSetIndex(long[] table, int index) { - int i = DESCRIPTOR_OFFSET + index; - return (short)BitUtility.getMiddle(table[i], 46, 16); - } - - static int completeGetStatementCountApproximation(long[] table, int index) { - int i = DESCRIPTOR_OFFSET + index; - int cType = BitUtility.getMiddle(table[i], 62, 2); - if (cType != 0) - return 1; - int cRef = BitUtility.getMiddle(table[i], 46, 16); - if (cRef != 0) - return 2; // Can be bigger, hence the approximation. - return 0; - } - - static int getValueIndex(long[] table, int index) { - int i = DESCRIPTOR_OFFSET + index; - int valueIndex = BitUtility.getMiddle(table[i], 24, 22); - return valueIndex; - } - - static void setValueIndex(long[] table, int index, int valueIndex) { - int i = DESCRIPTOR_OFFSET + index; - table[i] = BitUtility.setMiddle(table[i], 24, 22, valueIndex); - } - - static int getPredicateIndex(long[] table, int index) { - int i = DESCRIPTOR_OFFSET + index; - int predicateIndex = BitUtility.getMiddle(table[i], 0, 24); - return predicateIndex; - } - - static void setPredicateIndex(long[] table, int index, int predicateIndex) { - int i = DESCRIPTOR_OFFSET + index; - table[i] = BitUtility.setMiddle(table[i], 0, 24, predicateIndex); - } - - static short getStm1Predicate(long[] table, int index) { - int i = STM_OFFSET + index; - short predicateIndex = BitUtility.getLowShort(table[i]); - return predicateIndex; - } - - static void setStm1Predicate(long[] table, int index, short predicateIndex) { - int i = STM_OFFSET + index; - table[i] = BitUtility.setLowShort(table[i], predicateIndex); - } - - static short getStm1Object(long[] table, int index) { - int i = STM_OFFSET + index; - short objectIndex = (short)BitUtility.getMiddle(table[i], 16, 16); - return objectIndex; - } - - static void setStm1Object(long[] table, int index, short objectIndex) { - int i = STM_OFFSET + index; - table[i] = BitUtility.setMiddle(table[i], 16, 16, objectIndex); - } - - static short getStm2Predicate(long[] table, int index) { - int i = STM_OFFSET + index; - short predicateIndex = (short)BitUtility.getMiddle(table[i], 32, 16); - return predicateIndex; - } - - static void setStm2Predicate(long[] table, int index, short predicateIndex) { - int i = STM_OFFSET + index; - table[i] = BitUtility.setMiddle(table[i], 32, 16, predicateIndex); - } - - static short getStm2Object(long[] table, int index) { - int i = STM_OFFSET + index; - short objectIndex = (short)BitUtility.getMiddle(table[i], 48, 16); - return objectIndex; - } - - static void setStm2Object(long[] table, int index, short objectIndex) { - int i = STM_OFFSET + index; - table[i] = BitUtility.setMiddle(table[i], 48, 16, objectIndex); - } - - public static byte[] getValue(ValueTableSmall valueTable, long[] table, int index) - throws DatabaseException { - int valueIndex = getValueIndex(table, index); - if (0 == valueIndex) - return null; // no value - else if (ClusterTraitsSmall.VALUE_INDEX_EX == valueIndex) - throw new ExternalValueException("Value stored externally. index=" + index); - return valueTable.getValue(valueIndex); - } -//KRAA: -// static char[] getString(ValueTableSmall valueTable, long[] table, int index) { -// int valueIndex = getValueIndex(table, index); -// if (0 == valueIndex) -// return null; // no value -//// else if (ClusterTraitsSmall.VALUE_INDEX_MAX == valueIndex) -//// throw new Error("Not implemented! //KRAA:"); -// return valueTable.getString(valueIndex); -// } - - static boolean hasValue(long[] table, int index) { - int valueIndex = getValueIndex(table, index); - return 0 != valueIndex; - } - -// static boolean hasValue(ValueTable valueTable, long[] table, int index, byte[] value) { -// int valueIndex = getValueIndex(table, index); -// if (0 == valueIndex) -// return false; -// return valueTable.isEqual(valueIndex, value, 0, value.length); -// } - - static boolean removeValue(ValueTableSmall valueTable, long[] table, int index) { - int valueIndex = getValueIndex(table, index); - if (0 == valueIndex) - return false; // not removed - else if (ClusterTraitsSmall.VALUE_INDEX_EX != valueIndex) - valueTable.removeValue(valueIndex); - setValueIndex(table, index, 0); - return true; - } - - public static void setValue(ValueTableSmall valueTable, long[] table, int index, byte[] value, int length) - throws OutOfSpaceException { - int oldIndex = getValueIndex(table, index); - if (ClusterTraitsSmall.VALUE_INDEX_EX == oldIndex) - oldIndex = 0; - if (length > ClusterTraitsSmall.VALUE_SIZE_MAX) - throw new OutOfSpaceException("Out of space for value. size=" + length); - int newIndex = valueTable.setValue(oldIndex, value, 0, length); - if (newIndex != oldIndex) { - if (newIndex > ClusterTraitsSmall.VALUE_INDEX_MAX) { - setValueIndex(table, index, 0); - throw new OutOfSpaceException("Out of space for values. index=" + newIndex); - } - setValueIndex(table, index, newIndex); - } - return; - } - - public static boolean isValueEx(ValueTableSmall valueTable, long[] table, int index) { - int vIndex = getValueIndex(table, index); - if (ClusterTraitsSmall.VALUE_INDEX_EX == vIndex) - return true; - else - return false; - } - - public static void setValueEx(ValueTableSmall valueTable, long[] table, int index) { - setValueIndex(table, index, ClusterTraitsSmall.VALUE_INDEX_EX); - } - - public static boolean foreachPredicate(long[] table, int index, - ClusterI.PredicateProcedure procedure, - Context context, ClusterSupport support, Modifier modifier, - CompleteTable ct) - throws DatabaseException { - if (DEBUG) - System.out.println("ResourceElement.foreachPredicate: 1"); - int completeRef = ResourceElementSmall.getCompleteObjectRef(table, index); - if (0 != completeRef) { - if (ResourceElementSmall.completeHasMultiple(table, index)) { // multiple complete objects - // CompleteRef is a complete object set index. - boolean broken = ct.foreachPredicate(completeRef, procedure, context, support, modifier); - if (DEBUG) - System.out.println("ResourceElement.foreachPredicate: multi-complete ci=" + completeRef + " break=" + broken); - if (broken) - return true; // loop broken by procedure - } else { // We have zero or one complete statement. - ClusterI.CompleteTypeEnum completeType = ResourceElementSmall.getCompleteType(table, index); - if (ClusterI.CompleteTypeEnum.NotComplete != completeType) { - int key = ClusterTraitsBase.getCompleteTypeResourceKeyFromEnum(completeType); - boolean broken = procedure.execute(context, key, 0); - if (DEBUG) - System.out.println("ResourceElement.foreachPredicate: complete rk=" + key + " break=" + broken); - if (broken) - return true; // loop broken by procedure - } - } - } - // If predicate set is in use it will contain also these statements. - if (0 != ResourceElementSmall.getPredicateIndex(table, index)) { - if (DEBUG) - System.out.println("ResourceElement.foreachPredicate: more than 2 objects"); - return false; - } - int p1 = getStm1Predicate(table, index); - if (0 == p1) { - if (DEBUG) - System.out.println("ResourceElement.foreachPredicate: empty cache"); - return false; // loop finished, no statements - } - int externalRef; - if (null == modifier) - externalRef = p1; - else - externalRef = modifier.execute(p1); - if (DEBUG) - System.out.println("ResourceElement.foreachPredicate: cache1 pk=" + externalRef); - if (procedure.execute(context, externalRef, 0)) - return true; // loop broken by procedure - int p2 = getStm2Predicate(table, index); - if (0 == p2 || p1 == p2) { - if (DEBUG) - System.out.println("ResourceElement.foreachPredicate: cache2 empty"); - return false; // loop finished, one predicate - } - if (null == modifier) - externalRef = p2; - else - externalRef = modifier.execute(p2); - if (DEBUG) - System.out.println("ResourceElement.foreachPredicate: cache2 pk=" + externalRef); - return procedure.execute(context, externalRef, 0); - } - - public static int getSingleObject(long[] table, int index, ClusterSupport support, final short pRef, - final ClusterI.CompleteTypeEnum pCompleteType, CompleteTable ct, Modifier modifier) - throws DatabaseException { - if (DEBUG) - System.out.println("ResourceElement.getSingleObject: index=" + index); - if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType) { - int completeRef = getCompleteObjectRef(table, index); - if (0 == completeRef) - return 0; // no objects for given complete type - if (ResourceElementSmall.completeHasMultiple(table, index)) { - // Multiple complete type statements. - if (DEBUG) - System.out.println("ResourceElement.was complete 2"); - ClusterI.ObjectProcedure proc = new ClusterI.ObjectProcedure() { - @Override - public boolean execute(Short context, int completeRefAndType) - throws DatabaseException { - ClusterI.CompleteTypeEnum ct = ClusterTraitsSmall.completeRefAndTypeGetType(completeRefAndType); - if (ct == pCompleteType) { // we have a match - if (context != 0) { // we have an old match - context = 0; // multiple objects for given type - return true; // break loop - } - context = ClusterTraitsSmall.completeRefAndTypeGetRef(completeRefAndType); - } - return true; // continue looping - } - }; - Short objectRef = 0; - // CompleteRef is complete object set index. - ct.foreachComplete(completeRef, proc, objectRef, support, modifier); - return modifier.execute(objectRef); - } // One complete type statement. - ClusterI.CompleteTypeEnum rCompleteType = ResourceElementSmall.getCompleteType(table, index); - if (pCompleteType != rCompleteType) - return 0; // no objects for given complete type - // CompleteRef is object resource reference. - return modifier.execute(completeRef); - } - int p1 = getStm1Predicate(table, index); - if (0 == p1) - return 0; // loop finished, no statements - int result = 0; - if (pRef == p1) { - short o1 = getStm1Object(table, index); - result = modifier.execute(o1); -// procedure.execute(graph, new ResourceImpl(null, modifier.execute(o1))); -// int externalRef; -// if (null == modifier) -// externalRef = o1; -// else -// externalRef = modifier.execute(callerThread, o1); -// if (procedure.execute(callerThread, context, externalRef)) -// return true; // loop broken by procedure - } - int p2 = getStm2Predicate(table, index); - if (0 == p2 || pRef != p2) - return result; // loop finished, one statements - - // Many statements - if (result != 0) return -1; - - short o2 = getStm2Object(table, index); - return modifier.execute(o2); -// int externalRef; -// if (null == modifier) -// externalRef = o2; -// else -// externalRef = modifier.execute(callerThread, o2); -// if (procedure.execute(callerThread, context, externalRef)) -// return true; // loop broken by procedure -// return false; // loop finished -// procedure.execute(graph, new ResourceImpl(null, modifier.execute(o2))); - } - - public static void foreachObject(long[] table, int index, - final ReadGraphImpl graph, final AsyncMultiProcedure procedure, - ClusterSupport support, final int pRef, ClusterI.CompleteTypeEnum pCompleteType, CompleteTable ct, final Modifier modifier) - throws DatabaseException { - if (DEBUG) - System.out.println("ResourceElement.foreachObject1: index=" + index); - if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType) { - int completeRef = getCompleteObjectRef(table, index); - if (0 == completeRef) { - procedure.finished(graph); -// graph.state.dec(0); - return; // no objects for given complete type - } - if (ResourceElementSmall.completeHasMultiple(table, index)) {// multiple objects - ClusterI.ObjectProcedure proc = new ClusterI.ObjectProcedure() { - @Override - public boolean execute(Object _context, int objectRef) - throws DatabaseException { - procedure.execute(graph, new ResourceImpl(graph.getResourceSupport(), modifier.execute(objectRef))); - return false; // continue looping - } - - }; - // CompleteRef is complete object set index. - ct.foreachComplete(completeRef, proc, null, support, modifier); - } else { // One complete type element. CompleteRef is resource reference. - ClusterI.CompleteTypeEnum rCompleteType = ResourceElementSmall.getCompleteType(table, index); - if (pCompleteType != rCompleteType) { - procedure.finished(graph); -// graph.state.dec(0); - return; // Complete predicate does not match. - } - procedure.execute(graph, new ResourceImpl(graph.getResourceSupport(), modifier.execute(completeRef))); - } - procedure.finished(graph); -// graph.state.dec(0); - return; // loop finished - } - short p1 = getStm1Predicate(table, index); - if (0 == p1) { - procedure.finished(graph); -// graph.state.dec(0); - return; // loop finished, no statements - } - if (pRef == p1) { - short o1 = getStm1Object(table, index); - procedure.execute(graph, new ResourceImpl(graph.getResourceSupport(), modifier.execute(o1))); -// int externalRef; -// if (null == modifier) -// externalRef = o1; -// else -// externalRef = modifier.execute(callerThread, o1); -// if (procedure.execute(callerThread, context, externalRef)) -// return true; // loop broken by procedure - } - short p2 = getStm2Predicate(table, index); - if (0 == p2 || pRef != p2) { - procedure.finished(graph); -// graph.state.dec(0); - return; // loop finished, one statements - } - int o2 = getStm2Object(table, index); -// int externalRef; -// if (null == modifier) -// externalRef = o2; -// else -// externalRef = modifier.execute(callerThread, o2); -// if (procedure.execute(callerThread, context, externalRef)) -// return true; // loop broken by procedure -// return false; // loop finished - procedure.execute(graph, new ResourceImpl(graph.getResourceSupport(), modifier.execute(o2))); - procedure.finished(graph); -// graph.state.dec(0); - } - - public static void foreachObject(long[] table, int index, - final ReadGraphImpl graph, final C context, final AsyncContextMultiProcedure procedure, - ClusterSupport support, final int pRef, ClusterI.CompleteTypeEnum pCompleteType, CompleteTable ct, final Modifier modifier) - throws DatabaseException { - if (DEBUG) - System.out.println("ResourceElement.foreachObject1: index=" + index); - if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType) { - int completeRef = getCompleteObjectRef(table, index); - if (0 == completeRef) { - procedure.finished(graph); -// graph.state.dec(0); - return; // no objects for given complete type - } - if (ResourceElementSmall.completeHasMultiple(table, index)) {// multiple objects - ClusterI.ObjectProcedure proc = new ClusterI.ObjectProcedure() { - @Override - public boolean execute(Object _context, int objectRef) - throws DatabaseException { - procedure.execute(graph, context, new ResourceImpl(graph.getResourceSupport(), modifier.execute(objectRef))); - return false; // continue looping - } - - }; - // CompleteRef is complete object set index. - ct.foreachComplete(completeRef, proc, null, support, modifier); - } else { // One complete type element. CompleteRef is resource reference. - ClusterI.CompleteTypeEnum rCompleteType = ResourceElementSmall.getCompleteType(table, index); - if (pCompleteType != rCompleteType) { - procedure.finished(graph); -// graph.state.dec(0); - return; // Complete predicate does not match. - } - procedure.execute(graph, context, new ResourceImpl(graph.getResourceSupport(), modifier.execute(completeRef))); - } - procedure.finished(graph); -// graph.state.dec(0); - return; // loop finished - } - short p1 = getStm1Predicate(table, index); - if (0 == p1) { - procedure.finished(graph); -// graph.state.dec(0); - return; // loop finished, no statements - } - if (pRef == p1) { - short o1 = getStm1Object(table, index); - procedure.execute(graph, context, new ResourceImpl(graph.getResourceSupport(), modifier.execute(o1))); -// int externalRef; -// if (null == modifier) -// externalRef = o1; -// else -// externalRef = modifier.execute(callerThread, o1); -// if (procedure.execute(callerThread, context, externalRef)) -// return true; // loop broken by procedure - } - short p2 = getStm2Predicate(table, index); - if (0 == p2 || pRef != p2) { - procedure.finished(graph); -// graph.state.dec(0); - return; // loop finished, one statements - } - int o2 = getStm2Object(table, index); -// int externalRef; -// if (null == modifier) -// externalRef = o2; -// else -// externalRef = modifier.execute(callerThread, o2); -// if (procedure.execute(callerThread, context, externalRef)) -// return true; // loop broken by procedure -// return false; // loop finished - procedure.execute(graph, context, new ResourceImpl(graph.getResourceSupport(), modifier.execute(o2))); - procedure.finished(graph); -// graph.state.dec(0); - } - - public static boolean foreachObject(long[] table, int index - , ClusterI.ObjectProcedure procedure - , Context context, ClusterSupport support, Modifier modifier - , final short pRef, ClusterI.CompleteTypeEnum pCompleteType, CompleteTable ct) - throws DatabaseException { - if (DEBUG) - System.out.println("ResourceElementSmall.foreachObject2: 1"); - if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType) { - int completeRef = getCompleteObjectRef(table, index); - if (0 == completeRef) { - if (DEBUG) - System.out.println("ResourceElementSmall.foreachObject2: no complete"); - return false; // no objects for given complete type - } if (ResourceElementSmall.completeHasMultiple(table, index)) { - if (DEBUG) - System.out.println("ResourceElementSmall.foreachObject2: multi-complete ci=" + completeRef); - // CompleteRef is complete object set index. - return ct.foreachObject(completeRef, procedure, context, support, modifier, pCompleteType); - } - // One complete type statement at most. - ClusterI.CompleteTypeEnum completeType = ResourceElementSmall.getCompleteType(table, index); - if (pCompleteType != completeType) { - if (DEBUG) - System.out.println("ResourceElementSmall.foreachObject2: complete different predicate"); - return false; // Loop finished. No objects for given complete predicate type. - } - int externalRef = completeRef; - if (null != modifier) - externalRef = modifier.execute(externalRef); - if (DEBUG) - System.out.println("ResourceElementSmall.foreachObject2: complete ok=" + externalRef); - return procedure.execute(context, externalRef); - } - int p1 = getStm1Predicate(table, index); - if (0 == p1) { - if (DEBUG) - System.out.println("ResourceElementSmall.foreachObject2: empty cache="); - return false; // loop finished, no statements - } - if (pRef == p1) { - int o1 = getStm1Object(table, index); - int externalRef; - if (null == modifier) - externalRef = o1; - else - externalRef = modifier.execute(o1); - if (DEBUG) - System.out.println("ResourceElementSmall.foreachObject2: cache1 ok=" + externalRef); - if (procedure.execute(context, externalRef)) - return true; // loop broken by procedure - } - int p2 = getStm2Predicate(table, index); - if (0 == p2 || pRef != p2) { - if (DEBUG) - System.out.println("ResourceElementSmall.foreachObject2: not in cache1"); - return false; // loop finished, one statements - } - int o2 = getStm2Object(table, index); - int externalRef; - if (null == modifier) - externalRef = o2; - else - externalRef = modifier.execute(o2); - if (DEBUG) - System.out.println("ResourceElementSmall.foreachObject2: cache2 ok=" + externalRef); - return procedure.execute(context, externalRef); - } - static boolean isEmpty(long[] table, int index) { - return getStatementCountApproximation(table, index) == 0 && !hasValue(table, index); - } - static int getStatementCountApproximation(long[] table, int index) { - int n = ResourceElementSmall.completeGetStatementCountApproximation(table, index); - short p1 = getStm1Predicate(table, index); - if (0 == p1) - return n; - short p2 = getStm2Predicate(table, index); - if (0 == p2) - return n+1; - int predicateIndex = getPredicateIndex(table, index); - if (0 == predicateIndex) - return n + 2; - return n + 3; // Can be bigger, hence the approximation. - } - static int addStatement(long[] table, int index, short pRef, short oRef - , PredicateTable pt, ObjectTable ot - , ClusterI.CompleteTypeEnum completeType, CompleteTable ct) - throws DatabaseException { - assert (0 != pRef); - assert (0 != oRef); - if (ClusterI.CompleteTypeEnum.NotComplete != completeType) { // predicate is complete type - int coRefAndType = completeMakeObjectRefAndType(oRef, completeType); - if (completeIsFirstStatement(table, index)) - completeSetRefAndType(table, index, coRefAndType); - else { // old complete statements exist - if (completeIsSameStatement(table, index, coRefAndType)) - return -1; // old complete - int nRef; - if (completeHasMultiple(table, index)) { // nth statement - int coSetIndex = completeGetObjectSetIndex(table, index) & 0xFFFF; - nRef = ct.addComplete(coSetIndex, coRefAndType); - if (0 == nRef) - return -1; // old complete - else if (nRef >= 1<<16) { - ct.removeComplete(coSetIndex, coRefAndType); - throw new OutOfSpaceException("Out of space for complete objects. index=" + nRef); - } - } else { // second statement - int coRefAndTypeOld = ResourceElementSmall.completeGetRefAndType(table, index); - nRef = ct.createCompleteArraySet(coRefAndTypeOld, coRefAndType); - if (nRef >= 1<<16) - throw new OutOfSpaceException("Out of space for complete objects. index=" + nRef); - ResourceElementSmall.setCompleteType(table, index, (byte)0); - } - setCompleteObjectRef(table, index, nRef); - } - return 0; // added to complete - } - short p1 = getStm1Predicate(table, index); - short o1 = getStm1Object(table, index); - if (0 == p1) { - setStm1Predicate(table, index, pRef); - setStm1Object(table, index, oRef); - return 0; // added to stm cache - } else if (p1 == pRef && o1 == oRef) - return -1; // same statement - short p2 = getStm2Predicate(table, index); - short o2 = getStm2Object(table, index); - if (0 == p2) { - setStm2Predicate(table, index, pRef); - setStm2Object(table, index, oRef); - return 0; // added to stm cache - } else if (p2 == pRef && o2 == oRef) - return -1; // same statement - int predicateIndex = getPredicateIndex(table, index); - if (0 == predicateIndex) { - if (p1 == p2) { - int objectIndex = ot.createObjectSet(o1 & 0xFFFF, o2 & 0xFFFF); - assert (0 != objectIndex); - int[] os = new int[1]; - os[0] = ClusterTraits.statementIndexMake(objectIndex); - int[] ps = new int[1]; - ps[0] = p1 & 0xFFFF; - predicateIndex = pt.createPredicateSet(ps, os); - } else { - int[] os = new int[2]; - os[0] = o1 & 0xFFFF; - os[1] = o2 & 0xFFFF; - int[] ps = new int[2]; - ps[0] = p1 & 0xFFFF; - ps[1] = p2 & 0xFFFF; - predicateIndex = pt.createPredicateSet(ps, os); - } - assert (0 != predicateIndex); - setPredicateIndex(table, index, predicateIndex); - } - assert (0 != predicateIndex); - return predicateIndex; - } - - static boolean removeStatement(long[] table, int index, short pRef, short oRef, - ClusterI.CompleteTypeEnum completeType, CompleteTable ct) - throws DatabaseException { - assert (0 != pRef); - assert (0 != oRef); - if (completeType != ClusterI.CompleteTypeEnum.NotComplete) { - int completeRef = ResourceElementSmall.getCompleteObjectRef(table, index); - if (0 == completeRef) - return false; // Statement not removed because it doesn't exist. - int refAndType = ResourceElementSmall.completeMakeObjectRefAndType(oRef, completeType); - if (ResourceElementSmall.completeIsSameStatement(table, index, refAndType)) { - ResourceElementSmall.completeSetRefAndType(table, index, 0); - return true; // statement removed - } else if (ResourceElementSmall.completeHasMultiple(table, index)) { - // CompleteRef is index to complete table. - int oldSize = ct.getCompleteSetSize(completeRef); - int newSize = ct.removeComplete(completeRef, refAndType); - if (oldSize == newSize) - return false; // not removed - else if (newSize == 1) { - int cRef = ct.removeLast(completeRef); - ResourceElementSmall.completeSetRefAndType(table, index, cRef); - } - return true; - } - return false; // Statement not removed because it doesn't exist. - } - short p1 = getStm1Predicate(table, index); - short o1 = getStm1Object(table, index); - if (0 == p1) - return false; // no statements cached - short p2 = getStm2Predicate(table, index); - short o2 = getStm2Object(table, index); - if (p1 == pRef && o1 == oRef) { - setStm1Predicate(table, index, p2); - setStm1Object(table, index, o2); - setStm2Predicate(table, index, (short)0); - setStm2Object(table, index, (short)0); - return true; // statement removed - } - if (0 == p2) - return false; // no match - else if (p2 == pRef && o2 == oRef) { - setStm2Predicate(table, index, (short)0); - setStm2Object(table, index, (short)0); - return true; // statement removed - } - return false; - } -} +package org.simantics.db.procore.cluster; + +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.exception.ExternalValueException; +import org.simantics.db.impl.ClusterI; +import org.simantics.db.impl.ClusterSupport; +import org.simantics.db.impl.ClusterTraitsBase; +import org.simantics.db.impl.Modifier; +import org.simantics.db.impl.ResourceImpl; +import org.simantics.db.impl.graph.ReadGraphImpl; +import org.simantics.db.procedure.AsyncContextMultiProcedure; +import org.simantics.db.procedure.AsyncMultiProcedure; + + +public final class ResourceElementSmall { + private static final boolean DEBUG = ClusterImpl.DEBUG; + // Descriptor = type & complete object reference & value index & predicate index. + private static final int DESCRIPTOR_OFFSET = 0; // descriptor + private static final int STM_OFFSET = 1; // two statements + private static final int SIZE_OF = 2; + + static void construct(long[] table, int index) { + int i = DESCRIPTOR_OFFSET + index; + table[i++] = 0; // descriptor + table[i++] = 0; // stm1 & 2 + } + + static void destruct(long[] table, int index) { + int i = DESCRIPTOR_OFFSET + index; + table[i++] = 0; // descriptor + table[i++] = 0; // stm1 & 2 + } + + static boolean isUsed(long[] table, int index) { + int i = DESCRIPTOR_OFFSET + index; + if (table[i++] != 0) + return true; + if (table[i++] != 0) + return true; + return false; + } + + static int getSizeOf() { + return SIZE_OF; + } + + static ClusterI.CompleteTypeEnum getCompleteType(long[] table, int index) { + int i = DESCRIPTOR_OFFSET + index; + byte bits = (byte)BitUtility.getMiddle(table[i], 62, 2); + return ClusterI.CompleteTypeEnum.make(bits); + } + + static void setCompleteType(long[] table, int index, byte data) { + int i = DESCRIPTOR_OFFSET + index; + table[i] = BitUtility.setMiddle(table[i], 62, 2, data); + } + + static short getCompleteObjectRef(long[] table, int index) { + int i = DESCRIPTOR_OFFSET + index; + return (short)BitUtility.getMiddle(table[i], 46, 16); + } + + static void setCompleteObjectRef(long[] table, int index, int ref) { + if (ref > (1<<16)-1) + throw new IllegalArgumentException(); + int i = DESCRIPTOR_OFFSET + index; + table[i] = BitUtility.setMiddle(table[i], 46, 16, ref); + } + + static boolean completeHasMultiple(long[] table, int index) { + int i = DESCRIPTOR_OFFSET + index; + int completeRefAndType= BitUtility.getMiddle(table[i], 46, 18); + boolean complete = (completeRefAndType >>> 16) != 0; + return !complete && (completeRefAndType != 0); + } + + static boolean completeIsFirstStatement(long[] table, int index) { + int i = DESCRIPTOR_OFFSET + index; + int completeRefAndType = BitUtility.getMiddle(table[i], 46, 18); + return completeRefAndType == 0; + } + + static boolean completeIsSameStatement(long[] table, int index, int refAndType) { + int i = DESCRIPTOR_OFFSET + index; + int completeRefAndType = BitUtility.getMiddle(table[i], 46, 18); + return completeRefAndType == refAndType; + } + + static int completeGetRefAndType(long[] table, int index) { + int i = DESCRIPTOR_OFFSET + index; + return BitUtility.getMiddle(table[i], 46, 18); + } + + static void completeSetRefAndType(long[] table, int index, int refAndType) { + int i = DESCRIPTOR_OFFSET + index; + table[i] = BitUtility.setMiddle(table[i], 46, 18, refAndType); + } + + static int completeMakeObjectRefAndType(short oRef, ClusterI.CompleteTypeEnum completeType) { + return oRef & (1<<16)-1 | completeType.getValue()<<16; + } + + static short completeGetObjectSetIndex(long[] table, int index) { + int i = DESCRIPTOR_OFFSET + index; + return (short)BitUtility.getMiddle(table[i], 46, 16); + } + + static int completeGetStatementCountApproximation(long[] table, int index) { + int i = DESCRIPTOR_OFFSET + index; + int cType = BitUtility.getMiddle(table[i], 62, 2); + if (cType != 0) + return 1; + int cRef = BitUtility.getMiddle(table[i], 46, 16); + if (cRef != 0) + return 2; // Can be bigger, hence the approximation. + return 0; + } + + static int getValueIndex(long[] table, int index) { + int i = DESCRIPTOR_OFFSET + index; + int valueIndex = BitUtility.getMiddle(table[i], 24, 22); + return valueIndex; + } + + static void setValueIndex(long[] table, int index, int valueIndex) { + int i = DESCRIPTOR_OFFSET + index; + table[i] = BitUtility.setMiddle(table[i], 24, 22, valueIndex); + } + + static int getPredicateIndex(long[] table, int index) { + int i = DESCRIPTOR_OFFSET + index; + int predicateIndex = BitUtility.getMiddle(table[i], 0, 24); + return predicateIndex; + } + + static void setPredicateIndex(long[] table, int index, int predicateIndex) { + int i = DESCRIPTOR_OFFSET + index; + table[i] = BitUtility.setMiddle(table[i], 0, 24, predicateIndex); + } + + static short getStm1Predicate(long[] table, int index) { + int i = STM_OFFSET + index; + short predicateIndex = BitUtility.getLowShort(table[i]); + return predicateIndex; + } + + static void setStm1Predicate(long[] table, int index, short predicateIndex) { + int i = STM_OFFSET + index; + table[i] = BitUtility.setLowShort(table[i], predicateIndex); + } + + static short getStm1Object(long[] table, int index) { + int i = STM_OFFSET + index; + short objectIndex = (short)BitUtility.getMiddle(table[i], 16, 16); + return objectIndex; + } + + static void setStm1Object(long[] table, int index, short objectIndex) { + int i = STM_OFFSET + index; + table[i] = BitUtility.setMiddle(table[i], 16, 16, objectIndex); + } + + static short getStm2Predicate(long[] table, int index) { + int i = STM_OFFSET + index; + short predicateIndex = (short)BitUtility.getMiddle(table[i], 32, 16); + return predicateIndex; + } + + static void setStm2Predicate(long[] table, int index, short predicateIndex) { + int i = STM_OFFSET + index; + table[i] = BitUtility.setMiddle(table[i], 32, 16, predicateIndex); + } + + static short getStm2Object(long[] table, int index) { + int i = STM_OFFSET + index; + short objectIndex = (short)BitUtility.getMiddle(table[i], 48, 16); + return objectIndex; + } + + static void setStm2Object(long[] table, int index, short objectIndex) { + int i = STM_OFFSET + index; + table[i] = BitUtility.setMiddle(table[i], 48, 16, objectIndex); + } + + public static byte[] getValue(ValueTableSmall valueTable, long[] table, int index) + throws DatabaseException { + int valueIndex = getValueIndex(table, index); + if (0 == valueIndex) + return null; // no value + else if (ClusterTraitsSmall.VALUE_INDEX_EX == valueIndex) + throw new ExternalValueException("Value stored externally. index=" + index); + return valueTable.getValue(valueIndex); + } +//KRAA: +// static char[] getString(ValueTableSmall valueTable, long[] table, int index) { +// int valueIndex = getValueIndex(table, index); +// if (0 == valueIndex) +// return null; // no value +//// else if (ClusterTraitsSmall.VALUE_INDEX_MAX == valueIndex) +//// throw new Error("Not implemented! //KRAA:"); +// return valueTable.getString(valueIndex); +// } + + static boolean hasValue(long[] table, int index) { + int valueIndex = getValueIndex(table, index); + return 0 != valueIndex; + } + +// static boolean hasValue(ValueTable valueTable, long[] table, int index, byte[] value) { +// int valueIndex = getValueIndex(table, index); +// if (0 == valueIndex) +// return false; +// return valueTable.isEqual(valueIndex, value, 0, value.length); +// } + + static boolean removeValue(ValueTableSmall valueTable, long[] table, int index) { + int valueIndex = getValueIndex(table, index); + if (0 == valueIndex) + return false; // not removed + else if (ClusterTraitsSmall.VALUE_INDEX_EX != valueIndex) + valueTable.removeValue(valueIndex); + setValueIndex(table, index, 0); + return true; + } + + public static void setValue(ValueTableSmall valueTable, long[] table, int index, byte[] value, int length) + throws OutOfSpaceException { + int oldIndex = getValueIndex(table, index); + if (ClusterTraitsSmall.VALUE_INDEX_EX == oldIndex) + oldIndex = 0; + if (length > ClusterTraitsSmall.VALUE_SIZE_MAX) + throw new OutOfSpaceException("Out of space for value. size=" + length); + int newIndex = valueTable.setValue(oldIndex, value, 0, length); + if (newIndex != oldIndex) { + if (newIndex > ClusterTraitsSmall.VALUE_INDEX_MAX) { + setValueIndex(table, index, 0); + throw new OutOfSpaceException("Out of space for values. index=" + newIndex); + } + setValueIndex(table, index, newIndex); + } + return; + } + + public static boolean isValueEx(ValueTableSmall valueTable, long[] table, int index) { + int vIndex = getValueIndex(table, index); + if (ClusterTraitsSmall.VALUE_INDEX_EX == vIndex) + return true; + else + return false; + } + + public static void setValueEx(ValueTableSmall valueTable, long[] table, int index) { + setValueIndex(table, index, ClusterTraitsSmall.VALUE_INDEX_EX); + } + + public static boolean foreachPredicate(long[] table, int index, + ClusterI.PredicateProcedure procedure, + Context context, ClusterSupport support, Modifier modifier, + CompleteTable ct) + throws DatabaseException { + if (DEBUG) + System.out.println("ResourceElement.foreachPredicate: 1"); + int completeRef = ResourceElementSmall.getCompleteObjectRef(table, index); + if (0 != completeRef) { + if (ResourceElementSmall.completeHasMultiple(table, index)) { // multiple complete objects + // CompleteRef is a complete object set index. + boolean broken = ct.foreachPredicate(completeRef, procedure, context, support, modifier); + if (DEBUG) + System.out.println("ResourceElement.foreachPredicate: multi-complete ci=" + completeRef + " break=" + broken); + if (broken) + return true; // loop broken by procedure + } else { // We have zero or one complete statement. + ClusterI.CompleteTypeEnum completeType = ResourceElementSmall.getCompleteType(table, index); + if (ClusterI.CompleteTypeEnum.NotComplete != completeType) { + int key = ClusterTraitsBase.getCompleteTypeResourceKeyFromEnum(completeType); + boolean broken = procedure.execute(context, key, 0); + if (DEBUG) + System.out.println("ResourceElement.foreachPredicate: complete rk=" + key + " break=" + broken); + if (broken) + return true; // loop broken by procedure + } + } + } + // If predicate set is in use it will contain also these statements. + if (0 != ResourceElementSmall.getPredicateIndex(table, index)) { + if (DEBUG) + System.out.println("ResourceElement.foreachPredicate: more than 2 objects"); + return false; + } + int p1 = getStm1Predicate(table, index); + if (0 == p1) { + if (DEBUG) + System.out.println("ResourceElement.foreachPredicate: empty cache"); + return false; // loop finished, no statements + } + int externalRef; + if (null == modifier) + externalRef = p1; + else + externalRef = modifier.execute(p1); + if (DEBUG) + System.out.println("ResourceElement.foreachPredicate: cache1 pk=" + externalRef); + if (procedure.execute(context, externalRef, 0)) + return true; // loop broken by procedure + int p2 = getStm2Predicate(table, index); + if (0 == p2 || p1 == p2) { + if (DEBUG) + System.out.println("ResourceElement.foreachPredicate: cache2 empty"); + return false; // loop finished, one predicate + } + if (null == modifier) + externalRef = p2; + else + externalRef = modifier.execute(p2); + if (DEBUG) + System.out.println("ResourceElement.foreachPredicate: cache2 pk=" + externalRef); + return procedure.execute(context, externalRef, 0); + } + + public static int getSingleObject(long[] table, int index, ClusterSupport support, final short pRef, + final ClusterI.CompleteTypeEnum pCompleteType, CompleteTable ct, Modifier modifier) + throws DatabaseException { + if (DEBUG) + System.out.println("ResourceElement.getSingleObject: index=" + index); + if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType) { + int completeRef = getCompleteObjectRef(table, index); + if (0 == completeRef) + return 0; // no objects for given complete type + if (ResourceElementSmall.completeHasMultiple(table, index)) { + // Multiple complete type statements. + if (DEBUG) + System.out.println("ResourceElement.was complete 2"); + ClusterI.ObjectProcedure proc = new ClusterI.ObjectProcedure() { + @Override + public boolean execute(Short context, int completeRefAndType) + throws DatabaseException { + ClusterI.CompleteTypeEnum ct = ClusterTraitsSmall.completeRefAndTypeGetType(completeRefAndType); + if (ct == pCompleteType) { // we have a match + if (context != 0) { // we have an old match + context = 0; // multiple objects for given type + return true; // break loop + } + context = ClusterTraitsSmall.completeRefAndTypeGetRef(completeRefAndType); + } + return true; // continue looping + } + }; + Short objectRef = 0; + // CompleteRef is complete object set index. + ct.foreachComplete(completeRef, proc, objectRef, support, modifier); + return modifier.execute(objectRef); + } // One complete type statement. + ClusterI.CompleteTypeEnum rCompleteType = ResourceElementSmall.getCompleteType(table, index); + if (pCompleteType != rCompleteType) + return 0; // no objects for given complete type + // CompleteRef is object resource reference. + return modifier.execute(completeRef); + } + int p1 = getStm1Predicate(table, index); + if (0 == p1) + return 0; // loop finished, no statements + int result = 0; + if (pRef == p1) { + short o1 = getStm1Object(table, index); + result = modifier.execute(o1); +// procedure.execute(graph, new ResourceImpl(null, modifier.execute(o1))); +// int externalRef; +// if (null == modifier) +// externalRef = o1; +// else +// externalRef = modifier.execute(callerThread, o1); +// if (procedure.execute(callerThread, context, externalRef)) +// return true; // loop broken by procedure + } + int p2 = getStm2Predicate(table, index); + if (0 == p2 || pRef != p2) + return result; // loop finished, one statements + + // Many statements + if (result != 0) return -1; + + short o2 = getStm2Object(table, index); + return modifier.execute(o2); +// int externalRef; +// if (null == modifier) +// externalRef = o2; +// else +// externalRef = modifier.execute(callerThread, o2); +// if (procedure.execute(callerThread, context, externalRef)) +// return true; // loop broken by procedure +// return false; // loop finished +// procedure.execute(graph, new ResourceImpl(null, modifier.execute(o2))); + } + + public static void foreachObject(long[] table, int index, + final ReadGraphImpl graph, final AsyncMultiProcedure procedure, + ClusterSupport support, final int pRef, ClusterI.CompleteTypeEnum pCompleteType, CompleteTable ct, final Modifier modifier) + throws DatabaseException { + if (DEBUG) + System.out.println("ResourceElement.foreachObject1: index=" + index); + if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType) { + int completeRef = getCompleteObjectRef(table, index); + if (0 == completeRef) { + procedure.finished(graph); +// graph.state.dec(0); + return; // no objects for given complete type + } + if (ResourceElementSmall.completeHasMultiple(table, index)) {// multiple objects + ClusterI.ObjectProcedure proc = new ClusterI.ObjectProcedure() { + @Override + public boolean execute(Object _context, int objectRef) + throws DatabaseException { + procedure.execute(graph, new ResourceImpl(graph.getResourceSupport(), modifier.execute(objectRef))); + return false; // continue looping + } + + }; + // CompleteRef is complete object set index. + ct.foreachComplete(completeRef, proc, null, support, modifier); + } else { // One complete type element. CompleteRef is resource reference. + ClusterI.CompleteTypeEnum rCompleteType = ResourceElementSmall.getCompleteType(table, index); + if (pCompleteType != rCompleteType) { + procedure.finished(graph); +// graph.state.dec(0); + return; // Complete predicate does not match. + } + procedure.execute(graph, new ResourceImpl(graph.getResourceSupport(), modifier.execute(completeRef))); + } + procedure.finished(graph); +// graph.state.dec(0); + return; // loop finished + } + short p1 = getStm1Predicate(table, index); + if (0 == p1) { + procedure.finished(graph); +// graph.state.dec(0); + return; // loop finished, no statements + } + if (pRef == p1) { + short o1 = getStm1Object(table, index); + procedure.execute(graph, new ResourceImpl(graph.getResourceSupport(), modifier.execute(o1))); +// int externalRef; +// if (null == modifier) +// externalRef = o1; +// else +// externalRef = modifier.execute(callerThread, o1); +// if (procedure.execute(callerThread, context, externalRef)) +// return true; // loop broken by procedure + } + short p2 = getStm2Predicate(table, index); + if (0 == p2 || pRef != p2) { + procedure.finished(graph); +// graph.state.dec(0); + return; // loop finished, one statements + } + int o2 = getStm2Object(table, index); +// int externalRef; +// if (null == modifier) +// externalRef = o2; +// else +// externalRef = modifier.execute(callerThread, o2); +// if (procedure.execute(callerThread, context, externalRef)) +// return true; // loop broken by procedure +// return false; // loop finished + procedure.execute(graph, new ResourceImpl(graph.getResourceSupport(), modifier.execute(o2))); + procedure.finished(graph); +// graph.state.dec(0); + } + + public static void foreachObject(long[] table, int index, + final ReadGraphImpl graph, final C context, final AsyncContextMultiProcedure procedure, + ClusterSupport support, final int pRef, ClusterI.CompleteTypeEnum pCompleteType, CompleteTable ct, final Modifier modifier) + throws DatabaseException { + if (DEBUG) + System.out.println("ResourceElement.foreachObject1: index=" + index); + if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType) { + int completeRef = getCompleteObjectRef(table, index); + if (0 == completeRef) { + procedure.finished(graph, context); +// graph.state.dec(0); + return; // no objects for given complete type + } + if (ResourceElementSmall.completeHasMultiple(table, index)) {// multiple objects + ClusterI.ObjectProcedure proc = new ClusterI.ObjectProcedure() { + @Override + public boolean execute(Object _context, int objectRef) + throws DatabaseException { + procedure.execute(graph, context, new ResourceImpl(graph.getResourceSupport(), modifier.execute(objectRef))); + return false; // continue looping + } + + }; + // CompleteRef is complete object set index. + ct.foreachComplete(completeRef, proc, null, support, modifier); + } else { // One complete type element. CompleteRef is resource reference. + ClusterI.CompleteTypeEnum rCompleteType = ResourceElementSmall.getCompleteType(table, index); + if (pCompleteType != rCompleteType) { + procedure.finished(graph, context); +// graph.state.dec(0); + return; // Complete predicate does not match. + } + procedure.execute(graph, context, new ResourceImpl(graph.getResourceSupport(), modifier.execute(completeRef))); + } + procedure.finished(graph, context); +// graph.state.dec(0); + return; // loop finished + } + short p1 = getStm1Predicate(table, index); + if (0 == p1) { + procedure.finished(graph, context); +// graph.state.dec(0); + return; // loop finished, no statements + } + if (pRef == p1) { + short o1 = getStm1Object(table, index); + procedure.execute(graph, context, new ResourceImpl(graph.getResourceSupport(), modifier.execute(o1))); +// int externalRef; +// if (null == modifier) +// externalRef = o1; +// else +// externalRef = modifier.execute(callerThread, o1); +// if (procedure.execute(callerThread, context, externalRef)) +// return true; // loop broken by procedure + } + short p2 = getStm2Predicate(table, index); + if (0 == p2 || pRef != p2) { + procedure.finished(graph, context); +// graph.state.dec(0); + return; // loop finished, one statements + } + int o2 = getStm2Object(table, index); +// int externalRef; +// if (null == modifier) +// externalRef = o2; +// else +// externalRef = modifier.execute(callerThread, o2); +// if (procedure.execute(callerThread, context, externalRef)) +// return true; // loop broken by procedure +// return false; // loop finished + procedure.execute(graph, context, new ResourceImpl(graph.getResourceSupport(), modifier.execute(o2))); + procedure.finished(graph, context); +// graph.state.dec(0); + } + + public static boolean foreachObject(long[] table, int index + , ClusterI.ObjectProcedure procedure + , Context context, ClusterSupport support, Modifier modifier + , final short pRef, ClusterI.CompleteTypeEnum pCompleteType, CompleteTable ct) + throws DatabaseException { + if (DEBUG) + System.out.println("ResourceElementSmall.foreachObject2: 1"); + if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType) { + int completeRef = getCompleteObjectRef(table, index); + if (0 == completeRef) { + if (DEBUG) + System.out.println("ResourceElementSmall.foreachObject2: no complete"); + return false; // no objects for given complete type + } if (ResourceElementSmall.completeHasMultiple(table, index)) { + if (DEBUG) + System.out.println("ResourceElementSmall.foreachObject2: multi-complete ci=" + completeRef); + // CompleteRef is complete object set index. + return ct.foreachObject(completeRef, procedure, context, support, modifier, pCompleteType); + } + // One complete type statement at most. + ClusterI.CompleteTypeEnum completeType = ResourceElementSmall.getCompleteType(table, index); + if (pCompleteType != completeType) { + if (DEBUG) + System.out.println("ResourceElementSmall.foreachObject2: complete different predicate"); + return false; // Loop finished. No objects for given complete predicate type. + } + int externalRef = completeRef; + if (null != modifier) + externalRef = modifier.execute(externalRef); + if (DEBUG) + System.out.println("ResourceElementSmall.foreachObject2: complete ok=" + externalRef); + return procedure.execute(context, externalRef); + } + int p1 = getStm1Predicate(table, index); + if (0 == p1) { + if (DEBUG) + System.out.println("ResourceElementSmall.foreachObject2: empty cache="); + return false; // loop finished, no statements + } + if (pRef == p1) { + int o1 = getStm1Object(table, index); + int externalRef; + if (null == modifier) + externalRef = o1; + else + externalRef = modifier.execute(o1); + if (DEBUG) + System.out.println("ResourceElementSmall.foreachObject2: cache1 ok=" + externalRef); + if (procedure.execute(context, externalRef)) + return true; // loop broken by procedure + } + int p2 = getStm2Predicate(table, index); + if (0 == p2 || pRef != p2) { + if (DEBUG) + System.out.println("ResourceElementSmall.foreachObject2: not in cache1"); + return false; // loop finished, one statements + } + int o2 = getStm2Object(table, index); + int externalRef; + if (null == modifier) + externalRef = o2; + else + externalRef = modifier.execute(o2); + if (DEBUG) + System.out.println("ResourceElementSmall.foreachObject2: cache2 ok=" + externalRef); + return procedure.execute(context, externalRef); + } + static boolean isEmpty(long[] table, int index) { + return getStatementCountApproximation(table, index) == 0 && !hasValue(table, index); + } + static int getStatementCountApproximation(long[] table, int index) { + int n = ResourceElementSmall.completeGetStatementCountApproximation(table, index); + short p1 = getStm1Predicate(table, index); + if (0 == p1) + return n; + short p2 = getStm2Predicate(table, index); + if (0 == p2) + return n+1; + int predicateIndex = getPredicateIndex(table, index); + if (0 == predicateIndex) + return n + 2; + return n + 3; // Can be bigger, hence the approximation. + } + static int addStatement(long[] table, int index, short pRef, short oRef + , PredicateTable pt, ObjectTable ot + , ClusterI.CompleteTypeEnum completeType, CompleteTable ct) + throws DatabaseException { + assert (0 != pRef); + assert (0 != oRef); + if (ClusterI.CompleteTypeEnum.NotComplete != completeType) { // predicate is complete type + int coRefAndType = completeMakeObjectRefAndType(oRef, completeType); + if (completeIsFirstStatement(table, index)) + completeSetRefAndType(table, index, coRefAndType); + else { // old complete statements exist + if (completeIsSameStatement(table, index, coRefAndType)) + return -1; // old complete + int nRef; + if (completeHasMultiple(table, index)) { // nth statement + int coSetIndex = completeGetObjectSetIndex(table, index) & 0xFFFF; + nRef = ct.addComplete(coSetIndex, coRefAndType); + if (0 == nRef) + return -1; // old complete + else if (nRef >= 1<<16) { + ct.removeComplete(coSetIndex, coRefAndType); + throw new OutOfSpaceException("Out of space for complete objects. index=" + nRef); + } + } else { // second statement + int coRefAndTypeOld = ResourceElementSmall.completeGetRefAndType(table, index); + nRef = ct.createCompleteArraySet(coRefAndTypeOld, coRefAndType); + if (nRef >= 1<<16) + throw new OutOfSpaceException("Out of space for complete objects. index=" + nRef); + ResourceElementSmall.setCompleteType(table, index, (byte)0); + } + setCompleteObjectRef(table, index, nRef); + } + return 0; // added to complete + } + short p1 = getStm1Predicate(table, index); + short o1 = getStm1Object(table, index); + if (0 == p1) { + setStm1Predicate(table, index, pRef); + setStm1Object(table, index, oRef); + return 0; // added to stm cache + } else if (p1 == pRef && o1 == oRef) + return -1; // same statement + short p2 = getStm2Predicate(table, index); + short o2 = getStm2Object(table, index); + if (0 == p2) { + setStm2Predicate(table, index, pRef); + setStm2Object(table, index, oRef); + return 0; // added to stm cache + } else if (p2 == pRef && o2 == oRef) + return -1; // same statement + int predicateIndex = getPredicateIndex(table, index); + if (0 == predicateIndex) { + if (p1 == p2) { + int objectIndex = ot.createObjectSet(o1 & 0xFFFF, o2 & 0xFFFF); + assert (0 != objectIndex); + int[] os = new int[1]; + os[0] = ClusterTraits.statementIndexMake(objectIndex); + int[] ps = new int[1]; + ps[0] = p1 & 0xFFFF; + predicateIndex = pt.createPredicateSet(ps, os); + } else { + int[] os = new int[2]; + os[0] = o1 & 0xFFFF; + os[1] = o2 & 0xFFFF; + int[] ps = new int[2]; + ps[0] = p1 & 0xFFFF; + ps[1] = p2 & 0xFFFF; + predicateIndex = pt.createPredicateSet(ps, os); + } + assert (0 != predicateIndex); + setPredicateIndex(table, index, predicateIndex); + } + assert (0 != predicateIndex); + return predicateIndex; + } + + static boolean removeStatement(long[] table, int index, short pRef, short oRef, + ClusterI.CompleteTypeEnum completeType, CompleteTable ct) + throws DatabaseException { + assert (0 != pRef); + assert (0 != oRef); + if (completeType != ClusterI.CompleteTypeEnum.NotComplete) { + int completeRef = ResourceElementSmall.getCompleteObjectRef(table, index); + if (0 == completeRef) + return false; // Statement not removed because it doesn't exist. + int refAndType = ResourceElementSmall.completeMakeObjectRefAndType(oRef, completeType); + if (ResourceElementSmall.completeIsSameStatement(table, index, refAndType)) { + ResourceElementSmall.completeSetRefAndType(table, index, 0); + return true; // statement removed + } else if (ResourceElementSmall.completeHasMultiple(table, index)) { + // CompleteRef is index to complete table. + int oldSize = ct.getCompleteSetSize(completeRef); + int newSize = ct.removeComplete(completeRef, refAndType); + if (oldSize == newSize) + return false; // not removed + else if (newSize == 1) { + int cRef = ct.removeLast(completeRef); + ResourceElementSmall.completeSetRefAndType(table, index, cRef); + } + return true; + } + return false; // Statement not removed because it doesn't exist. + } + short p1 = getStm1Predicate(table, index); + short o1 = getStm1Object(table, index); + if (0 == p1) + return false; // no statements cached + short p2 = getStm2Predicate(table, index); + short o2 = getStm2Object(table, index); + if (p1 == pRef && o1 == oRef) { + setStm1Predicate(table, index, p2); + setStm1Object(table, index, o2); + setStm2Predicate(table, index, (short)0); + setStm2Object(table, index, (short)0); + return true; // statement removed + } + if (0 == p2) + return false; // no match + else if (p2 == pRef && o2 == oRef) { + setStm2Predicate(table, index, (short)0); + setStm2Object(table, index, (short)0); + return true; // statement removed + } + return false; + } +}