/******************************************************************************* * 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.acorn.cluster; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Arrays; import org.simantics.acorn.exception.IllegalAcornStateException; import org.simantics.acorn.internal.ClusterChange; import org.simantics.acorn.internal.ClusterStream; import org.simantics.acorn.internal.ClusterSupport2; import org.simantics.acorn.internal.DebugPolicy; import org.simantics.db.Resource; import org.simantics.db.common.utils.Logger; import org.simantics.db.exception.DatabaseException; import org.simantics.db.exception.ExternalValueException; import org.simantics.db.exception.ValidationException; import org.simantics.db.impl.ClusterI; import org.simantics.db.impl.ClusterSupport; import org.simantics.db.impl.ClusterTraitsBase; import org.simantics.db.impl.ForEachObjectContextProcedure; import org.simantics.db.impl.ForEachObjectProcedure; import org.simantics.db.impl.ForPossibleRelatedValueContextProcedure; import org.simantics.db.impl.ForPossibleRelatedValueProcedure; import org.simantics.db.impl.IClusterTable; import org.simantics.db.impl.Table; import org.simantics.db.impl.TableHeader; 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.ClusterMapSmall; import org.simantics.db.procore.cluster.ClusterTraits; import org.simantics.db.procore.cluster.ClusterTraitsSmall; import org.simantics.db.procore.cluster.CompleteTableSmall; import org.simantics.db.procore.cluster.ForeignTableSmall; import org.simantics.db.procore.cluster.ObjectTable; import org.simantics.db.procore.cluster.OutOfSpaceException; import org.simantics.db.procore.cluster.PredicateTable; import org.simantics.db.procore.cluster.ResourceTableSmall; import org.simantics.db.procore.cluster.ValueTableSmall; import org.simantics.db.service.Bytes; import org.simantics.db.service.ClusterUID; import org.simantics.db.service.ResourceUID; import org.simantics.utils.datastructures.Callback; import gnu.trove.map.hash.TIntShortHashMap; import gnu.trove.procedure.TIntProcedure; import gnu.trove.set.hash.TIntHashSet; final public class ClusterSmall extends ClusterImpl { private static final int TABLE_HEADER_SIZE = TableHeader.HEADER_SIZE + TableHeader.EXTRA_SIZE; private static final int RESOURCE_TABLE_OFFSET = 0; private static final int PREDICATE_TABLE_OFFSET = RESOURCE_TABLE_OFFSET + TABLE_HEADER_SIZE; private static final int OBJECT_TABLE_OFFSET = PREDICATE_TABLE_OFFSET + TABLE_HEADER_SIZE; private static final int VALUE_TABLE_OFFSET = OBJECT_TABLE_OFFSET + TABLE_HEADER_SIZE; private static final int FLAT_TABLE_OFFSET = VALUE_TABLE_OFFSET + TABLE_HEADER_SIZE; private static final int COMPLETE_TABLE_OFFSET = FLAT_TABLE_OFFSET + TABLE_HEADER_SIZE; private static final int FOREIGN_TABLE_OFFSET = COMPLETE_TABLE_OFFSET + TABLE_HEADER_SIZE; private static final int INT_HEADER_SIZE = FOREIGN_TABLE_OFFSET + TABLE_HEADER_SIZE; private final int clusterBits; private final ResourceTableSmall resourceTable; private final PredicateTable predicateTable; private final ObjectTable objectTable; private final ValueTableSmall valueTable; private final ForeignTableSmall foreignTable; private final CompleteTableSmall completeTable; private final ClusterMapSmall clusterMap; private final int[] headerTable; public final ClusterSupport2 clusterSupport; private boolean proxy; private boolean deleted = false; protected ClusterSmall() { this.proxy = true; this.headerTable = null; this.resourceTable = null; this.foreignTable = null; this.predicateTable = null; this.objectTable = null; this.valueTable = null; this.completeTable = null; this.clusterMap = null; this.clusterSupport = null; this.clusterBits = 0; this.importance = 0; } public ClusterSmall(IClusterTable clusterTable, ClusterUID clusterUID, int clusterKey, ClusterSupport2 support) { super(clusterTable, clusterUID, clusterKey, support); if(DebugPolicy.REPORT_CLUSTER_EVENTS) new Exception(clusterUID.toString()).printStackTrace(); this.proxy = true; this.headerTable = null; this.resourceTable = null; this.foreignTable = null; this.predicateTable = null; this.objectTable = null; this.valueTable = null; this.completeTable = null; this.clusterMap = null; this.clusterSupport = support; this.clusterBits = 0; this.importance = 0; // new Exception("ClusterSmall " + clusterKey).printStackTrace(); } ClusterSmall(ClusterUID clusterUID, int clusterKey, ClusterSupport2 support, IClusterTable clusterTable) { super(clusterTable, clusterUID, clusterKey, support); if(DebugPolicy.REPORT_CLUSTER_EVENTS) new Exception(clusterUID.toString()).printStackTrace(); this.proxy = false; this.clusterSupport = support; this.headerTable = new int[INT_HEADER_SIZE]; this.resourceTable = new ResourceTableSmall(this, headerTable, RESOURCE_TABLE_OFFSET); this.foreignTable = new ForeignTableSmall(this, headerTable, FOREIGN_TABLE_OFFSET); this.predicateTable = new PredicateTable(this, headerTable, PREDICATE_TABLE_OFFSET); this.objectTable = new ObjectTable(this, headerTable, OBJECT_TABLE_OFFSET); this.valueTable = new ValueTableSmall(this, headerTable, VALUE_TABLE_OFFSET); this.completeTable = new CompleteTableSmall(this, headerTable, COMPLETE_TABLE_OFFSET); this.clusterMap = new ClusterMapSmall(this, foreignTable); this.clusterBits = ClusterTraitsBase.getClusterBits(clusterKey); // if(clusterTable != null) // this.importance = -clusterTable.timeCounter(); // else this.importance = 0; // new Exception("ClusterSmall " + clusterKey).printStackTrace(); } protected ClusterSmall(IClusterTable clusterTable, long[] longs, int[] ints, byte[] bytes, ClusterSupport2 support, int clusterKey) throws DatabaseException { super(clusterTable, checkValidity(-1, longs, ints, bytes), clusterKey, support); this.proxy = false; this.clusterSupport = support; if (ints.length < INT_HEADER_SIZE) throw new IllegalArgumentException("Too small integer table for cluster."); this.headerTable = ints; if(DebugPolicy.REPORT_CLUSTER_EVENTS) new Exception(Long.toString(clusterId)).printStackTrace(); this.resourceTable = new ResourceTableSmall(this, ints, RESOURCE_TABLE_OFFSET, longs); this.foreignTable = new ForeignTableSmall(this, headerTable, FOREIGN_TABLE_OFFSET, longs); this.predicateTable = new PredicateTable(this, ints, PREDICATE_TABLE_OFFSET, ints); this.objectTable = new ObjectTable(this, ints, OBJECT_TABLE_OFFSET, ints); this.valueTable = new ValueTableSmall(this, ints, VALUE_TABLE_OFFSET, bytes); this.completeTable = new CompleteTableSmall(this, headerTable, COMPLETE_TABLE_OFFSET, ints); this.clusterMap = new ClusterMapSmall(this, foreignTable); this.clusterBits = ClusterTraitsBase.getClusterBits(clusterKey); // if(clusterTable != null) { // this.importance = clusterTable.timeCounter(); // clusterTable.markImmutable(this, getImmutable()); // } // new Exception("ClusterSmall " + clusterKey).printStackTrace(); } void analyse() { System.out.println("Cluster " + clusterId); System.out.println("-size:" + getUsedSpace()); System.out.println(" -rt:" + (resourceTable.getTableCapacity() * 8 + 8)); System.out.println(" -ft:" + foreignTable.getTableCapacity() * 8); System.out.println(" -pt:" + predicateTable.getTableCapacity() * 4); System.out.println(" -ot:" + objectTable.getTableCapacity() * 4); System.out.println(" -ct:" + completeTable.getTableCapacity() * 4); System.out.println(" -vt:" + valueTable.getTableCapacity()); System.out.println("-resourceTable:"); System.out.println(" -resourceCount=" + resourceTable.getResourceCount()); System.out.println(" -size=" + resourceTable.getTableSize()); System.out.println(" -capacity=" + resourceTable.getTableCapacity()); System.out.println(" -count=" + resourceTable.getTableCount()); System.out.println(" -size=" + resourceTable.getTableSize()); //resourceTable.analyse(); } public void checkDirectReference(int dr) throws DatabaseException { if (!ClusterTraits.statementIndexIsDirect(dr)) throw new ValidationException("Reference is not direct. Reference=" + dr); if (ClusterTraits.isFlat(dr)) throw new ValidationException("Reference is flat. Reference=" + dr); if (ClusterTraits.isLocal(dr)) { if (dr < 1 || dr > resourceTable.getUsedSize()) throw new ValidationException("Illegal local reference. Reference=" + dr); } else { int fi = ClusterTraits.getForeignIndexFromReference(dr); int ri = ClusterTraits.getResourceIndexFromForeignReference(dr); if (fi < 1 || fi > foreignTable.getUsedSize()) throw new ValidationException("Illegal foreign reference. Reference=" + dr + " foreign index=" + fi); if (ri < 1 || ri > ClusterTraits.getMaxNumberOfResources()) throw new ValidationException("Illegal foreign reference. Reference=" + dr + " resource index=" + ri); } } public void checkPredicateIndex(int pi) throws DatabaseException { // predicateTable.checkPredicateSetIndex(this, pi); } public void checkObjectSetReference(int or) throws DatabaseException { if (ClusterTraits.statementIndexIsDirect(or)) throw new ValidationException("Illegal object set reference. Reference=" + or); int oi = ClusterTraits.statementIndexGet(or); this.objectTable.checkObjectSetIndex(this, oi); } public void checkValueInit() throws DatabaseException { valueTable.checkValueInit(); } public void checkValue(int capacity, int index) throws DatabaseException { valueTable.checkValue(capacity, index); } public void checkValueFini() throws DatabaseException { valueTable.checkValueFini(); } public void checkForeingIndex(int fi) throws DatabaseException { if (fi<1 || fi > foreignTable.getUsedSize()) throw new ValidationException("Illegal foreign index=" + fi); } public void checkCompleteSetReference(int cr) throws DatabaseException { if (!ClusterTraits.completeReferenceIsMultiple(cr)) throw new ValidationException("Illegal complete set reference. Reference=" + cr); int ci = cr; this.completeTable.checkCompleteSetIndex(this, ci); } public void check() throws DatabaseException { // this.completeTable.check(this); // this.objectTable.check(this); // // Must be after object table check. // this.predicateTable.check(this); // this.resourceTable.check(this); } @Override public CompleteTypeEnum getCompleteType(int resourceKey, ClusterSupport support) throws DatabaseException { final int resourceRef = getLocalReference(resourceKey); CompleteTypeEnum ct = resourceTable.getCompleteType(resourceRef); if (DEBUG) System.out.println("ClusterSmall.getCompleteType rk=" + resourceKey + " ct=" + ct); return ct; } @Override public int getCompleteObjectKey(int resourceKey, ClusterSupport support) throws DatabaseException { final int resourceIndexOld = getLocalReference(resourceKey); short completeRef = resourceTable.getCompleteObjectRef(resourceIndexOld); int clusterIndex; int resourceIndex; if (0 == completeRef) throw new DatabaseException("Resource's complete object refernce is null. Resource key=" + resourceKey + "."); ClusterI.CompleteTypeEnum completeType = resourceTable.getCompleteType(resourceIndexOld); if (completeType == ClusterI.CompleteTypeEnum.NotComplete) throw new DatabaseException("Resource has multiple complete objects. Resource key=" + resourceKey + "."); if (ClusterTraitsSmall.resourceRefIsLocal(completeRef)) { clusterIndex = clusterKey; resourceIndex = completeRef; } else { // Resource has one complete statement. ResourceUID resourceUID = clusterMap.getForeignResourceUID(completeRef); ClusterUID uid = resourceUID.asCID(); clusterIndex = clusterSupport.getClusterKeyByUID(0, uid.second); //ClusterI c = clusterTable.getClusterByClusterUIDOrMakeProxy(uid); //clusterIndex = c.getClusterKey(); //assert(clusterIndex == clusterTable.getClusterByClusterUIDOrMakeProxy(uid).getClusterKey()); resourceIndex = resourceUID.getIndex(); } int key = ClusterTraits.createResourceKey(clusterIndex, resourceIndex); if (DEBUG) System.out.println("ClusterSmall.complete object rk=" + resourceKey + " ck=" + key); return key; } @Override public boolean isComplete(int resourceKey, ClusterSupport support) throws DatabaseException { final int resourceRef = getLocalReference(resourceKey); final ClusterI.CompleteTypeEnum completeType = resourceTable.getCompleteType(resourceRef); boolean complete = completeType != ClusterI.CompleteTypeEnum.NotComplete; if (DEBUG) System.out.println("ClusterSmall.key=" + resourceKey + " isComplete=" + complete); return complete; } public int getSingleObject(int resourceKey, int predicateKey, int objectIndex, ClusterSupport support) throws DatabaseException { if (DEBUG) System.out.println("ClusterSmall.getSingleObject: rk=" + resourceKey + " pk=" + predicateKey); if (0 == objectIndex) { final int resourceIndex = ClusterTraitsBase.getResourceIndexFromResourceKeyNoThrow(resourceKey); final short pRef = getInternalReferenceOrZero2(predicateKey, support); final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey); return resourceTable.getSingleObject(resourceIndex, support, pRef, pCompleteType, completeTable, this); } return objectTable.getSingleObject(objectIndex, support, this); } public void forObjects(ReadGraphImpl graph, int resourceKey, int predicateKey, int objectIndex, AsyncMultiProcedure procedure, ClusterSupport support) throws DatabaseException { if (DEBUG) System.out.println("ClusterSmall.forObjects1: rk=" + resourceKey + " pk=" + predicateKey); if (0 == objectIndex) { final int resourceIndex = ClusterTraitsBase.getResourceIndexFromResourceKey(resourceKey); final int pRef = getInternalReferenceOrZero2(predicateKey, support); final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey); resourceTable.foreachObject(resourceIndex, graph, procedure, support, pRef, pCompleteType, completeTable, this); return; } objectTable.foreachObject(graph, objectIndex, procedure, this); } public void forObjects(ReadGraphImpl graph, int resourceKey, int predicateKey, int objectIndex, C context, AsyncContextMultiProcedure procedure, ClusterSupport support) throws DatabaseException { if (DEBUG) System.out.println("ClusterSmall.forObjects1: rk=" + resourceKey + " pk=" + predicateKey); if (0 == objectIndex) { final int resourceIndex = ClusterTraitsBase.getResourceIndexFromResourceKey(resourceKey); final int pRef = getInternalReferenceOrZero2(predicateKey, support); final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey); resourceTable.foreachObject(resourceIndex, graph, context, procedure, support, pRef, pCompleteType, completeTable, this); return; } objectTable.foreachObject(graph, objectIndex, context, procedure, this); } @Override public boolean forObjects(int resourceKey, int predicateKey, int objectIndex, ObjectProcedure procedure, Context context, ClusterSupport support) throws DatabaseException { if (DEBUG) System.out.println("ClusterSmall.forObjects2: rk=" + resourceKey + " pk=" + predicateKey); if (0 == objectIndex) { final int resourceIndex = ClusterTraitsBase.getResourceIndexFromResourceKey(resourceKey); final short pRef = getInternalReferenceOrZero2(predicateKey, support); final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey); return resourceTable.foreachObject(resourceIndex, procedure, context, support, this, pRef, pCompleteType, completeTable); } return objectTable.foreachObject(objectIndex, procedure, context, support, this); } @Override public int getSingleObject(int resourceKey, int predicateKey, ClusterSupport support) throws DatabaseException { if (DEBUG) System.out.println("ClusterSmall.getSingleObject2: rk=" + resourceKey + " pk=" + predicateKey); final int resourceIndex = ClusterTraitsBase.getResourceIndexFromResourceKey(resourceKey); final short pRef = getInternalReferenceOrZero2(predicateKey, support); final int completeType = ClusterTraitsBase.getCompleteTypeIntFromResourceKey(predicateKey); final ClusterI.CompleteTypeEnum pCompleteType = CompleteTypeEnum.make(completeType); if (completeType > 0) return resourceTable.getSingleObject(resourceIndex, support, pRef, pCompleteType, completeTable, this); final int predicateIndex = (int)resourceTable.table[(resourceIndex<<1) - 1 + resourceTable.offset] & 0xFFFFFF; if (0 == predicateIndex) // All relevant data is in resource table. return resourceTable.getSingleObject(resourceIndex, support, pRef, pCompleteType, completeTable, this); int objectIndex = predicateTable.getObjectIndex(predicateIndex, pRef & 0xFFFF); return getSingleObject(resourceKey, predicateKey, objectIndex, support); } @Override public int getSingleObject(int resourceKey, ForPossibleRelatedValueProcedure procedure, ClusterSupport support) throws DatabaseException { final short resourceIndex = (short)ClusterTraitsBase.getResourceIndexFromResourceKey(resourceKey); final int predicateKey = procedure.predicateKey; int clusterKey = ClusterTraitsBase.getClusterMaskFromResourceKey(resourceKey); short pRef = 0; if(procedure.clusterKey[0] == clusterKey) { pRef = (short)procedure.predicateReference[0]; } else { pRef = getInternalReferenceOrZero2(predicateKey, support); procedure.clusterKey[0] = clusterKey; procedure.predicateReference[0] = pRef; } final ClusterI.CompleteTypeEnum pCompleteType = procedure.completeType; if (CompleteTypeEnum.NotComplete != pCompleteType) return resourceTable.getSingleObject(resourceIndex, support, pRef, pCompleteType, completeTable, this); final int predicateIndex = (int)resourceTable.table[(resourceIndex<<1) - 1 + resourceTable.offset] & 0xFFFFFF; if (0 == predicateIndex) // All relevant data is in resource table. return resourceTable.getSingleObject(resourceIndex, support, pRef, pCompleteType, completeTable, this); int objectIndex = predicateTable.getObjectIndex(predicateIndex, pRef & 0xFFFF); return getSingleObject(resourceKey, predicateKey, objectIndex, support); } @Override public int getSingleObject(int resourceKey, ForPossibleRelatedValueContextProcedure procedure, ClusterSupport support) throws DatabaseException { final short resourceIndex = (short)ClusterTraitsBase.getResourceIndexFromResourceKey(resourceKey); final int predicateKey = procedure.predicateKey; int clusterKey = ClusterTraitsBase.getClusterMaskFromResourceKey(resourceKey); short pRef = 0; if(procedure.clusterKey[0] == clusterKey) { pRef = (short)procedure.predicateReference[0]; } else { pRef = getInternalReferenceOrZero2(predicateKey, support); procedure.clusterKey[0] = clusterKey; procedure.predicateReference[0] = pRef; } final ClusterI.CompleteTypeEnum pCompleteType = procedure.completeType; if (CompleteTypeEnum.NotComplete != pCompleteType) return resourceTable.getSingleObject(resourceIndex, support, pRef, pCompleteType, completeTable, this); final int predicateIndex = (int)resourceTable.table[(resourceIndex<<1) - 1 + resourceTable.offset] & 0xFFFFFF; if (0 == predicateIndex) // All relevant data is in resource table. return resourceTable.getSingleObject(resourceIndex, support, pRef, pCompleteType, completeTable, this); int objectIndex = predicateTable.getObjectIndex(predicateIndex, pRef & 0xFFFF); return getSingleObject(resourceKey, predicateKey, objectIndex, support); } @Override public void forObjects(ReadGraphImpl graph, int resourceKey, int predicateKey, AsyncMultiProcedure procedure) throws DatabaseException { throw new UnsupportedOperationException(); // SessionImplSocket session = (SessionImplSocket)graph.getSession(); // ClusterSupport support = session.clusterTranslator; // if (DEBUG) // System.out.println("ClusterSmall.forObjects3: rk=" + resourceKey + " pk=" + predicateKey); // final int resourceIndex = ClusterTraitsBase.getResourceIndexFromResourceKey(resourceKey); // final int pRef = getInternalReferenceOrZero2(predicateKey, support); // final int completeType = ClusterTraitsBase.getCompleteTypeIntFromResourceKey(predicateKey); // final ClusterI.CompleteTypeEnum pCompleteType = CompleteTypeEnum.make(completeType); // if (completeType > 0) { // resourceTable.foreachObject(resourceIndex, graph, procedure, support, pRef, pCompleteType, completeTable, this); // return; // } // final int predicateIndex = (int)resourceTable.table[(resourceIndex<<1) - 1 + resourceTable.offset] & 0xFFFFFF; // if (0 == predicateIndex) { // resourceTable.foreachObject(resourceIndex, graph, procedure, support, pRef, pCompleteType, completeTable, this); // return; // } // int objectIndex = predicateTable.getObjectIndex(predicateIndex, pRef & 0xFFFF); // forObjects(graph, resourceKey, predicateKey, objectIndex, procedure, support); } public void forObjects(ReadGraphImpl graph, int resourceKey, ForEachObjectProcedure procedure) throws DatabaseException { throw new UnsupportedOperationException(); // final int resourceIndex = ClusterTraitsBase.getResourceIndexFromResourceKey(resourceKey); // final int predicateKey = procedure.predicateKey; // int clusterKey = ClusterTraitsBase.getClusterMaskFromResourceKey(resourceKey); // int pRef = 0; // if(procedure.clusterKey[0] == clusterKey) { // pRef = procedure.predicateReference[0]; // } else { // SessionImplSocket session = (SessionImplSocket)graph.getSession(); // ClusterSupport support = session.clusterTranslator; // pRef = getInternalReferenceOrZero2(predicateKey, support); // procedure.clusterKey[0] = clusterKey; // procedure.predicateReference[0] = pRef; // } // final ClusterI.CompleteTypeEnum pCompleteType = procedure.completeType; // if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType) { // SessionImplSocket session = (SessionImplSocket)graph.getSession(); // ClusterSupport support = session.clusterTranslator; // resourceTable.foreachObject(resourceIndex, graph, procedure, support, pRef, pCompleteType, completeTable, this); // return; // } // final int predicateIndex = (int)resourceTable.table[(resourceIndex<<1) - 1 + resourceTable.offset] & 0xFFFFFF; // if (0 == predicateIndex) { // SessionImplSocket session = (SessionImplSocket)graph.getSession(); // ClusterSupport support = session.clusterTranslator; // resourceTable.foreachObject(resourceIndex, graph, procedure, support, pRef, pCompleteType, completeTable, this); // return; // } // int hashBase = predicateIndex + predicateTable.offset; // if (predicateTable.table[hashBase-1] < 0) { // int objectIndex = TableIntArraySet2.get(predicateTable.table, hashBase, pRef & 0xFFFF); // //int objectIndex = predicateTable.getObjectIndex(predicateIndex, pRef & 0xFFFF); // SessionImplSocket session = (SessionImplSocket)graph.getSession(); // ClusterSupport support = session.clusterTranslator; // forObjects(graph, resourceKey, predicateKey, objectIndex, procedure, support); // } else { // procedure.finished(graph); //// graph.dec(); // } } public void forObjects(ReadGraphImpl graph, int resourceKey, C context, ForEachObjectContextProcedure procedure) throws DatabaseException { throw new UnsupportedOperationException(); // final int resourceIndex = ClusterTraitsBase.getResourceIndexFromResourceKey(resourceKey); // final int predicateKey = procedure.predicateKey; // int clusterKey = ClusterTraitsBase.getClusterMaskFromResourceKey(resourceKey); // int pRef = 0; // if(procedure.clusterKey[0] == clusterKey) { // pRef = procedure.predicateReference[0]; // } else { // SessionImplSocket session = (SessionImplSocket)graph.getSession(); // ClusterSupport support = session.clusterTranslator; // pRef = getInternalReferenceOrZero2(predicateKey, support); // procedure.clusterKey[0] = clusterKey; // procedure.predicateReference[0] = pRef; // } // // final ClusterI.CompleteTypeEnum pCompleteType = procedure.completeType; // if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType) { // SessionImplSocket session = (SessionImplSocket)graph.getSession(); // ClusterSupport support = session.clusterTranslator; // resourceTable.foreachObject(resourceIndex, graph, context, procedure, support, pRef, pCompleteType, completeTable, this); // return; // } // final int predicateIndex = (int)resourceTable.table[(resourceIndex<<1) - 1 + resourceTable.offset] & 0xFFFFFF; // if (0 == predicateIndex) { // SessionImplSocket session = (SessionImplSocket)graph.getSession(); // ClusterSupport support = session.clusterTranslator; // resourceTable.foreachObject(resourceIndex, graph, context, procedure, support, pRef, pCompleteType, completeTable, this); // return; // } // int hashBase = predicateIndex + predicateTable.offset; // if(predicateTable.table[hashBase-1] < 0) { // int objectIndex = TableIntArraySet2.get(predicateTable.table, hashBase, pRef & 0xFFFF); // SessionImplSocket session = (SessionImplSocket)graph.getSession(); // ClusterSupport support = session.clusterTranslator; // forObjects(graph, resourceKey, predicateKey, objectIndex, context, procedure, support); // } else { // int objectIndex = TableIntSet2.get(predicateTable.table, hashBase, pRef & 0xFFFF); // SessionImplSocket session = (SessionImplSocket)graph.getSession(); // ClusterSupport support = session.clusterTranslator; // forObjects(graph, resourceKey, predicateKey, objectIndex, context, procedure, support); // } } @Override public boolean forObjects(int resourceKey, int predicateKey, ObjectProcedure procedure, Context context, ClusterSupport support) throws DatabaseException { if (DEBUG) System.out.println("ClusterSmall.forObjects4: rk=" + resourceKey + " pk=" + predicateKey); final short resourceIndex = (short)ClusterTraitsBase.getResourceIndexFromResourceKey(resourceKey); final short pRef = getInternalReferenceOrZero2(predicateKey, support); final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey); // PredicateType is complete i.e. all relevant data is in resource table. if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType) { if (DEBUG) System.out.println("ClusterSmall.forObjects: complete type was " + pCompleteType + " cluster=" + getClusterUID()); return resourceTable.foreachObject(resourceIndex, procedure, context, support, this, pRef, pCompleteType, completeTable); } final int predicateIndex = resourceTable.getPredicateIndex(resourceIndex); if (0 == predicateIndex) { // All relevant data is in resource table. if (DEBUG) System.out.println("ClusterSmall.forObjects: no predicate table " + pCompleteType); return resourceTable.foreachObject(resourceIndex, procedure, context, support, this, pRef, pCompleteType, completeTable); } int objectIndex = predicateTable.getObjectIndex(predicateIndex, pRef & 0xFFFF); return forObjects(resourceKey, predicateKey, objectIndex, procedure, context, support); } @Override public boolean forPredicates(int resourceKey, PredicateProcedure procedure, Context context, ClusterSupport support) throws DatabaseException { if (DEBUG) System.out.println("ClusterSmall.forPredicates: rk=" + resourceKey ); final int resourceIndex = getLocalReference(resourceKey); final int predicateIndex = resourceTable.getPredicateIndex(resourceIndex); if (0 == predicateIndex) return resourceTable.foreachPredicate(resourceIndex, procedure, context, support, this, completeTable); else { boolean broken = resourceTable.foreachPredicate(resourceIndex, procedure, context, support, this, completeTable); if (broken) return true; } return predicateTable.foreachPredicate(predicateIndex, procedure, context, support, this); } @Override public ClusterI addRelation(int sResourceKey, ClusterUID puid, int pResourceKey, ClusterUID ouid, int oResourceKey, ClusterSupport support) throws DatabaseException { if(proxy) { throw new UnsupportedOperationException(); // ClusterImpl cluster = clusterTable.load2(clusterId, clusterKey); // return cluster.addRelation(sResourceKey, pResourceKey, oResourceKey, support); } // check(); boolean ret; try { short sri = getLocalReferenceAnd(sResourceKey, support, ClusterChange.ADD_OPERATION); short pri = getReferenceOrCreateIfForeign(pResourceKey, puid, support, ClusterStream.NULL_OPERATION); short ori = getReferenceOrCreateIfForeign(oResourceKey, ouid, support, ClusterStream.NULL_OPERATION); ClusterI.CompleteTypeEnum completeType = ClusterTraitsBase.getCompleteTypeFromResourceKey(pResourceKey); ret = addRelationInternal(sri, pri, ori, completeType); calculateModifiedId(); } catch (OutOfSpaceException e) { boolean streamOff = support.getStreamOff(); if (!streamOff) { support.cancelStatement(this); support.setStreamOff(true); } ClusterI cluster = toBig(clusterSupport); if (!streamOff) support.setStreamOff(false); ClusterI cluster2 = cluster.addRelation(sResourceKey, pResourceKey, oResourceKey, support); if (cluster != cluster2) throw new DatabaseException("Internal error. Contact application support."); return cluster; } // check(); if (ret) { support.addStatement(this); return this; } else { support.cancelStatement(this); return null; } } @Override public ClusterI addRelation(int sResourceKey, int pResourceKey, int oResourceKey, ClusterSupport support) throws DatabaseException { if (DEBUG) System.out.println("add rk=" + sResourceKey + " pk=" + pResourceKey + " ok=" + oResourceKey); if(proxy) { throw new UnsupportedOperationException(); // ClusterImpl cluster = clusterTable.load2(clusterId, clusterKey); // return cluster.addRelation(sResourceKey, pResourceKey, oResourceKey, support); } // check(); boolean ret; try { short sri = getLocalReferenceAnd(sResourceKey, support, ClusterChange.ADD_OPERATION); short pri = getReferenceOrCreateIfForeign(pResourceKey, support, ClusterStream.NULL_OPERATION); short ori = getReferenceOrCreateIfForeign(oResourceKey, support, ClusterStream.NULL_OPERATION); ClusterI.CompleteTypeEnum completeType = ClusterTraitsBase.getCompleteTypeFromResourceKey(pResourceKey); ret = addRelationInternal(sri, pri, ori, completeType); calculateModifiedId(); } catch (OutOfSpaceException e) { boolean streamOff = support.getStreamOff(); if (!streamOff) { support.cancelStatement(this); support.setStreamOff(true); } ClusterI cluster = toBig(clusterSupport); if (!streamOff) support.setStreamOff(false); ClusterI cluster2 = cluster.addRelation(sResourceKey, pResourceKey, oResourceKey, support); if (cluster != cluster2) throw new DatabaseException("Internal error. Contact application support."); return cluster; } // check(); if (ret) { support.addStatement(this); return this; } else { support.cancelStatement(this); return null; } } @Override public boolean removeRelation(int sResourceKey, int pResourceKey, int oResourceKey, ClusterSupport support) throws DatabaseException { // check(); short sri = getLocalReferenceAnd(sResourceKey, support, ClusterChange.REMOVE_OPERATION); short pri = getInternalReferenceOrZeroAnd(pResourceKey, support, ClusterStream.NULL_OPERATION); short ori = getInternalReferenceOrZeroAnd(oResourceKey, support, ClusterStream.NULL_OPERATION); boolean ret = false; if (0 != pri && 0 != ori) { ClusterI.CompleteTypeEnum completeType = ClusterTraitsBase.getCompleteTypeFromResourceKey(pResourceKey); ret = removeRelationInternal(sri, pri, ori, completeType, support); calculateModifiedId(); } if (ret) support.removeStatement(this); else support.cancelStatement(this); // check(); return ret; } @Override public void denyRelation(int sResourceKey, int pResourceKey, int oResourceKey, ClusterSupport support) throws DatabaseException { short s = checkResourceKeyIsOursAndGetResourceIndexIf(sResourceKey, support); ResourceReferenceAndCluster p = checkResourceKeyAndGetResourceIndexIf(pResourceKey, support); ResourceReferenceAndCluster o = checkResourceKeyAndGetResourceIndexIf(oResourceKey, support); if (0 == s || 0 == p.reference || 0 == o.reference) return; // check(); ClusterI.CompleteTypeEnum completeType = ClusterTraitsBase.getCompleteTypeFromResourceKey(pResourceKey); boolean ret = removeRelationInternal(s, p.reference, o.reference, completeType, support); if (ret) { support.addStatementIndex(this, sResourceKey, getClusterUID(), ClusterChange.REMOVE_OPERATION); support.addStatementIndex(this, pResourceKey, p.clusterUID, ClusterStream.NULL_OPERATION); support.addStatementIndex(this, oResourceKey, o.clusterUID, ClusterStream.NULL_OPERATION); support.removeStatement(this); } calculateModifiedId(); // check(); return; } @Override public InputStream getValueStream(int resourceKey, ClusterSupport support) throws DatabaseException { if (DEBUG) System.out.println("ClusterSmall.getValue " + resourceKey); int resourceIndex = ClusterTraitsBase.getResourceIndexFromResourceKeyNoThrow(resourceKey); try { byte[] buffer = resourceTable.getValue(valueTable, resourceIndex); if(buffer == null) return null; return new ByteArrayInputStream(buffer); } catch (ExternalValueException e) { return support.getValueStreamEx(resourceIndex, clusterUID.second); } } @Override public byte[] getValue(int resourceKey, ClusterSupport support) throws DatabaseException { if (DEBUG) System.out.println("ClusterSmall.getValue " + resourceKey); int resourceIndex = ClusterTraitsBase.getResourceIndexFromResourceKeyNoThrow(resourceKey); try { return resourceTable.getValue(valueTable, resourceIndex); } catch (ExternalValueException e) { return clusterSupport.impl.getResourceFile(clusterUID.asBytes(), resourceIndex); //return support.getValueEx(resourceIndex, clusterUID.second); } } @Override public boolean hasValue(int resourceKey, ClusterSupport support) throws DatabaseException { int resourceIndex = getLocalReference(resourceKey); return resourceTable.hasValue(resourceIndex); } @Override public boolean removeValue(int resourceKey, ClusterSupport support) throws DatabaseException { int resourceIndex = getLocalReferenceAnd(resourceKey, support, ClusterChange.DELETE_OPERATION); support.removeValue(this); calculateModifiedId(); return resourceTable.removeValue(valueTable, resourceIndex); } @Override public ClusterI setValue(int rResourceId, byte[] value, int length, ClusterSupport support) throws DatabaseException { int resourceIndex = getLocalReferenceAnd(rResourceId, support, ClusterStream.SET_OPERATION); support.setValue(this, getClusterId(), value, length); try { resourceTable.setValue(valueTable, resourceIndex, value, length); calculateModifiedId(); return this; } catch (OutOfSpaceException e) { boolean streamOff = support.getStreamOff(); if (!streamOff) support.setStreamOff(true); ClusterI cluster = toBig(support); cluster.setValue(rResourceId, value, length, support); if (!streamOff) support.setStreamOff(false); return cluster; } } @Override public ClusterI modiValueEx(int rResourceId, long voffset, int length, byte[] value, int offset, ClusterSupport support) throws DatabaseException { int resourceIndex = getLocalReferenceAnd(rResourceId, support, ClusterStream.MODI_OPERATION); support.modiValue(this, getClusterId(), voffset, length, value, offset); resourceTable.setValueEx(valueTable, resourceIndex); calculateModifiedId(); return this; } @Override public byte[] readValueEx(int rResourceId, long voffset, int length, ClusterSupport support) throws DatabaseException { int resourceIndex = getLocalReference(rResourceId); boolean isExternal = resourceTable.isValueEx(valueTable, resourceIndex); if (!isExternal) throw new DatabaseException("ClusterI.readValue supported only for external value. Resource key=" + rResourceId); return support.getValueEx(resourceIndex, getClusterId(), voffset, length); } @Override public boolean isValueEx(int resourceKey) throws DatabaseException { int resourceIndex = getLocalReference(resourceKey); return resourceTable.isValueEx(valueTable, resourceIndex); } @Override public long getValueSizeEx(int rResourceId, ClusterSupport support) throws DatabaseException, ExternalValueException { int resourceIndex = getLocalReference(rResourceId); boolean isExternal = resourceTable.isValueEx(valueTable, resourceIndex); if (!isExternal) throw new ExternalValueException("ClusterI.getValueSizeEx supported only for external value. Resource key=" + rResourceId); return support.getValueSizeEx(resourceIndex, getClusterId()); } @Override public void setValueEx(int rResourceId) throws DatabaseException { int resourceIndex = getLocalReference(rResourceId); resourceTable.setValueEx(valueTable, resourceIndex); } @Override public int createResource(ClusterSupport support) throws DatabaseException { if(proxy) { throw new UnsupportedOperationException(); // ClusterImpl cluster = clusterTable.load2(clusterId, clusterKey); // return cluster.createResource(support); } short resourceIndex = resourceTable.createResource(); calculateModifiedId(); if(DebugPolicy.REPORT_RESOURCE_ID_ALLOCATION) System.out.println("[RID_ALLOCATION]: ClusterSmall[" + clusterId + "] allocates " + resourceIndex); support.createResource(this, resourceIndex, getClusterId()); return ClusterTraits.createResourceKey(clusterKey, resourceIndex); } @Override public boolean hasResource(int resourceKey, ClusterSupport support) { int clusterKey = ClusterTraitsBase.getClusterKeyFromResourceKeyNoThrow(resourceKey); if (this.clusterKey != clusterKey) // foreign resource return false; int resourceIndex; try { resourceIndex = ClusterTraits.getResourceIndexFromResourceKey(resourceKey); } catch (DatabaseException e) { return false; } if (resourceIndex > 0 & resourceIndex <= resourceTable.getTableCount()) return true; else return false; } @Override public int getNumberOfResources(ClusterSupport support) throws DatabaseException { if(proxy) { throw new UnsupportedOperationException(); // ClusterImpl cluster = clusterTable.load2(clusterId, clusterKey); // return cluster.getNumberOfResources(support); } return resourceTable.getUsedSize(); } public int getNumberOfResources() throws IllegalAcornStateException { if(proxy) throw new IllegalAcornStateException("proxy == true for " + clusterId); return resourceTable.getUsedSize(); } @Override public long getUsedSpace() { if(isEmpty()) return 0; long rt = resourceTable.getTableCapacity() * 8 + 8; // (8 = cluster id) long ft = foreignTable.getTableCapacity() * 8; long pt = predicateTable.getTableCapacity() * 4; long ot = objectTable.getTableCapacity() * 4; long ct = completeTable.getTableCapacity() * 4; long vt = valueTable.getTableCapacity() * 1; long cm = clusterMap.getUsedSpace(); return rt + ft + pt + ot + ct + vt + cm; } @Override public boolean isEmpty() { if(resourceTable == null) return true; return resourceTable.getTableCount() == 0; } @Override public void printDebugInfo(String message, ClusterSupport support) throws DatabaseException { throw new DatabaseException("Not implemented!"); } private short getInternalReferenceOrZero2(int resourceKey, ClusterSupport support) throws DatabaseException { int resourceIndex = ClusterTraitsBase.getResourceIndexFromResourceKeyNoThrow(resourceKey); if (!ClusterTraitsBase.isCluster(clusterBits, resourceKey)) { return clusterMap.getForeignReferenceOrZero(resourceKey); } else { return (short)resourceIndex; } } private short getInternalReferenceOrZeroAnd(int resourceKey, ClusterSupport support, byte op) throws DatabaseException { int clusterKey = ClusterTraits.getClusterKeyFromResourceKey(resourceKey); int resourceIndex = ClusterTraits.getResourceIndexFromResourceKey(resourceKey); if (this.clusterKey != clusterKey) { // foreign resource ClusterUID clusterUID = clusterSupport.getClusterUIDByResourceKey(resourceKey); short foreignRef = clusterMap.getForeignReferenceOrZero(resourceKey); support.addStatementIndex(this, resourceKey, clusterUID, op); return foreignRef; } support.addStatementIndex(this, resourceKey, getClusterUID(), op); return (short)resourceIndex; } private final short getLocalReference(int resourceKey) throws DatabaseException { return ClusterTraits.getResourceIndexFromResourceKeyNoThrow(resourceKey); } private final short getLocalReferenceAnd(int resourceKey, ClusterSupport support, byte op) throws DatabaseException { short resourceIndex = getLocalReference(resourceKey); support.addStatementIndex(this, resourceKey, getClusterUID(), op); return resourceIndex; } private short checkResourceKeyIsOursAndGetResourceIndexIf(int resourceKey, ClusterSupport support) throws DatabaseException { int clusterShortId = ClusterTraits.getClusterKeyFromResourceKey(resourceKey); if (this.clusterKey != clusterShortId) return 0; int resourceIndex = ClusterTraits.getResourceIndexFromResourceKey(resourceKey); return (short)resourceIndex; } private short getReferenceOrCreateIfForeign(int resourceKey, ClusterUID clusterUID, ClusterSupport support, byte op) throws DatabaseException { int clusterKey = ClusterTraits.getClusterKeyFromResourceKey(resourceKey); short resourceIndex = (short)ClusterTraits.getResourceIndexFromResourceKey(resourceKey); if (this.clusterKey != clusterKey) { support.addStatementIndex(this, resourceKey, clusterUID, op); short ref = clusterMap.getForeignReferenceOrCreateByResourceKey(resourceKey, clusterUID); return ref; } support.addStatementIndex(this, resourceKey, getClusterUID(), op); return resourceIndex; } private short getReferenceOrCreateIfForeign(int resourceKey, ClusterSupport support, byte op) throws DatabaseException { int clusterKey = ClusterTraits.getClusterKeyFromResourceKey(resourceKey); short resourceIndex = (short)ClusterTraits.getResourceIndexFromResourceKey(resourceKey); if (this.clusterKey != clusterKey) { ClusterUID clusterUID = clusterSupport.getClusterUIDByResourceKey(resourceKey); support.addStatementIndex(this, resourceKey, clusterUID, op); short ref = clusterMap.getForeignReferenceOrCreateByResourceKey(resourceKey, clusterUID); return ref; } support.addStatementIndex(this, resourceKey, getClusterUID(), op); return resourceIndex; } private class ResourceReferenceAndCluster { ResourceReferenceAndCluster(short reference, ClusterUID clusterUID) { this.reference = reference; this.clusterUID = clusterUID; } public final short reference; public final ClusterUID clusterUID; } private ResourceReferenceAndCluster checkResourceKeyAndGetResourceIndexIf(int resourceKey, ClusterSupport support) throws DatabaseException { int clusterKey = ClusterTraits.getClusterKeyFromResourceKey(resourceKey); short resourceIndex = (short)ClusterTraits.getResourceIndexFromResourceKey(resourceKey); if (this.clusterKey != clusterKey) { // foreign resource ClusterI foreignCluster = support.getClusterByClusterKey(clusterKey); ClusterUID clusterUID = foreignCluster.getClusterUID(); short ref = clusterMap.getForeignReferenceOrZero(resourceKey); return new ResourceReferenceAndCluster(ref, clusterUID); } return new ResourceReferenceAndCluster(resourceIndex, getClusterUID()); } static long fTime = 0; @Override final public int execute(int resourceReference) throws DatabaseException { short resourceRef = (short)resourceReference; int key; if (ClusterTraitsSmall.resourceRefIsLocal(resourceRef)) { key = clusterBits | resourceRef; } else { short foreignIndex = ClusterTraitsSmall.resourceRefGetForeignIndex((short)resourceRef); //long start = System.nanoTime(); ResourceUID resourceUID = foreignTable.getResourceUID(foreignIndex); int clusterKey = clusterSupport.getClusterKeyByClusterUIDOrMake(resourceUID.asCID()); // ClusterBase cluster = clusterSupport.getClusterByClusterUIDOrMake(resourceUID.asCID()); key = ClusterTraitsBase.createResourceKey(clusterKey, resourceUID.getIndex()); //fTime += System.nanoTime() - start; //System.err.println("fTime: " + 1e-9*fTime); } if (DEBUG) System.out.println("ClusterSmall.execute key=" + key); return key; } private boolean addRelationInternal(short sReference, short pReference, short oReference, ClusterI.CompleteTypeEnum completeType) throws DatabaseException { int predicateIndex = resourceTable.addStatement(sReference, pReference, oReference, predicateTable, objectTable, completeType, completeTable); if (0 == predicateIndex) return true; // added to resourceTable else if (0 > predicateIndex) return false; // old complete statemenent int newPredicateIndex = predicateTable.addPredicate(predicateIndex, 0xFFFF & pReference, 0xFFFF & oReference, objectTable); if (0 == newPredicateIndex) return false; if (predicateIndex != newPredicateIndex) resourceTable.setPredicateIndex(sReference, newPredicateIndex); return true; } private boolean removeRelationInternal(int sResourceIndex, short pResourceIndex, short oResourceIndex, ClusterI.CompleteTypeEnum completeType, ClusterSupport support) throws DatabaseException { int predicateIndex = resourceTable.getPredicateIndex(sResourceIndex); if (0 == predicateIndex || ClusterI.CompleteTypeEnum.NotComplete != completeType) return resourceTable.removeStatementFromCache(sResourceIndex, pResourceIndex, oResourceIndex, completeType, completeTable); PredicateTable.Status ret = predicateTable.removePredicate(predicateIndex, 0xFFFF & pResourceIndex, 0xFFFF & oResourceIndex, objectTable); switch (ret) { case NothingRemoved: return false; case PredicateRemoved: { if (0 == predicateTable.getPredicateSetSize(predicateIndex)) resourceTable.setPredicateIndex(sResourceIndex, 0); // intentionally dropping to next case } default: break; } resourceTable.removeStatement(sResourceIndex, pResourceIndex, oResourceIndex, completeType, completeTable, predicateTable, objectTable, support); return true; } @Override public void load() { throw new Error("Not supported."); } @Override public void load(Callback r) { throw new Error("Not supported."); } public boolean contains(int resourceKey) { return ClusterTraitsBase.isCluster(clusterBits, resourceKey); } @Override public void load(final ClusterSupport support, final Runnable callback) { throw new UnsupportedOperationException(); // try { // clusterTable.load2(clusterId, clusterKey); // callback.run(); // } catch (DatabaseException e) { // e.printStackTrace(); // } } @Override public ClusterI getClusterByResourceKey(int resourceKey, ClusterSupport support) { throw new Error(); } @Override public void increaseReferenceCount(int amount) { throw new Error(); } @Override public void decreaseReferenceCount(int amount) { throw new Error(); } @Override public int getReferenceCount() { throw new Error(); } @Override public void releaseMemory() { } @Override public void compact() { clusterMap.compact(); } @Override public boolean isLoaded() { return !proxy; } // public ClusterImpl tryLoad(SessionImplSocket sessionImpl) { // // throw new UnsupportedOperationException(); // assert(Constants.ReservedClusterId != clusterId); // // return clusterTable.tryLoad(clusterId, clusterKey); // // } @Override public ClusterBig toBig(ClusterSupport support) throws DatabaseException { if (DEBUG) { System.out.println("DEBUG: toBig cluster=" + clusterId); new Exception().printStackTrace(); } ClusterBig big = new ClusterBig(clusterSupport, getClusterUID(), clusterKey, (ClusterSupport2)support); big.cc = this.cc; // if(big.cc != null) // big.cc.clusterImpl = this; resourceTable.toBig(big, support, this); big.foreignLookup = this.foreignLookup; big.change = this.change; this.cc = null; this.foreignLookup = null; this.change = null; return big; } @Override public ClusterTypeEnum getType() { return ClusterTypeEnum.SMALL; } @Override public boolean getImmutable() { int status = resourceTable.getClusterStatus(); return (status & ClusterStatus.ImmutableMaskSet) == 1; } @Override public void setImmutable(boolean immutable, ClusterSupport support) { if(resourceTable != null) { int status = resourceTable.getClusterStatus(); if (immutable) status |= ClusterStatus.ImmutableMaskSet; else status &= ClusterStatus.ImmutableMaskClear; resourceTable.setClusterStatus(status); } support.setImmutable(this, immutable); } @Override public String toString() { try { final TIntHashSet set = new TIntHashSet(); TIntShortHashMap map = foreignTable.getResourceHashMap(); map.forEachKey(new TIntProcedure() { @Override public boolean execute(int value) { set.add(value & 0xfffff000); return true; } }); return "ClusterSmall[" + getClusterUID() + " - " + getClusterId() + " - " + getNumberOfResources() + " - " + foreignTable.getResourceHashMap().size() + " - " + set.size() + "]"; } catch (DatabaseException e) { try { return "ClusterSmall[" + getNumberOfResources() + "]"; } catch (IllegalAcornStateException e1) { Logger.defaultLogError(e1); e1.printStackTrace(); return "An exception occured!!"; } } } // Memory map // bytes (b) | headers(i) | predicateTable (i) | objectTable (i) | completeTable (i) | resourceTable (l) | foreignTable (l) @Override public byte[] storeBytes() throws IOException { int byteSize = valueTable.getTableSize(); int longSize = LONG_HEADER_SIZE + resourceTable.getTableSize() + foreignTable.getTableSize(); int intSize = INT_HEADER_SIZE + predicateTable.getTableSize() + objectTable.getTableSize() + completeTable.getTableSize(); byte[] raw = new byte[12 + byteSize + 8*longSize + 4*intSize]; int[] currentHeader = Arrays.copyOf(headerTable, INT_HEADER_SIZE); Bytes.writeLE(raw, 0, byteSize); Bytes.writeLE(raw, 4, intSize); Bytes.writeLE(raw, 8, longSize); int rawPos = valueTable.storeBytes(raw, 0, 12); int intBase = rawPos; rawPos += 4*INT_HEADER_SIZE; rawPos = predicateTable.storeBytes(raw, (rawPos-intBase)>>2, rawPos); rawPos = objectTable.storeBytes(raw, (rawPos-intBase)>>2, rawPos); rawPos = completeTable.storeBytes(raw, (rawPos-intBase)>>2, rawPos); int longBase = rawPos; rawPos += 8*LONG_HEADER_SIZE; rawPos = resourceTable.storeBytes(raw, (rawPos-longBase)>>3, rawPos); rawPos = foreignTable.storeBytes(raw, (rawPos-longBase)>>3, rawPos); Bytes.writeLE8(raw, longBase, -1); Bytes.writeLE8(raw, longBase+8, LONG_HEADER_VERSION); Bytes.writeLE8(raw, longBase+16, 0); Bytes.writeLE8(raw, longBase+24, clusterUID.second); // write header for(int i=0;i getPredicateTable() { return predicateTable; } @Override public Table getForeignTable() { return foreignTable; } @Override public int makeResourceKey(int pRef) throws DatabaseException { throw new UnsupportedOperationException(); } @Override public Table getCompleteTable() { return completeTable; } @Override public Table getValueTable() { return valueTable; } @Override public Table getObjectTable() { return objectTable; } } class ClusterStatus { public static final int ImmutableMaskClear = 0xFFFFFFFE; public static final int ImmutableMaskSet = 0x00000001; public static final int DeletedMaskClear = 0xFFFFFFFD; public static final int DeletedMaskSet = 0x00000002; }