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%2FResourceTableSmall.java;fp=bundles%2Forg.simantics.db.procore%2Fsrc%2Forg%2Fsimantics%2Fdb%2Fprocore%2Fcluster%2FResourceTableSmall.java;h=d72b79aa567d5d582e23e90f132c9c45edee7599;hp=1edaeec789df4672afa1a4000eae1f3686059823;hb=0ae2b770234dfc3cbb18bd38f324125cf0faca07;hpb=24e2b34260f219f0d1644ca7a138894980e25b14 diff --git a/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ResourceTableSmall.java b/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ResourceTableSmall.java index 1edaeec78..d72b79aa5 100644 --- a/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ResourceTableSmall.java +++ b/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ResourceTableSmall.java @@ -1,483 +1,483 @@ -/******************************************************************************* - * 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 { - 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); - } - - boolean foreachResource(ClusterI.ObjectProcedure 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 boolean foreachPredicate(int resourceIndex - , ClusterI.PredicateProcedure 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 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 void foreachObject(int resourceIndex, ReadGraphImpl graph, C context, - AsyncContextMultiProcedure 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 boolean foreachObject(int resourceIndex - , ClusterI.ObjectProcedure 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 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 - implements ClusterI.ObjectProcedure { - 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 op = new ForeachObject(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 boolean foreach(int setIndex, Procedure procedure, Context context, - ClusterSupport support, Modifier modifier) throws DatabaseException { - throw new UnsupportedOperationException(); - } -} - -class CalculateStatementsSmall -implements ClusterI.PredicateProcedure { - 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, ClusterI.ObjectProcedure { - private ObjectTable ot; - private final ArrayList stms = new ArrayList(); - GetStatementsSmall(ObjectTable ot) { - this.ot = ot; - } - ArrayList 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, ObjectProcedure { - 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 - } - -} +/******************************************************************************* + * 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 { + 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); + } + + boolean foreachResource(ClusterI.ObjectProcedure 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 boolean foreachPredicate(int resourceIndex + , ClusterI.PredicateProcedure 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 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 void foreachObject(int resourceIndex, ReadGraphImpl graph, C context, + AsyncContextMultiProcedure 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 boolean foreachObject(int resourceIndex + , ClusterI.ObjectProcedure 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 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 + implements ClusterI.ObjectProcedure { + 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 op = new ForeachObject(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 boolean foreach(int setIndex, Procedure procedure, Context context, + ClusterSupport support, Modifier modifier) throws DatabaseException { + throw new UnsupportedOperationException(); + } +} + +class CalculateStatementsSmall +implements ClusterI.PredicateProcedure { + 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, ClusterI.ObjectProcedure { + private ObjectTable ot; + private final ArrayList stms = new ArrayList(); + GetStatementsSmall(ObjectTable ot) { + this.ot = ot; + } + ArrayList 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, ObjectProcedure { + 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 + } + +}