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=1edaeec789df4672afa1a4000eae1f3686059823;hp=0000000000000000000000000000000000000000;hb=969bd23cab98a79ca9101af33334000879fb60c5;hpb=866dba5cd5a3929bbeae85991796acb212338a08 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 new file mode 100644 index 000000000..1edaeec78 --- /dev/null +++ b/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ResourceTableSmall.java @@ -0,0 +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 + } + +}