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; } }