-/*******************************************************************************\r
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
- * in Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- * VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.db.procore.cluster;\r
-\r
-import java.util.ArrayList;\r
-\r
-import org.simantics.db.Resource;\r
-import org.simantics.db.common.utils.Logger;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.db.impl.ClusterBase;\r
-import org.simantics.db.impl.ClusterI;\r
-import org.simantics.db.impl.ClusterI.ObjectProcedure;\r
-import org.simantics.db.impl.ClusterI.PredicateProcedure;\r
-import org.simantics.db.impl.ClusterI.Procedure;\r
-import org.simantics.db.impl.ClusterSupport;\r
-import org.simantics.db.impl.ClusterTraitsBase;\r
-import org.simantics.db.impl.Modifier;\r
-import org.simantics.db.impl.Table;\r
-import org.simantics.db.impl.TableFactory;\r
-import org.simantics.db.impl.TableSizeListener;\r
-import org.simantics.db.impl.graph.ReadGraphImpl;\r
-import org.simantics.db.procedure.AsyncContextMultiProcedure;\r
-import org.simantics.db.procedure.AsyncMultiProcedure;\r
-import org.simantics.db.procore.cluster.PredicateTable.Status;\r
-\r
-\r
-\r
-public final class ResourceTableSmall extends Table<long[]> {\r
- public ResourceTableSmall(TableSizeListener sizeListener, int[] header, int headerBase) {\r
- super(TableFactory.getLongFactory(), sizeListener, header, headerBase);\r
- }\r
-\r
- public ResourceTableSmall(TableSizeListener sizeListener, int[] header, int headerBase, long[] longs) {\r
- super(TableFactory.getLongFactory(), sizeListener, header, headerBase, longs);\r
- }\r
-\r
- public int getUsedSize() {\r
- return getTableCount();\r
- }\r
-\r
- public short createResource() {\r
- final int INDEX = getTableCount();\r
- final int SIZE = ResourceElementSmall.getSizeOf();\r
- int resourceIndex = createNewElement(SIZE);\r
- assert (0 != resourceIndex);\r
- final int REAL_INDEX = checkIndexAndGetRealIndex(resourceIndex, SIZE);\r
- ResourceElementSmall.construct(getTable(), REAL_INDEX);\r
- incResourceCount();\r
- return (short)(INDEX + ZERO_SHIFT);\r
- }\r
-\r
- void createResource(int resourceIndex) {\r
- final int tableCount = getTableCount();\r
- if (resourceIndex <= tableCount) { // old index\r
- int realIndex = checkIndexAndGetRealIndex(resourceIndex);\r
- if (ResourceElementSmall.isEmpty(getTable(), realIndex))\r
- return;\r
- } if (resourceIndex == tableCount+1) {\r
- createResource();\r
- return;\r
- }\r
- throw new InternalError("Trying to create resource with illegal index=" + resourceIndex);\r
- }\r
-\r
- public short getCompleteObjectRef(int resourceIndex) {\r
- int realIndex = checkIndexAndGetRealIndex(resourceIndex);\r
- return ResourceElementSmall.getCompleteObjectRef(getTable(), realIndex);\r
- }\r
- \r
- public ClusterI.CompleteTypeEnum getCompleteType(int resourceIndex) {\r
- int realIndex = checkIndexAndGetRealIndex(resourceIndex);\r
- return ResourceElementSmall.getCompleteType(getTable(), realIndex);\r
- }\r
- \r
- public int getPredicateIndex(int resourceIndex) {\r
- int realIndex = checkIndexAndGetRealIndex(resourceIndex);\r
- return ResourceElementSmall.getPredicateIndex(table, realIndex);\r
- }\r
-\r
- public void setPredicateIndex(int resourceIndex, int predicateIndex) {\r
- int realIndex = checkIndexAndGetRealIndex(resourceIndex);\r
- ResourceElementSmall.setPredicateIndex(getTable(), realIndex, predicateIndex);\r
- }\r
-\r
- public byte[] getValue(ValueTableSmall valueTable, int resourceIndex)\r
- throws DatabaseException {\r
- int realIndex = checkIndexAndGetRealIndex(resourceIndex);\r
- return ResourceElementSmall.getValue(valueTable, getTable(), realIndex);\r
- }\r
-//KRAA:\r
-// char[] getString(ValueTableSmall valueTable, int resourceIndex) {\r
-// int realIndex = checkIndexAndGetRealIndex(resourceIndex);\r
-// return ResourceElementSmall.getString(valueTable, getTable(), realIndex);\r
-// }\r
-\r
- public boolean hasValue(int resourceIndex) {\r
- int realIndex = checkIndexAndGetRealIndex(resourceIndex);\r
- return ResourceElementSmall.hasValue(getTable(), realIndex);\r
- }\r
-\r
-// boolean hasValue(ValueTable valueTable, int resourceIndex, byte[] value) {\r
-// int realIndex = checkIndexAndGetRealIndex(resourceIndex);\r
-// return ResourceElementSmall.hasValue(valueTable, getTable(), realIndex, value);\r
-// }\r
-\r
- public boolean removeValue(ValueTableSmall valueTable, int resourceIndex) {\r
- int realIndex = checkIndexAndGetRealIndex(resourceIndex);\r
- boolean ret = ResourceElementSmall.removeValue(valueTable, getTable(), realIndex);\r
-// if (ret && !ResourceElementSmall.isUsed(getTable(), realIndex))\r
-// decResourceCount();\r
- return ret;\r
- }\r
-\r
- public void setValue(ValueTableSmall valueTable, int resourceIndex, byte[] value, int length)\r
- throws OutOfSpaceException {\r
- int realIndex = checkIndexAndGetRealIndex(resourceIndex);\r
- ResourceElementSmall.setValue(valueTable, getTable(), realIndex, value, length);\r
- }\r
-\r
- public boolean isValueEx(ValueTableSmall valueTable, int resourceIndex) {\r
- int realIndex = checkIndexAndGetRealIndex(resourceIndex);\r
- return ResourceElementSmall.isValueEx(valueTable, getTable(), realIndex);\r
- }\r
-\r
- public void setValueEx(ValueTableSmall valueTable, int resourceIndex) {\r
- int realIndex = checkIndexAndGetRealIndex(resourceIndex);\r
- ResourceElementSmall.setValueEx(valueTable, getTable(), realIndex);\r
- }\r
-\r
- static final int RESOURCE_COUNT_INDEX = 0;\r
- static final int FOREIGN_COUNT_INDEX = 1; // Reserved by server.\r
- static final int CLUSTER_STATUS_INDEX = 2;\r
-\r
- int incResourceCount() {\r
- int count = getExtra(RESOURCE_COUNT_INDEX) + 1;\r
- setExtra(RESOURCE_COUNT_INDEX, count);\r
- return count;\r
- }\r
-\r
-// int decResourceCount() {\r
-// int count = getExtra(RESOURCE_COUNT_INDEX) - 1;\r
-// setExtra(RESOURCE_COUNT_INDEX, count);\r
-// return count;\r
-// }\r
-\r
- public int getResourceCount() {\r
- return getExtra(RESOURCE_COUNT_INDEX);\r
- }\r
- public int getClusterStatus() {\r
- return getExtra(CLUSTER_STATUS_INDEX);\r
- }\r
- public void setClusterStatus(int value) {\r
- setExtra(CLUSTER_STATUS_INDEX, value);\r
- }\r
-\r
- <Context> boolean foreachResource(ClusterI.ObjectProcedure<Context> procedure, Context context,\r
- ClusterSupport support, Modifier modifier) throws DatabaseException {\r
- final int tsize = getTableSize();\r
-// final int rsize = getResourceCount();\r
- final int esize = ResourceElementSmall.getSizeOf();\r
- //int count = 0;\r
- int key = ZERO_SHIFT;\r
- for (int i = getTableBase(); i < getTableBase() + tsize; i += esize, ++key) {\r
- if (ResourceElementSmall.isUsed(getTable(), i)) {\r
- int ref;\r
- if (null == modifier)\r
- ref = key;\r
- else\r
- ref = modifier.execute(key);\r
- if (procedure.execute(context, ref))\r
- return true; // loop was broken by procedure\r
-// if (rsize == ++count)\r
-// return false; // loop finished\r
- }\r
- }\r
- //assert(rsize == count);\r
- return false; // loop finished\r
- }\r
-\r
- public <Context> boolean foreachPredicate(int resourceIndex\r
- , ClusterI.PredicateProcedure<Context> procedure, Context context\r
- , ClusterSupport support, Modifier modifier, CompleteTable ct)\r
- throws DatabaseException {\r
- int realIndex = checkIndexAndGetRealIndex(resourceIndex);\r
- return ResourceElementSmall.foreachPredicate(getTable(), realIndex\r
- , procedure, context, support, modifier, ct);\r
- }\r
-\r
- public int getSingleObject(int resourceIndex, ClusterSupport support, short pRef, ClusterI.CompleteTypeEnum completeType, CompleteTable ct, Modifier modifier) throws DatabaseException {\r
- int realIndex = checkIndexAndGetRealIndex(resourceIndex);\r
- return ResourceElementSmall.getSingleObject(table, realIndex, support, pRef, completeType, ct, modifier);\r
- }\r
-\r
- public void foreachObject(int resourceIndex, ReadGraphImpl graph,\r
- AsyncMultiProcedure<Resource> procedure, ClusterSupport support, int pRef, ClusterI.CompleteTypeEnum completeType, CompleteTable ct, Modifier modifier) throws DatabaseException {\r
- int realIndex = checkIndexAndGetRealIndex(resourceIndex);\r
- ResourceElementSmall.foreachObject(table, realIndex, graph, procedure, support,\r
- pRef, completeType, ct, modifier);\r
- }\r
-\r
- public <C> void foreachObject(int resourceIndex, ReadGraphImpl graph, C context,\r
- AsyncContextMultiProcedure<C, Resource> procedure, ClusterSupport support, int pRef, ClusterI.CompleteTypeEnum completeType, CompleteTable ct, Modifier modifier) throws DatabaseException {\r
- int realIndex = checkIndexAndGetRealIndex(resourceIndex);\r
- ResourceElementSmall.foreachObject(table, realIndex, graph, context, procedure, support,\r
- pRef, completeType, ct, modifier);\r
- }\r
-\r
- public <Context> boolean foreachObject(int resourceIndex\r
- , ClusterI.ObjectProcedure<Context> procedure, Context context\r
- , ClusterSupport support, Modifier modifier,\r
- short pRef, ClusterI.CompleteTypeEnum completeType, CompleteTable ct)\r
- throws DatabaseException {\r
- int realIndex = checkIndexAndGetRealIndex(resourceIndex);\r
- return ResourceElementSmall.foreachObject(table, realIndex\r
- , procedure, context, support, modifier\r
- , pRef, completeType, ct);\r
- }\r
- public int addStatement(int resourceIndex, short pRef, short oRef, PredicateTable pt, ObjectTable ot\r
- , ClusterI.CompleteTypeEnum completeType, CompleteTable ct)\r
- throws DatabaseException {\r
- int realIndex = checkIndexAndGetRealIndex(resourceIndex);\r
- return ResourceElementSmall.addStatement(getTable(), realIndex, pRef, oRef, pt, ot, completeType, ct);\r
- }\r
-\r
- public boolean removeStatementFromCache(int resourceIndex, short pRef, short oRef,\r
- ClusterI.CompleteTypeEnum completeType, CompleteTable ct)\r
- throws DatabaseException {\r
- int realIndex = checkIndexAndGetRealIndex(resourceIndex);\r
- boolean ret = ResourceElementSmall.removeStatement(getTable(), realIndex, pRef, oRef, completeType, ct);\r
-// if (ret && !ResourceElementSmall.isUsed(getTable(), realIndex))\r
-// decResourceCount();\r
- return ret;\r
- }\r
- \r
- public void removeStatement(int resourceIndex, short pRef, short oRef, ClusterI.CompleteTypeEnum pCompleteType, CompleteTable ct,\r
- PredicateTable pt, ObjectTable ot, ClusterSupport support)\r
- throws DatabaseException {\r
- int realIndex = checkIndexAndGetRealIndex(resourceIndex);\r
- boolean removed = ResourceElementSmall.removeStatement(getTable(), realIndex,\r
- pRef, oRef, pCompleteType, ct);\r
- if (!removed)\r
- return;\r
- int predicateIndex = ResourceElementSmall.getPredicateIndex(getTable(), realIndex);\r
- if (0 == predicateIndex) {\r
-// if (!ResourceElementSmall.isUsed(getTable(), realIndex))\r
-// decResourceCount();\r
- return;\r
- } else if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType)\r
- return; // Complete type statements are not kept in statement cache.\r
- // We have one more statements in predicate table.\r
- // Here we check if statement cache needs fixing.\r
- GetStatementsSmall gs = new GetStatementsSmall(ot);\r
- pt.foreachPredicate(predicateIndex, gs, null, null, null);\r
- ArrayList<Statement> stms = gs.getStatements();\r
-\r
- final int SIZE = stms.size();\r
- if (SIZE < 3) {\r
- for (int i = 0; i < SIZE; ++i) {\r
- Statement stm = stms.get(i);\r
- PredicateTable.Status ret = pt.removePredicate(predicateIndex,\r
- stm.pRef, stm.oIndex, ot);\r
- if (ret == Status.NothingRemoved)\r
- throw new DatabaseException("Internal error during statement cache fix (2).");\r
- assert(stm.pRef < (1<<16));\r
- assert(stm.oIndex < 1<<16);\r
- int pi = ResourceElementSmall.addStatement(getTable(), realIndex, (short)stm.pRef, (short)stm.oIndex,\r
- pt, ot, ClusterI.CompleteTypeEnum.NotComplete, ct);\r
- assert(0 >= pi);\r
- }\r
- assert(0 == pt.getPredicateSetSize(predicateIndex));\r
- ResourceElementSmall.setPredicateIndex(getTable(), realIndex, 0);\r
- } else {\r
- for (int i = 0; i < SIZE; ++i) {\r
- Statement stm = stms.get(i);\r
- assert(stm.pRef < (1<<16));\r
- assert(stm.oIndex < 1<<16);\r
- int pIndex = ResourceElementSmall.addStatement(getTable(), realIndex,\r
- (short)stm.pRef, (short)stm.oIndex, pt, ot, ClusterI.CompleteTypeEnum.NotComplete, ct);\r
- if (pIndex > 0)\r
- return; // cache fixed and full, p and o sets in use\r
- }\r
- throw new DatabaseException("Internal error during statement cache fix (3).");\r
- }\r
-// if (!ResourceElementSmall.isUsed(getTable(), realIndex))\r
-// decResourceCount();\r
- }\r
-\r
- private int checkIndexAndGetRealIndex(final int resourceIndex) {\r
- if (ClusterTraitsBase.isIllegalResourceIndex(resourceIndex))\r
- throw new RuntimeException("Illegal resource index. index=" + resourceIndex + ".");\r
- if(resourceIndex > getTableCount())\r
- throw new RuntimeException("Illegal resource index. index=" + resourceIndex + " table count=" + getTableCount());\r
- final int SIZE = ResourceElementSmall.getSizeOf();\r
- final int REAL_INDEX = resourceIndex * SIZE - (SIZE - ZERO_SHIFT) + offset;\r
- return REAL_INDEX;\r
- }\r
- void check(ClusterImpl cluster)\r
- throws DatabaseException {\r
-// throw new Error("Not implemented.//KRAA:");\r
- }\r
-\r
- public void toBig(ClusterBase big, final ClusterSupport support, final ClusterBase small)\r
- throws DatabaseException {\r
- int resourceIndex = 1;\r
- long[] table = getTable();\r
- int ps = getHeader().getOffset() + ZERO_SHIFT;\r
- final int TABLE_SIZE = getTableSize();\r
- int pe = ps + TABLE_SIZE;\r
- for (int p=ps; p<pe; p+=ResourceElementSmall.getSizeOf(), ++resourceIndex) {\r
- big.createResource(support);\r
- int subjectKey = ClusterTraits.createResourceKey(small.clusterKey, resourceIndex); \r
- if (!ResourceElementSmall.isUsed(table, p))\r
- continue;\r
- int cr = ResourceElementSmall.getCompleteObjectRef(table, p);\r
- if (0 != cr) {\r
- ClusterI.CompleteTypeEnum ct = ResourceElementSmall.getCompleteType(table, p);\r
- if (ClusterI.CompleteTypeEnum.NotComplete != ct) {\r
- int pKey = ClusterTraitsBase.getCompleteTypeResourceKeyFromEnum(ct);\r
- int oKey = small.getCompleteObjectKey(subjectKey, support);\r
- big.addRelation(subjectKey, pKey, oKey, support);\r
- } else {\r
- final class ForeachObject<Context>\r
- implements ClusterI.ObjectProcedure<Context> {\r
- int sKey;\r
- ClusterBase big;\r
- public ForeachObject(int sKey, ClusterBase big) {\r
- this.sKey = sKey;\r
- this.big = big;\r
- }\r
- @Override\r
- public boolean execute(Context context, int completeRef)\r
- throws DatabaseException {\r
- ClusterI.CompleteTypeEnum ct = ClusterTraitsSmall.completeRefAndTypeGetType(completeRef);\r
- int p = ClusterTraitsBase.getCompleteTypeResourceKeyFromEnum(ct);\r
- int o = small.execute(completeRef & 0xFFFF);\r
- big.addRelation(sKey, p, o, support);\r
- return false; // Continue looping.\r
- }\r
- }\r
- ForeachObject<Object> op = new ForeachObject<Object>(subjectKey, big);\r
- small.getCompleteTable().foreach(cr & 0xFFFF, op, null, support, null);\r
- }\r
- }\r
- int pi = ResourceElementSmall.getPredicateIndex(table, p);\r
- if (0 != pi) {\r
- ToBigStatements tbs = new ToBigStatements(small, big, support, subjectKey);\r
- small.getPredicateTable().foreach(pi, tbs, null, null, null);\r
- } else {\r
- int p1 = ResourceElementSmall.getStm1Predicate(table, p);\r
- int o1 = ResourceElementSmall.getStm1Object(table, p);\r
- if (p1 != 0) {\r
- int pk1 = small.execute(p1);\r
- int ok1 = small.execute(o1);\r
- big.addRelation(subjectKey, pk1, ok1, support);\r
- int p2 = ResourceElementSmall.getStm2Predicate(table, p);\r
- int o2 = ResourceElementSmall.getStm2Object(table, p);\r
- if (p2 != 0) {\r
- int pk2 = small.execute(p2);\r
- int ok2 = small.execute(o2);\r
- big.addRelation(subjectKey, pk2, ok2, support);\r
- }\r
- }\r
- }\r
- int valueIndex = ResourceElementSmall.getValueIndex(table, p);\r
- if (ClusterTraitsSmall.VALUE_INDEX_EX == valueIndex)\r
- big.setValueEx(subjectKey);\r
- else {\r
- byte[] value = ResourceElementSmall.getValue((ValueTableSmall)small.getValueTable(), table, p);\r
- if (null != value)\r
- big.setValue(subjectKey, value, value.length, support);\r
- }\r
- }\r
- }\r
-\r
- @Override\r
- public <Context> boolean foreach(int setIndex, Procedure procedure, Context context,\r
- ClusterSupport support, Modifier modifier) throws DatabaseException {\r
- throw new UnsupportedOperationException();\r
- }\r
-}\r
-\r
-class CalculateStatementsSmall\r
-implements ClusterI.PredicateProcedure<CalculateStatements> {\r
- private ObjectTable ot;\r
- private final int sRef;\r
-\r
- CalculateStatementsSmall(int sRef, ObjectTable ot) {\r
- this.sRef = sRef;\r
- this.ot = ot;\r
- }\r
-\r
- @Override\r
- public boolean execute(CalculateStatements context\r
- , final int pKey, int oIndex) {\r
- if (ClusterTraits.statementIndexIsDirect(oIndex))\r
- return false; // osize = 1\r
- try {\r
- oIndex = ClusterTraits.statementIndexGet(oIndex);\r
- } catch (DatabaseException e) {\r
- Logger.getDefault().logError("Missing object set for s="\r
- + sRef + " p=" + pKey, null);\r
- return false; // continue looping\r
- }\r
- int osize = ot.getObjectSetSize(oIndex);\r
- if (osize == 3 || osize > 9)\r
- System.out.println("Resource " + sRef + " predicate " + pKey + " has "\r
- + osize + " objects.");\r
- return true; // break loop\r
- }\r
-}\r
-\r
-class GetStatementsSmall implements ClusterI.PredicateProcedure<Object>, ClusterI.ObjectProcedure<Integer> {\r
- private ObjectTable ot;\r
- private final ArrayList<Statement> stms = new ArrayList<Statement>(); \r
- GetStatementsSmall(ObjectTable ot) {\r
- this.ot = ot;\r
- }\r
- ArrayList<Statement> getStatements() {\r
- return stms;\r
- }\r
- @Override\r
- public boolean execute(Object context, int pRef, int oIndex) {\r
- try {\r
- ot.foreachObject(oIndex, this, pRef, null, null);\r
- } catch (DatabaseException e) {\r
- e.printStackTrace();\r
- return false; // continue looping\r
- }\r
- if (stms.size() > 2)\r
- return true; // break loop\r
- return false; // continue looping\r
- }\r
- \r
- @Override\r
- public boolean execute(Integer pRef, int oRef) {\r
- stms.add(new Statement(pRef, oRef));\r
- if (stms.size() > 2)\r
- return true; // break loop\r
- return false; // continue looping\r
- }\r
-}\r
-\r
-class ToBigStatements implements PredicateProcedure<Object>, ObjectProcedure<Integer> {\r
- private ClusterBase small;\r
- private ClusterBase big;\r
- private ClusterSupport support;\r
- private int subjectKey;\r
- ToBigStatements(ClusterBase small, ClusterBase big, ClusterSupport support, int subjectKey) {\r
- this.small = small;\r
- this.big = big;\r
- this.support = support;\r
- this.subjectKey = subjectKey;\r
- }\r
- @Override\r
- public boolean execute(Object context, int pRef, int oIndex) {\r
- try {\r
- small.getObjectTable().foreach(oIndex, this, pRef, null, null);\r
- } catch (DatabaseException e) {\r
- e.printStackTrace();\r
- return false; // continue looping\r
- }\r
- return false; // continue looping\r
- }\r
-\r
- @Override\r
- public boolean execute(Integer pRef, int oRef)\r
- throws DatabaseException {\r
- int pKey = small.execute(pRef);\r
- int oKey = small.execute(oRef);\r
- big.addRelation(subjectKey, pKey, oKey, support);\r
- return false; // continue looping\r
- }\r
- \r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.db.procore.cluster;
+
+import java.util.ArrayList;
+
+import org.simantics.db.Resource;
+import org.simantics.db.common.utils.Logger;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.impl.ClusterBase;
+import org.simantics.db.impl.ClusterI;
+import org.simantics.db.impl.ClusterI.ObjectProcedure;
+import org.simantics.db.impl.ClusterI.PredicateProcedure;
+import org.simantics.db.impl.ClusterI.Procedure;
+import org.simantics.db.impl.ClusterSupport;
+import org.simantics.db.impl.ClusterTraitsBase;
+import org.simantics.db.impl.Modifier;
+import org.simantics.db.impl.Table;
+import org.simantics.db.impl.TableFactory;
+import org.simantics.db.impl.TableSizeListener;
+import org.simantics.db.impl.graph.ReadGraphImpl;
+import org.simantics.db.procedure.AsyncContextMultiProcedure;
+import org.simantics.db.procedure.AsyncMultiProcedure;
+import org.simantics.db.procore.cluster.PredicateTable.Status;
+
+
+
+public final class ResourceTableSmall extends Table<long[]> {
+ public ResourceTableSmall(TableSizeListener sizeListener, int[] header, int headerBase) {
+ super(TableFactory.getLongFactory(), sizeListener, header, headerBase);
+ }
+
+ public ResourceTableSmall(TableSizeListener sizeListener, int[] header, int headerBase, long[] longs) {
+ super(TableFactory.getLongFactory(), sizeListener, header, headerBase, longs);
+ }
+
+ public int getUsedSize() {
+ return getTableCount();
+ }
+
+ public short createResource() {
+ final int INDEX = getTableCount();
+ final int SIZE = ResourceElementSmall.getSizeOf();
+ int resourceIndex = createNewElement(SIZE);
+ assert (0 != resourceIndex);
+ final int REAL_INDEX = checkIndexAndGetRealIndex(resourceIndex, SIZE);
+ ResourceElementSmall.construct(getTable(), REAL_INDEX);
+ incResourceCount();
+ return (short)(INDEX + ZERO_SHIFT);
+ }
+
+ void createResource(int resourceIndex) {
+ final int tableCount = getTableCount();
+ if (resourceIndex <= tableCount) { // old index
+ int realIndex = checkIndexAndGetRealIndex(resourceIndex);
+ if (ResourceElementSmall.isEmpty(getTable(), realIndex))
+ return;
+ } if (resourceIndex == tableCount+1) {
+ createResource();
+ return;
+ }
+ throw new InternalError("Trying to create resource with illegal index=" + resourceIndex);
+ }
+
+ public short getCompleteObjectRef(int resourceIndex) {
+ int realIndex = checkIndexAndGetRealIndex(resourceIndex);
+ return ResourceElementSmall.getCompleteObjectRef(getTable(), realIndex);
+ }
+
+ public ClusterI.CompleteTypeEnum getCompleteType(int resourceIndex) {
+ int realIndex = checkIndexAndGetRealIndex(resourceIndex);
+ return ResourceElementSmall.getCompleteType(getTable(), realIndex);
+ }
+
+ public int getPredicateIndex(int resourceIndex) {
+ int realIndex = checkIndexAndGetRealIndex(resourceIndex);
+ return ResourceElementSmall.getPredicateIndex(table, realIndex);
+ }
+
+ public void setPredicateIndex(int resourceIndex, int predicateIndex) {
+ int realIndex = checkIndexAndGetRealIndex(resourceIndex);
+ ResourceElementSmall.setPredicateIndex(getTable(), realIndex, predicateIndex);
+ }
+
+ public byte[] getValue(ValueTableSmall valueTable, int resourceIndex)
+ throws DatabaseException {
+ int realIndex = checkIndexAndGetRealIndex(resourceIndex);
+ return ResourceElementSmall.getValue(valueTable, getTable(), realIndex);
+ }
+//KRAA:
+// char[] getString(ValueTableSmall valueTable, int resourceIndex) {
+// int realIndex = checkIndexAndGetRealIndex(resourceIndex);
+// return ResourceElementSmall.getString(valueTable, getTable(), realIndex);
+// }
+
+ public boolean hasValue(int resourceIndex) {
+ int realIndex = checkIndexAndGetRealIndex(resourceIndex);
+ return ResourceElementSmall.hasValue(getTable(), realIndex);
+ }
+
+// boolean hasValue(ValueTable valueTable, int resourceIndex, byte[] value) {
+// int realIndex = checkIndexAndGetRealIndex(resourceIndex);
+// return ResourceElementSmall.hasValue(valueTable, getTable(), realIndex, value);
+// }
+
+ public boolean removeValue(ValueTableSmall valueTable, int resourceIndex) {
+ int realIndex = checkIndexAndGetRealIndex(resourceIndex);
+ boolean ret = ResourceElementSmall.removeValue(valueTable, getTable(), realIndex);
+// if (ret && !ResourceElementSmall.isUsed(getTable(), realIndex))
+// decResourceCount();
+ return ret;
+ }
+
+ public void setValue(ValueTableSmall valueTable, int resourceIndex, byte[] value, int length)
+ throws OutOfSpaceException {
+ int realIndex = checkIndexAndGetRealIndex(resourceIndex);
+ ResourceElementSmall.setValue(valueTable, getTable(), realIndex, value, length);
+ }
+
+ public boolean isValueEx(ValueTableSmall valueTable, int resourceIndex) {
+ int realIndex = checkIndexAndGetRealIndex(resourceIndex);
+ return ResourceElementSmall.isValueEx(valueTable, getTable(), realIndex);
+ }
+
+ public void setValueEx(ValueTableSmall valueTable, int resourceIndex) {
+ int realIndex = checkIndexAndGetRealIndex(resourceIndex);
+ ResourceElementSmall.setValueEx(valueTable, getTable(), realIndex);
+ }
+
+ static final int RESOURCE_COUNT_INDEX = 0;
+ static final int FOREIGN_COUNT_INDEX = 1; // Reserved by server.
+ static final int CLUSTER_STATUS_INDEX = 2;
+
+ int incResourceCount() {
+ int count = getExtra(RESOURCE_COUNT_INDEX) + 1;
+ setExtra(RESOURCE_COUNT_INDEX, count);
+ return count;
+ }
+
+// int decResourceCount() {
+// int count = getExtra(RESOURCE_COUNT_INDEX) - 1;
+// setExtra(RESOURCE_COUNT_INDEX, count);
+// return count;
+// }
+
+ public int getResourceCount() {
+ return getExtra(RESOURCE_COUNT_INDEX);
+ }
+ public int getClusterStatus() {
+ return getExtra(CLUSTER_STATUS_INDEX);
+ }
+ public void setClusterStatus(int value) {
+ setExtra(CLUSTER_STATUS_INDEX, value);
+ }
+
+ <Context> boolean foreachResource(ClusterI.ObjectProcedure<Context> procedure, Context context,
+ ClusterSupport support, Modifier modifier) throws DatabaseException {
+ final int tsize = getTableSize();
+// final int rsize = getResourceCount();
+ final int esize = ResourceElementSmall.getSizeOf();
+ //int count = 0;
+ int key = ZERO_SHIFT;
+ for (int i = getTableBase(); i < getTableBase() + tsize; i += esize, ++key) {
+ if (ResourceElementSmall.isUsed(getTable(), i)) {
+ int ref;
+ if (null == modifier)
+ ref = key;
+ else
+ ref = modifier.execute(key);
+ if (procedure.execute(context, ref))
+ return true; // loop was broken by procedure
+// if (rsize == ++count)
+// return false; // loop finished
+ }
+ }
+ //assert(rsize == count);
+ return false; // loop finished
+ }
+
+ public <Context> boolean foreachPredicate(int resourceIndex
+ , ClusterI.PredicateProcedure<Context> procedure, Context context
+ , ClusterSupport support, Modifier modifier, CompleteTable ct)
+ throws DatabaseException {
+ int realIndex = checkIndexAndGetRealIndex(resourceIndex);
+ return ResourceElementSmall.foreachPredicate(getTable(), realIndex
+ , procedure, context, support, modifier, ct);
+ }
+
+ public int getSingleObject(int resourceIndex, ClusterSupport support, short pRef, ClusterI.CompleteTypeEnum completeType, CompleteTable ct, Modifier modifier) throws DatabaseException {
+ int realIndex = checkIndexAndGetRealIndex(resourceIndex);
+ return ResourceElementSmall.getSingleObject(table, realIndex, support, pRef, completeType, ct, modifier);
+ }
+
+ public void foreachObject(int resourceIndex, ReadGraphImpl graph,
+ AsyncMultiProcedure<Resource> procedure, ClusterSupport support, int pRef, ClusterI.CompleteTypeEnum completeType, CompleteTable ct, Modifier modifier) throws DatabaseException {
+ int realIndex = checkIndexAndGetRealIndex(resourceIndex);
+ ResourceElementSmall.foreachObject(table, realIndex, graph, procedure, support,
+ pRef, completeType, ct, modifier);
+ }
+
+ public <C> void foreachObject(int resourceIndex, ReadGraphImpl graph, C context,
+ AsyncContextMultiProcedure<C, Resource> procedure, ClusterSupport support, int pRef, ClusterI.CompleteTypeEnum completeType, CompleteTable ct, Modifier modifier) throws DatabaseException {
+ int realIndex = checkIndexAndGetRealIndex(resourceIndex);
+ ResourceElementSmall.foreachObject(table, realIndex, graph, context, procedure, support,
+ pRef, completeType, ct, modifier);
+ }
+
+ public <Context> boolean foreachObject(int resourceIndex
+ , ClusterI.ObjectProcedure<Context> procedure, Context context
+ , ClusterSupport support, Modifier modifier,
+ short pRef, ClusterI.CompleteTypeEnum completeType, CompleteTable ct)
+ throws DatabaseException {
+ int realIndex = checkIndexAndGetRealIndex(resourceIndex);
+ return ResourceElementSmall.foreachObject(table, realIndex
+ , procedure, context, support, modifier
+ , pRef, completeType, ct);
+ }
+ public int addStatement(int resourceIndex, short pRef, short oRef, PredicateTable pt, ObjectTable ot
+ , ClusterI.CompleteTypeEnum completeType, CompleteTable ct)
+ throws DatabaseException {
+ int realIndex = checkIndexAndGetRealIndex(resourceIndex);
+ return ResourceElementSmall.addStatement(getTable(), realIndex, pRef, oRef, pt, ot, completeType, ct);
+ }
+
+ public boolean removeStatementFromCache(int resourceIndex, short pRef, short oRef,
+ ClusterI.CompleteTypeEnum completeType, CompleteTable ct)
+ throws DatabaseException {
+ int realIndex = checkIndexAndGetRealIndex(resourceIndex);
+ boolean ret = ResourceElementSmall.removeStatement(getTable(), realIndex, pRef, oRef, completeType, ct);
+// if (ret && !ResourceElementSmall.isUsed(getTable(), realIndex))
+// decResourceCount();
+ return ret;
+ }
+
+ public void removeStatement(int resourceIndex, short pRef, short oRef, ClusterI.CompleteTypeEnum pCompleteType, CompleteTable ct,
+ PredicateTable pt, ObjectTable ot, ClusterSupport support)
+ throws DatabaseException {
+ int realIndex = checkIndexAndGetRealIndex(resourceIndex);
+ boolean removed = ResourceElementSmall.removeStatement(getTable(), realIndex,
+ pRef, oRef, pCompleteType, ct);
+ if (!removed)
+ return;
+ int predicateIndex = ResourceElementSmall.getPredicateIndex(getTable(), realIndex);
+ if (0 == predicateIndex) {
+// if (!ResourceElementSmall.isUsed(getTable(), realIndex))
+// decResourceCount();
+ return;
+ } else if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType)
+ return; // Complete type statements are not kept in statement cache.
+ // We have one more statements in predicate table.
+ // Here we check if statement cache needs fixing.
+ GetStatementsSmall gs = new GetStatementsSmall(ot);
+ pt.foreachPredicate(predicateIndex, gs, null, null, null);
+ ArrayList<Statement> stms = gs.getStatements();
+
+ final int SIZE = stms.size();
+ if (SIZE < 3) {
+ for (int i = 0; i < SIZE; ++i) {
+ Statement stm = stms.get(i);
+ PredicateTable.Status ret = pt.removePredicate(predicateIndex,
+ stm.pRef, stm.oIndex, ot);
+ if (ret == Status.NothingRemoved)
+ throw new DatabaseException("Internal error during statement cache fix (2).");
+ assert(stm.pRef < (1<<16));
+ assert(stm.oIndex < 1<<16);
+ int pi = ResourceElementSmall.addStatement(getTable(), realIndex, (short)stm.pRef, (short)stm.oIndex,
+ pt, ot, ClusterI.CompleteTypeEnum.NotComplete, ct);
+ assert(0 >= pi);
+ }
+ assert(0 == pt.getPredicateSetSize(predicateIndex));
+ ResourceElementSmall.setPredicateIndex(getTable(), realIndex, 0);
+ } else {
+ for (int i = 0; i < SIZE; ++i) {
+ Statement stm = stms.get(i);
+ assert(stm.pRef < (1<<16));
+ assert(stm.oIndex < 1<<16);
+ int pIndex = ResourceElementSmall.addStatement(getTable(), realIndex,
+ (short)stm.pRef, (short)stm.oIndex, pt, ot, ClusterI.CompleteTypeEnum.NotComplete, ct);
+ if (pIndex > 0)
+ return; // cache fixed and full, p and o sets in use
+ }
+ throw new DatabaseException("Internal error during statement cache fix (3).");
+ }
+// if (!ResourceElementSmall.isUsed(getTable(), realIndex))
+// decResourceCount();
+ }
+
+ private int checkIndexAndGetRealIndex(final int resourceIndex) {
+ if (ClusterTraitsBase.isIllegalResourceIndex(resourceIndex))
+ throw new RuntimeException("Illegal resource index. index=" + resourceIndex + ".");
+ if(resourceIndex > getTableCount())
+ throw new RuntimeException("Illegal resource index. index=" + resourceIndex + " table count=" + getTableCount());
+ final int SIZE = ResourceElementSmall.getSizeOf();
+ final int REAL_INDEX = resourceIndex * SIZE - (SIZE - ZERO_SHIFT) + offset;
+ return REAL_INDEX;
+ }
+ void check(ClusterImpl cluster)
+ throws DatabaseException {
+// throw new Error("Not implemented.//KRAA:");
+ }
+
+ public void toBig(ClusterBase big, final ClusterSupport support, final ClusterBase small)
+ throws DatabaseException {
+ int resourceIndex = 1;
+ long[] table = getTable();
+ int ps = getHeader().getOffset() + ZERO_SHIFT;
+ final int TABLE_SIZE = getTableSize();
+ int pe = ps + TABLE_SIZE;
+ for (int p=ps; p<pe; p+=ResourceElementSmall.getSizeOf(), ++resourceIndex) {
+ big.createResource(support);
+ int subjectKey = ClusterTraits.createResourceKey(small.clusterKey, resourceIndex);
+ if (!ResourceElementSmall.isUsed(table, p))
+ continue;
+ int cr = ResourceElementSmall.getCompleteObjectRef(table, p);
+ if (0 != cr) {
+ ClusterI.CompleteTypeEnum ct = ResourceElementSmall.getCompleteType(table, p);
+ if (ClusterI.CompleteTypeEnum.NotComplete != ct) {
+ int pKey = ClusterTraitsBase.getCompleteTypeResourceKeyFromEnum(ct);
+ int oKey = small.getCompleteObjectKey(subjectKey, support);
+ big.addRelation(subjectKey, pKey, oKey, support);
+ } else {
+ final class ForeachObject<Context>
+ implements ClusterI.ObjectProcedure<Context> {
+ int sKey;
+ ClusterBase big;
+ public ForeachObject(int sKey, ClusterBase big) {
+ this.sKey = sKey;
+ this.big = big;
+ }
+ @Override
+ public boolean execute(Context context, int completeRef)
+ throws DatabaseException {
+ ClusterI.CompleteTypeEnum ct = ClusterTraitsSmall.completeRefAndTypeGetType(completeRef);
+ int p = ClusterTraitsBase.getCompleteTypeResourceKeyFromEnum(ct);
+ int o = small.execute(completeRef & 0xFFFF);
+ big.addRelation(sKey, p, o, support);
+ return false; // Continue looping.
+ }
+ }
+ ForeachObject<Object> op = new ForeachObject<Object>(subjectKey, big);
+ small.getCompleteTable().foreach(cr & 0xFFFF, op, null, support, null);
+ }
+ }
+ int pi = ResourceElementSmall.getPredicateIndex(table, p);
+ if (0 != pi) {
+ ToBigStatements tbs = new ToBigStatements(small, big, support, subjectKey);
+ small.getPredicateTable().foreach(pi, tbs, null, null, null);
+ } else {
+ int p1 = ResourceElementSmall.getStm1Predicate(table, p);
+ int o1 = ResourceElementSmall.getStm1Object(table, p);
+ if (p1 != 0) {
+ int pk1 = small.execute(p1);
+ int ok1 = small.execute(o1);
+ big.addRelation(subjectKey, pk1, ok1, support);
+ int p2 = ResourceElementSmall.getStm2Predicate(table, p);
+ int o2 = ResourceElementSmall.getStm2Object(table, p);
+ if (p2 != 0) {
+ int pk2 = small.execute(p2);
+ int ok2 = small.execute(o2);
+ big.addRelation(subjectKey, pk2, ok2, support);
+ }
+ }
+ }
+ int valueIndex = ResourceElementSmall.getValueIndex(table, p);
+ if (ClusterTraitsSmall.VALUE_INDEX_EX == valueIndex)
+ big.setValueEx(subjectKey);
+ else {
+ byte[] value = ResourceElementSmall.getValue((ValueTableSmall)small.getValueTable(), table, p);
+ if (null != value)
+ big.setValue(subjectKey, value, value.length, support);
+ }
+ }
+ }
+
+ @Override
+ public <Context> boolean foreach(int setIndex, Procedure procedure, Context context,
+ ClusterSupport support, Modifier modifier) throws DatabaseException {
+ throw new UnsupportedOperationException();
+ }
+}
+
+class CalculateStatementsSmall
+implements ClusterI.PredicateProcedure<CalculateStatements> {
+ private ObjectTable ot;
+ private final int sRef;
+
+ CalculateStatementsSmall(int sRef, ObjectTable ot) {
+ this.sRef = sRef;
+ this.ot = ot;
+ }
+
+ @Override
+ public boolean execute(CalculateStatements context
+ , final int pKey, int oIndex) {
+ if (ClusterTraits.statementIndexIsDirect(oIndex))
+ return false; // osize = 1
+ try {
+ oIndex = ClusterTraits.statementIndexGet(oIndex);
+ } catch (DatabaseException e) {
+ Logger.getDefault().logError("Missing object set for s="
+ + sRef + " p=" + pKey, null);
+ return false; // continue looping
+ }
+ int osize = ot.getObjectSetSize(oIndex);
+ if (osize == 3 || osize > 9)
+ System.out.println("Resource " + sRef + " predicate " + pKey + " has "
+ + osize + " objects.");
+ return true; // break loop
+ }
+}
+
+class GetStatementsSmall implements ClusterI.PredicateProcedure<Object>, ClusterI.ObjectProcedure<Integer> {
+ private ObjectTable ot;
+ private final ArrayList<Statement> stms = new ArrayList<Statement>();
+ GetStatementsSmall(ObjectTable ot) {
+ this.ot = ot;
+ }
+ ArrayList<Statement> getStatements() {
+ return stms;
+ }
+ @Override
+ public boolean execute(Object context, int pRef, int oIndex) {
+ try {
+ ot.foreachObject(oIndex, this, pRef, null, null);
+ } catch (DatabaseException e) {
+ e.printStackTrace();
+ return false; // continue looping
+ }
+ if (stms.size() > 2)
+ return true; // break loop
+ return false; // continue looping
+ }
+
+ @Override
+ public boolean execute(Integer pRef, int oRef) {
+ stms.add(new Statement(pRef, oRef));
+ if (stms.size() > 2)
+ return true; // break loop
+ return false; // continue looping
+ }
+}
+
+class ToBigStatements implements PredicateProcedure<Object>, ObjectProcedure<Integer> {
+ private ClusterBase small;
+ private ClusterBase big;
+ private ClusterSupport support;
+ private int subjectKey;
+ ToBigStatements(ClusterBase small, ClusterBase big, ClusterSupport support, int subjectKey) {
+ this.small = small;
+ this.big = big;
+ this.support = support;
+ this.subjectKey = subjectKey;
+ }
+ @Override
+ public boolean execute(Object context, int pRef, int oIndex) {
+ try {
+ small.getObjectTable().foreach(oIndex, this, pRef, null, null);
+ } catch (DatabaseException e) {
+ e.printStackTrace();
+ return false; // continue looping
+ }
+ return false; // continue looping
+ }
+
+ @Override
+ public boolean execute(Integer pRef, int oRef)
+ throws DatabaseException {
+ int pKey = small.execute(pRef);
+ int oKey = small.execute(oRef);
+ big.addRelation(subjectKey, pKey, oKey, support);
+ return false; // continue looping
+ }
+
+}