]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ClusterBig.java
Fail safe import fixes made by Antti
[simantics/platform.git] / bundles / org.simantics.db.procore / src / org / simantics / db / procore / cluster / ClusterBig.java
index 48f1b27a258cd084fda8ca7939997ba9b7b7babf..0520ec3e67a709b746b208c507e60a320d790dcb 100644 (file)
-/*******************************************************************************\r
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
- * in Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- *     VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.db.procore.cluster;\r
-\r
-import java.io.ByteArrayInputStream;\r
-import java.io.InputStream;\r
-\r
-import org.simantics.db.Resource;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.db.exception.ExternalValueException;\r
-import org.simantics.db.exception.ValidationException;\r
-import org.simantics.db.impl.ClusterI;\r
-import org.simantics.db.impl.ClusterI.PredicateProcedure;\r
-import org.simantics.db.impl.ClusterSupport;\r
-import org.simantics.db.impl.ClusterTraitsBase;\r
-import org.simantics.db.impl.ForEachObjectContextProcedure;\r
-import org.simantics.db.impl.ForEachObjectProcedure;\r
-import org.simantics.db.impl.ForPossibleRelatedValueContextProcedure;\r
-import org.simantics.db.impl.ForPossibleRelatedValueProcedure;\r
-import org.simantics.db.impl.Table;\r
-import org.simantics.db.impl.TableHeader;\r
-import org.simantics.db.impl.graph.ReadGraphImpl;\r
-import org.simantics.db.impl.query.QueryProcessor;\r
-import org.simantics.db.procedure.AsyncContextMultiProcedure;\r
-import org.simantics.db.procedure.AsyncMultiProcedure;\r
-import org.simantics.db.service.ClusterUID;\r
-import org.simantics.utils.datastructures.Callback;\r
-\r
-import fi.vtt.simantics.procore.DebugPolicy;\r
-import fi.vtt.simantics.procore.internal.ClusterChange;\r
-import fi.vtt.simantics.procore.internal.ClusterStream;\r
-import fi.vtt.simantics.procore.internal.SessionImplSocket;\r
-\r
-final public class ClusterBig extends ClusterImpl {\r
-    private static final int TABLE_HEADER_SIZE = TableHeader.HEADER_SIZE + TableHeader.EXTRA_SIZE;\r
-    private static final int RESOURCE_TABLE_OFFSET = 0;\r
-    private static final int PREDICATE_TABLE_OFFSET = RESOURCE_TABLE_OFFSET + TABLE_HEADER_SIZE;\r
-    private static final int OBJECT_TABLE_OFFSET = PREDICATE_TABLE_OFFSET + TABLE_HEADER_SIZE;\r
-    private static final int VALUE_TABLE_OFFSET = OBJECT_TABLE_OFFSET + TABLE_HEADER_SIZE;\r
-    private static final int FLAT_TABLE_OFFSET = VALUE_TABLE_OFFSET + TABLE_HEADER_SIZE;\r
-    private static final int COMPLETE_TABLE_OFFSET = FLAT_TABLE_OFFSET + TABLE_HEADER_SIZE;\r
-    private static final int FOREIGN_TABLE_OFFSET = COMPLETE_TABLE_OFFSET + TABLE_HEADER_SIZE;\r
-    private static final int INT_HEADER_SIZE = FOREIGN_TABLE_OFFSET + TABLE_HEADER_SIZE;\r
-    private final int clusterBits;\r
-    final private ResourceTable resourceTable;\r
-    //final private ResourceTable movedResourceTable;\r
-    final private PredicateTable predicateTable;\r
-    final private ObjectTable objectTable;\r
-    final private ValueTable valueTable;\r
-    final private FlatTable flatTable;\r
-    final private ForeignTable foreignTable;\r
-    final private CompleteTable completeTable;\r
-    final private ClusterMap clusterMap;\r
-    final private int[] headerTable;\r
-    final private ClusterSupport clusterSupport;\r
-    public ClusterBig(ClusterUID clusterUID, int clusterKey, ClusterSupport support) {\r
-        super(clusterUID, clusterKey, support);\r
-        if(DebugPolicy.REPORT_CLUSTER_EVENTS)\r
-            new Exception(getClusterUID().toString()).printStackTrace();\r
-        this.headerTable = new int[INT_HEADER_SIZE];\r
-        this.resourceTable = new ResourceTable(this, headerTable, RESOURCE_TABLE_OFFSET);\r
-        this.foreignTable = new ForeignTable(this, headerTable, FOREIGN_TABLE_OFFSET);\r
-        this.predicateTable = new PredicateTable(this, headerTable, PREDICATE_TABLE_OFFSET);\r
-        this.objectTable = new ObjectTable(this, headerTable, OBJECT_TABLE_OFFSET);\r
-        this.valueTable = new ValueTable(this, headerTable, VALUE_TABLE_OFFSET);\r
-        this.completeTable = new CompleteTable(this, headerTable, COMPLETE_TABLE_OFFSET);\r
-        this.flatTable = null;\r
-        this.clusterMap = new ClusterMap(foreignTable, flatTable);\r
-        this.clusterSupport = support;\r
-        this.clusterBits = ClusterTraitsBase.getClusterBits(clusterKey);\r
-        this.importance = 0;\r
-//        clusterTable.setDirtySizeInBytes(true);\r
-    }\r
-    protected ClusterBig(long[] longs, int[] ints, byte[] bytes, ClusterSupport support, int clusterKey)\r
-    throws DatabaseException {\r
-        super(checkValidity(0, longs, ints, bytes), clusterKey, support);\r
-        if(DebugPolicy.REPORT_CLUSTER_EVENTS)\r
-            new Exception(getClusterUID().toString()).printStackTrace();\r
-        if (ints.length < INT_HEADER_SIZE)\r
-            throw new IllegalArgumentException("Too small integer table for cluster.");\r
-        this.headerTable = ints;\r
-        this.resourceTable = new ResourceTable(this, ints, RESOURCE_TABLE_OFFSET, longs);\r
-        this.foreignTable = new ForeignTable(this, headerTable, FOREIGN_TABLE_OFFSET, longs);\r
-        this.predicateTable = new PredicateTable(this, ints, PREDICATE_TABLE_OFFSET, ints);\r
-        this.objectTable = new ObjectTable(this, ints, OBJECT_TABLE_OFFSET, ints);\r
-        this.valueTable = new ValueTable(this, ints, VALUE_TABLE_OFFSET, bytes);\r
-        this.flatTable = null;\r
-        this.completeTable = new CompleteTable(this, headerTable, COMPLETE_TABLE_OFFSET, ints);\r
-        this.clusterMap = new ClusterMap(foreignTable, flatTable);\r
-        this.clusterSupport = support;\r
-        this.clusterBits = ClusterTraitsBase.getClusterBits(clusterKey);\r
-        this.importance = clusterTable.timeCounter();\r
-        clusterTable.markImmutable(this, getImmutable());\r
-    }\r
-    void analyse() {\r
-        System.out.println("Cluster " + clusterId);\r
-        System.out.println("-size:" + getUsedSpace());\r
-        System.out.println(" -rt:" + (resourceTable.getTableCapacity() * 8 + 8));\r
-        System.out.println(" -ft:" + foreignTable.getTableCapacity() * 8);\r
-        System.out.println(" -pt:" + predicateTable.getTableCapacity() * 4);\r
-        System.out.println(" -ot:" + objectTable.getTableCapacity() * 4);\r
-        System.out.println(" -ct:" + completeTable.getTableCapacity() * 4);\r
-        System.out.println(" -vt:" + valueTable.getTableCapacity());\r
-\r
-        System.out.println("-resourceTable:");\r
-        System.out.println(" -resourceCount=" + resourceTable.getResourceCount());\r
-        System.out.println(" -size=" + resourceTable.getTableSize());\r
-        System.out.println(" -capacity=" + resourceTable.getTableCapacity());\r
-        System.out.println(" -count=" + resourceTable.getTableCount());\r
-        System.out.println(" -size=" + resourceTable.getTableSize());\r
-        //resourceTable.analyse();\r
-    }\r
-    public void checkDirectReference(int dr)\r
-    throws DatabaseException {\r
-        if (!ClusterTraits.statementIndexIsDirect(dr))\r
-            throw new ValidationException("Reference is not direct. Reference=" + dr);\r
-        if (ClusterTraits.isFlat(dr))\r
-            throw new ValidationException("Reference is flat. Reference=" + dr);\r
-        if (ClusterTraits.isLocal(dr)) {\r
-            if (dr < 1 || dr > resourceTable.getUsedSize())\r
-                throw new ValidationException("Illegal local reference. Reference=" + dr);\r
-        } else {\r
-            int fi = ClusterTraits.getForeignIndexFromReference(dr);\r
-            int ri = ClusterTraits.getResourceIndexFromForeignReference(dr);\r
-            if (fi < 1 || fi > foreignTable.getUsedSize())\r
-                throw new ValidationException("Illegal foreign reference. Reference=" + dr + " foreign index=" + fi);\r
-            if (ri < 1 || ri > ClusterTraits.getMaxNumberOfResources())\r
-                throw new ValidationException("Illegal foreign reference. Reference=" + dr + " resource index=" + ri);\r
-        }\r
-    }\r
-    public void checkPredicateIndex(int pi)\r
-    throws DatabaseException {\r
-        predicateTable.checkPredicateSetIndex(this, pi);\r
-    }\r
-    public void checkObjectSetReference(int or)\r
-    throws DatabaseException {\r
-        if (ClusterTraits.statementIndexIsDirect(or))\r
-            throw new ValidationException("Illegal object set reference. Reference=" + or);\r
-        int oi = ClusterTraits.statementIndexGet(or);\r
-        this.objectTable.checkObjectSetIndex(this, oi);\r
-    }\r
-\r
-    public void checkValueInit()\r
-    throws DatabaseException {\r
-        valueTable.checkValueInit();\r
-    }\r
-    public void checkValue(int capacity, int index)\r
-    throws DatabaseException {\r
-        valueTable.checkValue(capacity, index);\r
-    }\r
-    public void checkValueFini()\r
-    throws DatabaseException {\r
-        valueTable.checkValueFini();\r
-    }\r
-    public void checkForeingIndex(int fi)\r
-    throws DatabaseException {\r
-        if (fi<1 || fi > foreignTable.getUsedSize())\r
-            throw new ValidationException("Illegal foreign index=" + fi);\r
-    }\r
-    public void checkCompleteSetReference(int cr)\r
-    throws DatabaseException {\r
-        if (!ClusterTraits.completeReferenceIsMultiple(cr))\r
-            throw new ValidationException("Illegal complete set reference. Reference=" + cr);\r
-        int ci = cr;\r
-        this.completeTable.checkCompleteSetIndex(this, ci);\r
-    }\r
-    public void check()\r
-    throws DatabaseException {\r
-        this.completeTable.check(this);\r
-        this.objectTable.check(this);\r
-        // Must be after object table check.\r
-        this.predicateTable.check(this);\r
-        this.resourceTable.check(this);\r
-    }\r
-    @Override\r
-    public CompleteTypeEnum getCompleteType(int resourceKey, ClusterSupport support)\r
-    throws DatabaseException {\r
-        final int resourceRef = getLocalReference(resourceKey);\r
-        int completeRef = resourceTable.getCompleteObjectRef(resourceRef);\r
-        CompleteTypeEnum ct = ClusterTraits.completeReferenceGetType(completeRef);\r
-        if (DEBUG)\r
-            System.out.println("Cluster.getCompleteType rk=" + resourceKey + " ct=" + ct);\r
-        int i = ct.getValue();\r
-        switch (i) {\r
-            case 0: return CompleteTypeEnum.NotComplete;\r
-            case 1: return CompleteTypeEnum.InstanceOf;\r
-            case 2: return CompleteTypeEnum.Inherits;\r
-            case 3: return CompleteTypeEnum.SubrelationOf;\r
-            default: throw new DatabaseException("Illegal complete type enumeration.");\r
-        }\r
-    }\r
-\r
-    @Override\r
-    public int getCompleteObjectKey(int resourceKey, ClusterSupport support)\r
-    throws DatabaseException {\r
-        final int resourceRef = getLocalReference(resourceKey);\r
-        int completeRef = resourceTable.getCompleteObjectRef(resourceRef);\r
-        int clusterIndex;\r
-        int resourceIndex = ClusterTraits.completeReferenceGetResourceIndex(completeRef);\r
-\r
-        ClusterI.CompleteTypeEnum completeType = ClusterTraits.completeReferenceGetType(completeRef);\r
-        if (completeType == ClusterI.CompleteTypeEnum.NotComplete)\r
-            throw new DatabaseException("Resource has multiple complete objects. Resource key=" + resourceKey + ".");\r
-\r
-        if (ClusterTraits.completeReferenceIsLocal(completeRef)) {\r
-            clusterIndex = clusterKey;\r
-        } else {\r
-            int foreignIndex = ClusterTraits.completeReferenceGetForeignIndex(completeRef);\r
-//            System.err.println("completeRef=" + completeRef + " foreignIndex=" + foreignIndex );\r
-            ClusterUID clusterUID = foreignTable.getResourceUID(foreignIndex).asCID();\r
-            ClusterI c = support.getClusterByClusterUIDOrMake(clusterUID);\r
-            clusterIndex = c.getClusterKey();\r
-        }\r
-        int key = ClusterTraits.createResourceKey(clusterIndex, resourceIndex);\r
-        if (DEBUG)\r
-            System.out.println("Cluster.complete object rk=" + resourceKey + " ck=" + key);\r
-        return key;\r
-    }\r
-\r
-    @Override\r
-    public boolean isComplete(int resourceKey, ClusterSupport support)\r
-    throws DatabaseException {\r
-        final int resourceRef = getLocalReference(resourceKey);\r
-        int completeRef = resourceTable.getCompleteObjectRef(resourceRef);\r
-        ClusterI.CompleteTypeEnum completeType = ClusterTraits.completeReferenceGetType(completeRef);\r
-        boolean complete = completeType != ClusterI.CompleteTypeEnum.NotComplete;\r
-        if (DEBUG)\r
-            System.out.println("Cluster.key=" + resourceKey + " isComplete=" + complete);\r
-        return complete;\r
-    }\r
-\r
-    public int getSingleObject(int resourceKey, int predicateKey, int objectIndex, ClusterSupport support) throws DatabaseException {\r
-        if (DEBUG)\r
-            System.out.println("Cluster.getSingleObject: rk=" + resourceKey + " pk=" + predicateKey);\r
-        if (0 == objectIndex) {\r
-            final int resourceIndex = getLocalReference(resourceKey);\r
-            final int pRef = getInternalReferenceOrZero(predicateKey, support);\r
-            final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey);\r
-            return resourceTable.getSingleObject(resourceIndex, support, pRef, pCompleteType, completeTable, this);\r
-        }\r
-        return objectTable.getSingleObject(objectIndex, support, this);\r
-    }\r
-\r
-    public void forObjects(int resourceKey, int predicateKey, int objectIndex, QueryProcessor processor, ReadGraphImpl graph, AsyncMultiProcedure<Resource> procedure,\r
-            ClusterSupport support) throws DatabaseException {\r
-        if (DEBUG)\r
-            System.out.println("Cluster.forObjects1: rk=" + resourceKey + " pk=" + predicateKey);\r
-        if (0 == objectIndex) {\r
-            final int resourceIndex = getLocalReference(resourceKey);\r
-            final int pRef = getInternalReferenceOrZero(predicateKey, support);\r
-            final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey);\r
-            resourceTable.foreachObject(resourceIndex, graph, procedure, support, pRef, pCompleteType, completeTable, this);\r
-            return;\r
-        }\r
-        objectTable.foreachObject(graph, objectIndex, procedure, this);\r
-    }\r
-    public <C> void forObjects(int resourceKey, int predicateKey, int objectIndex, QueryProcessor processor, ReadGraphImpl graph, C context, AsyncContextMultiProcedure<C, Resource> procedure,\r
-            ClusterSupport support) throws DatabaseException {\r
-        if (DEBUG)\r
-            System.out.println("Cluster.forObjects1: rk=" + resourceKey + " pk=" + predicateKey);\r
-        if (0 == objectIndex) {\r
-            final int resourceIndex = getLocalReference(resourceKey);\r
-            final int pRef = getInternalReferenceOrZero(predicateKey, support);\r
-            final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey);\r
-            resourceTable.foreachObject(resourceIndex, graph, context, procedure, support, pRef, pCompleteType, completeTable, this);\r
-            return;\r
-        }\r
-        objectTable.foreachObject(graph, objectIndex, context, procedure, this);\r
-    }\r
-    @Override\r
-    public <Context> boolean forObjects(int resourceKey, int predicateKey, int objectIndex, ObjectProcedure<Context> procedure,\r
-            Context context, ClusterSupport support) throws DatabaseException {\r
-        if (DEBUG)\r
-            System.out.println("Cluster.forObjects2: rk=" + resourceKey + " pk=" + predicateKey);\r
-        if (0 == objectIndex) {\r
-            final int resourceIndex = getLocalReference(resourceKey);\r
-            final int pRef = getInternalReferenceOrZero(predicateKey, support);\r
-            final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey);\r
-            return resourceTable.foreachObject(resourceIndex, procedure, context, support, this, pRef, pCompleteType, completeTable);\r
-        }\r
-        return objectTable.foreachObject(objectIndex, procedure, context, support, this);\r
-    }\r
-\r
-    @Override\r
-    public int getSingleObject(int resourceKey, int predicateKey, ClusterSupport support) throws DatabaseException {\r
-        if (DEBUG)\r
-            System.out.println("Cluster.getSingleObject2: rk=" + resourceKey + " pk=" + predicateKey);\r
-        final int resourceIndex = getLocalReference(resourceKey);\r
-        final int pRef = getInternalReferenceOrZero(predicateKey, support);\r
-        final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey);\r
-        if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType)\r
-            return resourceTable.getSingleObject(resourceIndex, support, pRef, pCompleteType, completeTable, this);\r
-        final int predicateIndex = resourceTable.getPredicateIndex(resourceIndex);\r
-        if (0 == predicateIndex)\r
-            return resourceTable.getSingleObject(resourceIndex, support, pRef, pCompleteType, completeTable, this);\r
-        int objectIndex = predicateTable.getObjectIndex(predicateIndex, pRef);\r
-        return getSingleObject(resourceKey, predicateKey, objectIndex, support);\r
-    }\r
-\r
-    @Override\r
-    public <T> int getSingleObject(int resourceKey, ForPossibleRelatedValueProcedure<T> procedure, ClusterSupport support) throws DatabaseException {\r
-        final int predicateKey = procedure.predicateKey;\r
-        if (DEBUG)\r
-            System.out.println("Cluster.getSingleObject2: rk=" + resourceKey + " pk=" + predicateKey);\r
-        final int resourceIndex = getLocalReference(resourceKey);\r
-        final int pRef = getInternalReferenceOrZero(predicateKey, support);\r
-        final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey);\r
-        if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType)\r
-            return resourceTable.getSingleObject(resourceIndex, support, pRef, pCompleteType, completeTable, this);\r
-        final int predicateIndex = resourceTable.getPredicateIndex(resourceIndex);\r
-        if (0 == predicateIndex)\r
-            return resourceTable.getSingleObject(resourceIndex, support, pRef, pCompleteType, completeTable, this);\r
-        int objectIndex = predicateTable.getObjectIndex(predicateIndex, pRef);\r
-        return getSingleObject(resourceKey, predicateKey, objectIndex, support);\r
-    }\r
-\r
-    @Override\r
-    public <C, T> int getSingleObject(int resourceKey, ForPossibleRelatedValueContextProcedure<C, T> procedure, ClusterSupport support) throws DatabaseException {\r
-        final int predicateKey = procedure.predicateKey;\r
-        if (DEBUG)\r
-            System.out.println("Cluster.getSingleObject2: rk=" + resourceKey + " pk=" + predicateKey);\r
-        final int resourceIndex = getLocalReference(resourceKey);\r
-        final int pRef = getInternalReferenceOrZero(predicateKey, support);\r
-        final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey);\r
-        if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType)\r
-            return resourceTable.getSingleObject(resourceIndex, support, pRef, pCompleteType, completeTable, this);\r
-        final int predicateIndex = resourceTable.getPredicateIndex(resourceIndex);\r
-        if (0 == predicateIndex)\r
-            return resourceTable.getSingleObject(resourceIndex, support, pRef, pCompleteType, completeTable, this);\r
-        int objectIndex = predicateTable.getObjectIndex(predicateIndex, pRef);\r
-        return getSingleObject(resourceKey, predicateKey, objectIndex, support);\r
-    }\r
-\r
-    @Override\r
-    public void forObjects(ReadGraphImpl graph, int resourceKey,\r
-            int predicateKey, AsyncMultiProcedure<Resource> procedure)\r
-            throws DatabaseException {\r
-\r
-        SessionImplSocket session = (SessionImplSocket)graph.getSession();\r
-        ClusterSupport support = session.clusterTranslator;\r
-\r
-        if (DEBUG)\r
-            System.out.println("Cluster.forObjects3: rk=" + resourceKey + " pk=" + predicateKey);\r
-        final int resourceIndex = getLocalReference(resourceKey);\r
-        final int pRef = getInternalReferenceOrZero(predicateKey, support);\r
-        final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey);\r
-        if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType) {\r
-            resourceTable.foreachObject(resourceIndex, graph, procedure, support, pRef, pCompleteType, completeTable, this);\r
-            return;\r
-        }\r
-        final int predicateIndex = resourceTable.getPredicateIndex(resourceIndex);\r
-        if (0 == predicateIndex) {\r
-            resourceTable.foreachObject(resourceIndex, graph, procedure, support, pRef, pCompleteType, completeTable, this);\r
-            return;\r
-        }\r
-        int objectIndex = predicateTable.getObjectIndex(predicateIndex, pRef);\r
-        forObjects(resourceKey, predicateKey, objectIndex, graph.processor, graph, procedure, support);\r
-\r
-    }\r
-\r
-    @Override\r
-    public void forObjects(ReadGraphImpl graph, int resourceKey, ForEachObjectProcedure procedure) throws DatabaseException {\r
-        SessionImplSocket session = (SessionImplSocket)graph.getSession();\r
-        ClusterSupport support = session.clusterTranslator;\r
-        final int predicateKey = procedure.predicateKey;\r
-        if (DEBUG)\r
-            System.out.println("Cluster.forObjects3: rk=" + resourceKey + " pk=" + predicateKey);\r
-        final int resourceIndex = getLocalReference(resourceKey);\r
-        final int pRef = getInternalReferenceOrZero(predicateKey, support);\r
-        final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey);\r
-        if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType) {\r
-            resourceTable.foreachObject(resourceIndex, graph, procedure, support, pRef, pCompleteType, completeTable, this);\r
-            return;\r
-        }\r
-        final int predicateIndex = resourceTable.getPredicateIndex(resourceIndex);\r
-        if (0 == predicateIndex) {\r
-            resourceTable.foreachObject(resourceIndex, graph, procedure, support, pRef, pCompleteType, completeTable, this);\r
-            return;\r
-        }\r
-        int objectIndex = predicateTable.getObjectIndex(predicateIndex, pRef);\r
-        forObjects(resourceKey, predicateKey, objectIndex, graph.processor, graph, procedure, support);\r
-\r
-    }\r
-    @Override\r
-    public <C> void forObjects(ReadGraphImpl graph, int resourceKey, C context,\r
-            ForEachObjectContextProcedure<C> procedure) throws DatabaseException {\r
-\r
-        SessionImplSocket session = (SessionImplSocket)graph.getSession();\r
-        ClusterSupport support = session.clusterTranslator;\r
-\r
-        final int predicateKey = procedure.predicateKey;\r
-\r
-        if (DEBUG)\r
-            System.out.println("Cluster.forObjects3: rk=" + resourceKey + " pk=" + predicateKey);\r
-        final int resourceIndex = getLocalReference(resourceKey);\r
-        final int pRef = getInternalReferenceOrZero(predicateKey, support);\r
-        final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey);\r
-        if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType) {\r
-            resourceTable.foreachObject(resourceIndex, graph, context, procedure, support, pRef, pCompleteType, completeTable, this);\r
-            return;\r
-        }\r
-        final int predicateIndex = resourceTable.getPredicateIndex(resourceIndex);\r
-        if (0 == predicateIndex) {\r
-            resourceTable.foreachObject(resourceIndex, graph, context, procedure, support, pRef, pCompleteType, completeTable, this);\r
-            return;\r
-        }\r
-        int objectIndex = predicateTable.getObjectIndex(predicateIndex, pRef);\r
-        forObjects(resourceKey, predicateKey, objectIndex, graph.processor, graph, context, procedure, support);\r
-\r
-    }\r
-\r
-    @Override\r
-    public <Context> boolean forObjects(int resourceKey, int predicateKey,\r
-            ObjectProcedure<Context> procedure, Context context, ClusterSupport support)\r
-    throws DatabaseException {\r
-        if (DEBUG)\r
-            System.out.println("Cluster.forObjects4: rk=" + resourceKey + " pk=" + predicateKey);\r
-        final int resourceIndex = getLocalReference(resourceKey);\r
-        final int pRef = getInternalReferenceOrZero(predicateKey, support);\r
-        final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey);\r
-        if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType)\r
-            return resourceTable.foreachObject(resourceIndex, procedure, context, support, this, pRef, pCompleteType, completeTable);\r
-        final int predicateIndex = resourceTable.getPredicateIndex(resourceIndex);\r
-        if (0 == predicateIndex)\r
-            return resourceTable.foreachObject(resourceIndex, procedure, context, support, this, pRef, pCompleteType, completeTable);\r
-        int objectIndex = predicateTable.getObjectIndex(predicateIndex, pRef);\r
-        return forObjects(resourceKey, predicateKey, objectIndex, procedure, context, support);\r
-    }\r
-    @Override\r
-    public <Context> boolean forPredicates(int resourceKey,\r
-            PredicateProcedure<Context> procedure, Context context, ClusterSupport support)\r
-    throws DatabaseException {\r
-        if (DEBUG)\r
-            System.out.println("Cluster.forPredicates: rk=" + resourceKey);\r
-        final int resourceIndex = getLocalReference(resourceKey);\r
-        final int predicateIndex = resourceTable.getPredicateIndex(resourceIndex);\r
-        if (0 == predicateIndex)\r
-            return resourceTable.foreachPredicate(resourceIndex,\r
-                    procedure, context, support, this, completeTable);\r
-        else {\r
-            boolean broken = resourceTable.foreachPredicate(resourceIndex,\r
-                    procedure, context, support, this, completeTable);\r
-            if (broken)\r
-                return true;\r
-        }\r
-        return predicateTable.foreachPredicate(predicateIndex, procedure, context, support, this);\r
-    }\r
-    @Override\r
-    public ClusterI addRelation(int sResourceKey, int pResourceKey, int oResourceKey, ClusterSupport support)\r
-    throws DatabaseException {\r
-        if (DEBUG)\r
-            System.out.println("add rk=" + sResourceKey + " pk=" + pResourceKey + " ok=" + oResourceKey);\r
-        int sri = getLocalReferenceAnd(sResourceKey, support, ClusterChange.ADD_OPERATION);\r
-        int pri = getReferenceOrCreateIfForeign(pResourceKey, support, ClusterStream.NULL_OPERATION);\r
-        int ori = getReferenceOrCreateIfForeign(oResourceKey, support, ClusterStream.NULL_OPERATION);\r
-        ClusterI.CompleteTypeEnum completeType = ClusterTraitsBase.getCompleteTypeFromResourceKey(pResourceKey);\r
-        boolean ret = addRelationInternal(sri, pri, ori, completeType);\r
-//      check();\r
-        if (ret) {\r
-            support.addStatement(this);\r
-            return this;\r
-        } else {\r
-            support.cancelStatement(this);\r
-            return null;\r
-        }\r
-    }\r
-    @Override\r
-    public boolean removeRelation(int sResourceKey, int pResourceKey, int oResourceKey, ClusterSupport support)\r
-    throws DatabaseException {\r
-//        check();\r
-        int sri = getLocalReferenceAnd(sResourceKey, support, ClusterChange.REMOVE_OPERATION);\r
-        int pri = getInternalReferenceOrZeroAnd(pResourceKey, support, ClusterStream.NULL_OPERATION);\r
-        int ori = getInternalReferenceOrZeroAnd(oResourceKey, support, ClusterStream.NULL_OPERATION);\r
-        boolean ret = false;\r
-        if (0 != pri && 0 != ori) {\r
-            ClusterI.CompleteTypeEnum completeType = ClusterTraitsBase.getCompleteTypeFromResourceKey(pResourceKey);\r
-            ret = removeRelationInternal(sri, pri, ori, completeType, support);\r
-        }\r
-        if (ret)\r
-            support.removeStatement(this);\r
-        else\r
-            support.cancelStatement(this);\r
-//        check();\r
-        return ret;\r
-    }\r
-    @Override\r
-    public void denyRelation(int sResourceKey, int pResourceKey, int oResourceKey, ClusterSupport support)\r
-    throws DatabaseException {\r
-        int sri = checkResourceKeyIsOursAndGetResourceIndexIf(sResourceKey, support);\r
-        ResourceIndexAndId p = checkResourceKeyAndGetResourceIndexIf(pResourceKey, support);\r
-        ResourceIndexAndId o = checkResourceKeyAndGetResourceIndexIf(oResourceKey, support);\r
-        if (0 == sri || 0 == p.index || 0 == o.index)\r
-            return;\r
-//        check();\r
-        ClusterI.CompleteTypeEnum completeType = ClusterTraitsBase.getCompleteTypeFromResourceKey(pResourceKey);\r
-        boolean ret = removeRelationInternal(sri, p.reference, o.reference, completeType, support);\r
-        if (ret) {\r
-            support.addStatementIndex(this, sResourceKey, getClusterUID(), ClusterChange.REMOVE_OPERATION);\r
-            support.addStatementIndex(this, pResourceKey, p.clusterUID, ClusterStream.NULL_OPERATION);\r
-            support.addStatementIndex(this, oResourceKey, o.clusterUID, ClusterStream.NULL_OPERATION);\r
-            support.removeStatement(this);\r
-        }\r
-//        check();\r
-        return;\r
-    }\r
-    @Override\r
-    public InputStream getValueStream(int rResourceId, ClusterSupport support) throws DatabaseException {\r
-        if (DEBUG)\r
-            System.out.println("ClusterBig.getValue " + rResourceId);\r
-        int resourceIndex = getLocalReference(rResourceId);\r
-        try {\r
-            byte[] buffer = resourceTable.getValue(valueTable, resourceIndex);\r
-            if(buffer == null) return null;\r
-            return new ByteArrayInputStream(buffer);\r
-        } catch (ExternalValueException e) {\r
-            return support.getValueStreamEx(resourceIndex, clusterId);\r
-        }\r
-    }\r
-    @Override\r
-    public byte[] getValue(int rResourceId, ClusterSupport support)\r
-    throws DatabaseException {\r
-        if (DEBUG)\r
-            System.out.println("ClusterBig.getValue " + rResourceId);\r
-        int resourceIndex = getLocalReference(rResourceId);\r
-        try {\r
-            return resourceTable.getValue(valueTable, resourceIndex);\r
-        } catch (ExternalValueException e) {\r
-            return support.getValueEx(resourceIndex, clusterId);\r
-        }\r
-    }\r
-    @Override\r
-    public boolean hasValue(int rResourceId, ClusterSupport support)\r
-    throws DatabaseException {\r
-        int resourceIndex = getLocalReference(rResourceId);\r
-        return resourceTable.hasValue(resourceIndex);\r
-    }\r
-    @Override\r
-    public boolean removeValue(int rResourceId, ClusterSupport support)\r
-    throws DatabaseException {\r
-        int resourceIndex = getLocalReferenceAnd(rResourceId, support, ClusterChange.DELETE_OPERATION);\r
-        support.removeValue(this);\r
-        return resourceTable.removeValue(valueTable, resourceIndex);\r
-    }\r
-\r
-    @Override\r
-    public ClusterI setValue(int rResourceId, byte[] value, int length, ClusterSupport support)\r
-    throws DatabaseException {\r
-        int resourceIndex = getLocalReferenceAnd(rResourceId, support, ClusterStream.SET_OPERATION);\r
-        support.setValue(this, getClusterId(), value, length);\r
-        resourceTable.setValue(valueTable, resourceIndex, value, length);\r
-        return this;\r
-    }\r
-    @Override\r
-    public ClusterI modiValueEx(int rResourceId, long voffset, int length, byte[] value, int offset, ClusterSupport support)\r
-    throws DatabaseException {\r
-        int resourceIndex = getLocalReferenceAnd(rResourceId, support, ClusterStream.MODI_OPERATION);\r
-        support.modiValue(this, getClusterId(), voffset, length, value, offset);\r
-        resourceTable.setValueEx(valueTable, resourceIndex);\r
-        return this;\r
-    }\r
-    @Override\r
-    public byte[] readValueEx(int rResourceId, long voffset, int length, ClusterSupport support)\r
-    throws DatabaseException {\r
-        int resourceIndex = getLocalReference(rResourceId);\r
-        boolean isExternal = resourceTable.isValueEx(valueTable, resourceIndex);\r
-        if (!isExternal)\r
-            throw new DatabaseException("ClusterI.readValue supported only for external value. Resource key=" + rResourceId);\r
-        return support.getValueEx(resourceIndex, getClusterId(), voffset, length);\r
-    }\r
-    @Override\r
-    public long getValueSizeEx(int resourceKey, ClusterSupport support)\r
-    throws DatabaseException, ExternalValueException {\r
-        int resourceIndex = getLocalReference(resourceKey);\r
-        boolean isExternal = resourceTable.isValueEx(valueTable, resourceIndex);\r
-        if (!isExternal)\r
-            throw new ExternalValueException("ClusterI.getSize supported only for external value. Resource key=" + resourceKey);\r
-        return support.getValueSizeEx(resourceIndex, getClusterId());\r
-    }\r
-    public boolean isValueEx(int resourceKey)\r
-    throws DatabaseException {\r
-        int resourceIndex = getLocalReference(resourceKey);\r
-        return resourceTable.isValueEx(valueTable, resourceIndex);\r
-    }\r
-    @Override\r
-    public void setValueEx(int resourceKey)\r
-    throws DatabaseException {\r
-        int resourceIndex = getLocalReference(resourceKey);\r
-        resourceTable.setValueEx(valueTable, resourceIndex);\r
-    }\r
-    @Override\r
-    public int createResource(ClusterSupport support)\r
-    throws DatabaseException {\r
-        short resourceIndex = resourceTable.createResource();\r
-\r
-        if(DebugPolicy.REPORT_RESOURCE_ID_ALLOCATION)\r
-            System.out.println("[RID_ALLOCATION]: ClusterBig[" + clusterId + "] allocates " + resourceIndex);\r
-\r
-        support.createResource(this, resourceIndex, clusterId);\r
-        return ClusterTraits.createResourceKey(clusterKey, resourceIndex);\r
-    }\r
-    @Override\r
-    public boolean hasResource(int resourceKey, ClusterSupport support) {\r
-        int clusterKey = ClusterTraitsBase.getClusterKeyFromResourceKeyNoThrow(resourceKey);\r
-        if (this.clusterKey != clusterKey) // foreign resource\r
-            return false;\r
-        int resourceIndex;\r
-        try {\r
-            resourceIndex = ClusterTraits.getResourceIndexFromResourceKey(resourceKey);\r
-        } catch (DatabaseException e) {\r
-            return false;\r
-        }\r
-        if (resourceIndex > 0 & resourceIndex <= resourceTable.getTableCount())\r
-            return true;\r
-        else\r
-            return false;\r
-    }\r
-    @Override\r
-    public int getNumberOfResources(ClusterSupport support) {\r
-        return resourceTable.getUsedSize();\r
-    }\r
-    @Override\r
-    public long getUsedSpace() {\r
-        long rt = resourceTable.getTableCapacity() * 8 + 8; // (8 = cluster id)\r
-        long ft = foreignTable.getTableCapacity() * 8;\r
-        long pt = predicateTable.getTableCapacity() * 4;\r
-        long ot = objectTable.getTableCapacity() * 4;\r
-        long ct = completeTable.getTableCapacity() * 4;\r
-        long vt = valueTable.getTableCapacity() * 1;\r
-        long cm = clusterMap.getUsedSpace();\r
-\r
-        return rt + ft + pt + ot + ct + vt + cm;\r
-//        System.out.println("resource table " + rt);\r
-//        System.out.println("foreign table (non flat cluster table) " + ft);\r
-//        System.out.println("predicate table " + pt);\r
-//        long pt2 = getRealSizeOfPredicateTable() * 4;\r
-//        System.out.println("predicate table real size " + pt2);\r
-//        System.out.println("object table " + ot);\r
-//        long ot2 = getRealSizeOfObjectTable() * 4;\r
-//        System.out.println("object table real size " + ot2);\r
-//        System.out.println("value table " + vt);\r
-    }\r
-    int getRealSizeOfPredicateTable() throws DatabaseException {\r
-        SizeOfPredicateTable proc = new SizeOfPredicateTable(resourceTable, predicateTable);\r
-        resourceTable.foreachResource(proc, 0, null, null);\r
-        return proc.getSize();\r
-    }\r
-    int getRealSizeOfObjectTable() throws DatabaseException {\r
-        SizeOfObjectTable proc = new SizeOfObjectTable(resourceTable, predicateTable, objectTable);\r
-        resourceTable.foreachResource(proc, 0, null, null);\r
-        return proc.getSize();\r
-    }\r
-    @Override\r
-    public boolean isEmpty() {\r
-        return resourceTable.getTableCount() == 0;\r
-    }\r
-    @Override\r
-    public void printDebugInfo(String message, ClusterSupport support)\r
-    throws DatabaseException {\r
-        predicateTable.printDebugInfo();\r
-        objectTable.printDebugInfo();\r
-        ClusterPrintDebugInfo proc = new ClusterPrintDebugInfo(this\r
-                , resourceTable, predicateTable, support, objectTable);\r
-        resourceTable.foreachResource(proc, 0, null, null);\r
-    }\r
-    private int getInternalReferenceOrZero(int resourceKey, ClusterSupport support)\r
-    throws DatabaseException {\r
-        int clusterKey = ClusterTraits.getClusterKeyFromResourceKey(resourceKey);\r
-        int resourceIndex = ClusterTraits.getResourceIndexFromResourceKey(resourceKey);\r
-        if (this.clusterKey != clusterKey) { // foreign resource\r
-            ClusterI foreignCluster = support.getClusterByClusterKey(clusterKey);\r
-            ClusterUID clusterUID = foreignCluster.getClusterUID();\r
-            int foreignResourceIndex = clusterMap.getForeignReferenceOrZero(resourceIndex, clusterUID);\r
-            return foreignResourceIndex;\r
-        }\r
-        return resourceIndex;\r
-    }\r
-    private int getInternalReferenceOrZeroAnd(int resourceKey, ClusterSupport support, byte op)\r
-    throws DatabaseException {\r
-        int clusterKey = ClusterTraits.getClusterKeyFromResourceKey(resourceKey);\r
-        int resourceIndex = ClusterTraits.getResourceIndexFromResourceKey(resourceKey);\r
-        if (this.clusterKey != clusterKey) { // foreign resource\r
-            ClusterI foreignCluster = support.getClusterByClusterKey(clusterKey);\r
-            ClusterUID clusterUID = foreignCluster.getClusterUID();\r
-            int foreignResourceIndex = clusterMap.getForeignReferenceOrZero(resourceIndex, clusterUID);\r
-            support.addStatementIndex(this, resourceKey, clusterUID, op);\r
-            return foreignResourceIndex;\r
-        }\r
-        support.addStatementIndex(this, resourceKey, getClusterUID(), op);\r
-        return resourceIndex;\r
-    }\r
-    private short getLocalReference(int resourceKey) throws DatabaseException {\r
-        return ClusterTraitsBase.getResourceIndexFromResourceKeyNoThrow(resourceKey);\r
-    }\r
-    private int getLocalReferenceAnd(int resourceKey, ClusterSupport support, byte op)\r
-    throws DatabaseException {\r
-        int resourceIndex = getLocalReference(resourceKey);\r
-        support.addStatementIndex(this, resourceKey, getClusterUID(), op);\r
-        return resourceIndex;\r
-    }\r
-    private int checkResourceKeyIsOursAndGetResourceIndexIf(int resourceKey, ClusterSupport support)\r
-    throws DatabaseException {\r
-        int clusterShortId = ClusterTraits.getClusterKeyFromResourceKey(resourceKey);\r
-        if (this.clusterKey != clusterShortId)\r
-            return 0;\r
-        int resourceIndex = ClusterTraits.getResourceIndexFromResourceKey(resourceKey);\r
-        return resourceIndex;\r
-    }\r
-    private int getReferenceOrCreateIfForeign(int resourceKey, ClusterSupport support, byte op)\r
-    throws DatabaseException {\r
-        int clusterKey = ClusterTraits.getClusterKeyFromResourceKey(resourceKey);\r
-        int resourceIndex = ClusterTraits.getResourceIndexFromResourceKey(resourceKey);\r
-        if (this.clusterKey != clusterKey) {\r
-            ClusterI foreignCluster = support.getClusterByClusterKey(clusterKey);\r
-            ClusterUID clusterUID = foreignCluster.getClusterUID();\r
-            support.addStatementIndex(this, resourceKey, clusterUID, op);\r
-            return clusterMap.getForeignReferenceOrCreateByResourceKey(resourceKey, clusterUID);\r
-        }\r
-        support.addStatementIndex(this, resourceKey, getClusterUID(), op);\r
-        return resourceIndex;\r
-    }\r
-    private class ResourceIndexAndId {\r
-        ResourceIndexAndId(int reference, int index, ClusterUID clusterUID) {\r
-            this.reference = reference;\r
-            this.index = index;\r
-            this.clusterUID = clusterUID;\r
-        }\r
-        public final int reference;\r
-        public final int index;\r
-        public final ClusterUID clusterUID;\r
-    }\r
-    private ResourceIndexAndId checkResourceKeyAndGetResourceIndexIf(int resourceKey, ClusterSupport support)\r
-    throws DatabaseException {\r
-        int clusterKey = ClusterTraits.getClusterKeyFromResourceKey(resourceKey);\r
-        int resourceIndex = ClusterTraits.getResourceIndexFromResourceKey(resourceKey);\r
-        if (this.clusterKey != clusterKey) { // foreign resource\r
-            ClusterI foreignCluster = support.getClusterByClusterKey(clusterKey);\r
-            ClusterUID clusterUID = foreignCluster.getClusterUID();\r
-            int ref = clusterMap.getForeignReferenceOrCreateByResourceIndex(resourceIndex, clusterUID);\r
-            return new ResourceIndexAndId(ref, resourceIndex, clusterUID);\r
-        }\r
-        return new ResourceIndexAndId(resourceIndex, resourceIndex, getClusterUID());\r
-    }\r
-\r
-    @Override\r
-    final public int execute(int resourceIndex) throws DatabaseException {\r
-        int key;\r
-        if(resourceIndex > 0) {\r
-            key = clusterBits | resourceIndex;\r
-        } else {\r
-            ClusterUID clusterUID = clusterMap.getResourceUID(resourceIndex).asCID();\r
-            ClusterI cluster = clusterSupport.getClusterByClusterUIDOrMake(clusterUID);\r
-            int foreingResourceIndex =  clusterMap.getForeignResourceIndex(resourceIndex);\r
-            key = ClusterTraits.createResourceKey(cluster.getClusterKey(), foreingResourceIndex);\r
-        }\r
-        if (DEBUG)\r
-            System.out.println("Cluster.execute key=" + key);\r
-        return key;\r
-    }\r
-\r
-    private boolean addRelationInternal(int sReference, int pReference, int oReference, ClusterI.CompleteTypeEnum completeType)\r
-    throws DatabaseException {\r
-        int predicateIndex = resourceTable.addStatement(sReference, pReference,\r
-                oReference, predicateTable, objectTable, completeType, completeTable);\r
-        if (0 == predicateIndex)\r
-            return true; // added to resourceTable\r
-        else if (0 > predicateIndex)\r
-            return false; // old complete statemenent\r
-        int newPredicateIndex = predicateTable.addPredicate(predicateIndex,\r
-                pReference, oReference, objectTable);\r
-        if (0 == newPredicateIndex)\r
-            return false;\r
-        if (predicateIndex != newPredicateIndex)\r
-            resourceTable.setPredicateIndex(sReference, newPredicateIndex);\r
-        return true;\r
-    }\r
-    private boolean removeRelationInternal(int sResourceIndex, int pResourceIndex,\r
-            int oResourceIndex, ClusterI.CompleteTypeEnum completeType, ClusterSupport support)\r
-    throws DatabaseException {\r
-        int predicateIndex = resourceTable.getPredicateIndex(sResourceIndex);\r
-        if (0 == predicateIndex || ClusterI.CompleteTypeEnum.NotComplete != completeType)\r
-            return resourceTable.removeStatementFromCache(sResourceIndex,\r
-                    pResourceIndex, oResourceIndex, completeType, completeTable);\r
-        PredicateTable.Status ret = predicateTable.removePredicate(predicateIndex, pResourceIndex, oResourceIndex, objectTable);\r
-        switch (ret) {\r
-            case NothingRemoved:\r
-                return false;\r
-            case PredicateRemoved: {\r
-                if (0 == predicateTable.getPredicateSetSize(predicateIndex))\r
-                    resourceTable.setPredicateIndex(sResourceIndex, 0);\r
-                // intentionally dropping to next case\r
-            } default:\r
-                break;\r
-        }\r
-        resourceTable.removeStatement(sResourceIndex,\r
-                pResourceIndex, oResourceIndex,\r
-                completeType, completeTable,\r
-                predicateTable, objectTable, this, support);\r
-        return true;\r
-    }\r
-    @Override\r
-    public void load() {\r
-        throw new Error("Not supported.");\r
-    }\r
-\r
-    @Override\r
-    public void load(Callback<DatabaseException> r) {\r
-        throw new Error("Not supported.");\r
-    }\r
-\r
-    public int makeResourceKey(int resourceIndex) throws DatabaseException {\r
-        int key = 0;\r
-//        if (ClusterTraitsBase.isIllegalResourceIndex(resourceIndex))\r
-//            throw new DatabaseException("Illegal resource key " + resourceIndex);\r
-        if (resourceIndex > 0) // local resource\r
-            key = ClusterTraits.createResourceKey(clusterKey, resourceIndex);\r
-        else {\r
-            ClusterUID clusterUID = clusterMap.getResourceUID(resourceIndex).asCID();\r
-            ClusterI cluster = clusterSupport.getClusterByClusterUIDOrMake(clusterUID);\r
-            int foreingResourceIndex =  clusterMap.getForeignResourceIndex(resourceIndex);\r
-            key = ClusterTraits.createResourceKey(cluster.getClusterKey(), foreingResourceIndex);\r
-        }\r
-        if (0 == key)\r
-            throw new DatabaseException("Failed to make resource key from " + resourceIndex);\r
-        return key;\r
-    }\r
-    @Override\r
-    public ClusterBig toBig(ClusterSupport support) throws DatabaseException {\r
-        throw new Error("Not implemented");\r
-    }\r
-    @Override\r
-    public void load(ClusterSupport session, Runnable callback) {\r
-        throw new Error("Not implemented");\r
-    }\r
-    @Override\r
-    public ClusterI getClusterByResourceKey(int resourceKey,\r
-            ClusterSupport support) {\r
-        throw new Error("Not implemented");\r
-    }\r
-    @Override\r
-    public void increaseReferenceCount(int amount) {\r
-        throw new Error("Not implemented");\r
-    }\r
-    @Override\r
-\r
-    public void decreaseReferenceCount(int amount) {\r
-        throw new Error("Not implemented");\r
-    }\r
-    @Override\r
-    public int getReferenceCount() {\r
-        throw new Error("Not implemented");\r
-    }\r
-    @Override\r
-    public void releaseMemory() {\r
-    }\r
-    @Override\r
-    public void compact() {\r
-        clusterMap.compact();\r
-    }\r
-    public boolean contains(int resourceKey) {\r
-        return ClusterTraitsBase.isCluster(clusterBits, resourceKey);\r
-    }\r
-    @Override\r
-    public ClusterTypeEnum getType() {\r
-        return ClusterTypeEnum.BIG;\r
-    }\r
-    @Override\r
-    public boolean getImmutable() {\r
-        int status = resourceTable.getClusterStatus();\r
-        return (status & ClusterStatus.ImmutableMaskSet) == ClusterStatus.ImmutableMaskSet;\r
-    }\r
-    @Override\r
-    public void setImmutable(boolean immutable, ClusterSupport support) {\r
-        int status = resourceTable.getClusterStatus();\r
-        if (immutable)\r
-            status |= ClusterStatus.ImmutableMaskSet;\r
-        else\r
-            status &= ClusterStatus.ImmutableMaskClear;\r
-        resourceTable.setClusterStatus(status);\r
-        support.setImmutable(this, immutable);\r
-    }\r
-    @Override\r
-    public boolean getDeleted() {\r
-        int status = resourceTable.getClusterStatus();\r
-        return (status & ClusterStatus.DeletedMaskSet) == ClusterStatus.DeletedMaskSet;\r
-    }\r
-    @Override\r
-    public void setDeleted(boolean deleted, ClusterSupport support) {\r
-        int status = resourceTable.getClusterStatus();\r
-        if (deleted)\r
-            status |= ClusterStatus.DeletedMaskSet;\r
-        else\r
-            status &= ClusterStatus.DeletedMaskClear;\r
-        resourceTable.setClusterStatus(status);\r
-        support.setDeleted(this, deleted);\r
-    }\r
-    @Override\r
-    public Table<?> getPredicateTable() {\r
-        return predicateTable;\r
-    }\r
-    @Override\r
-    public Table<?> getForeignTable() {\r
-        return foreignTable;\r
-    }\r
-    @Override\r
-    public Table<?> getCompleteTable() {\r
-        return completeTable;\r
-    }\r
-    @Override\r
-    public Table<?> getValueTable() {\r
-        return valueTable;\r
-    }\r
-    @Override\r
-    public Table<?> getObjectTable() {\r
-        return objectTable;\r
-    }\r
-}\r
-\r
-class SizeOfPredicateTable implements ClusterI.ObjectProcedure<Integer> {\r
-    private final ResourceTable mrResourceTable;\r
-    private final PredicateTable mrPredicateTable;\r
-    private int size = 0;\r
-    SizeOfPredicateTable(ResourceTable resourceTable\r
-            , PredicateTable predicateTable) {\r
-        mrResourceTable = resourceTable;\r
-        mrPredicateTable = predicateTable;\r
-    }\r
-    @Override\r
-    public boolean execute(Integer i, int resourceRef) {\r
-        int predicateIndex = mrResourceTable.getPredicateIndex(resourceRef);\r
-        if (0 == predicateIndex)\r
-            return false; // continue loop\r
-        size += mrPredicateTable.getPredicateSetSize(predicateIndex);\r
-        return false; // continue loop\r
-    }\r
-\r
-    public int getSize() {\r
-        return size;\r
-    }\r
-}\r
-\r
-class SizeOfObjectTable implements ClusterI.ObjectProcedure<Integer> {\r
-    private final ResourceTable mrResourceTable;\r
-    private final PredicateTable mrPredicateTable;\r
-    private final ObjectTable mrObjectTable;\r
-    private int size = 0;\r
-    SizeOfObjectTable(ResourceTable resourceTable\r
-            , PredicateTable predicateTable, ObjectTable objectTable) {\r
-        mrResourceTable = resourceTable;\r
-        mrPredicateTable = predicateTable;\r
-        mrObjectTable = objectTable;\r
-    }\r
-\r
-    @Override\r
-    public boolean execute(Integer i, int resourceRef) {\r
-        int predicateIndex = mrResourceTable.getPredicateIndex(resourceRef);\r
-        if (0 == predicateIndex)\r
-            return false; // continue loop\r
-        ClusterI.PredicateProcedure<Object> procedure = new PredicateProcedure<Object>() {\r
-            @Override\r
-            public boolean execute(Object context, int pRef, int oIndex) {\r
-                if (ClusterTraits.statementIndexIsDirect(oIndex))\r
-                    return false; // no table space reserved, continue looping\r
-                int objectIndex;\r
-                try {\r
-                    objectIndex = ClusterTraits.statementIndexGet(oIndex);\r
-                    size += mrObjectTable.getObjectSetSize(objectIndex);\r
-                } catch (DatabaseException e) {\r
-                    e.printStackTrace();\r
-                }\r
-                return false; // continue looping\r
-            }\r
-        };\r
-        try {\r
-            mrPredicateTable.foreachPredicate(predicateIndex, procedure, null, null, null);\r
-        } catch (DatabaseException e) {\r
-            e.printStackTrace();\r
-        }\r
-        return false; // continue loop\r
-    }\r
-\r
-    public int getSize() {\r
-        return size;\r
-    }\r
-\r
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.db.procore.cluster;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+
+import org.simantics.db.Resource;
+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.ClusterI.PredicateProcedure;
+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.Table;
+import org.simantics.db.impl.TableHeader;
+import org.simantics.db.impl.graph.ReadGraphImpl;
+import org.simantics.db.impl.query.QueryProcessor;
+import org.simantics.db.procedure.AsyncContextMultiProcedure;
+import org.simantics.db.procedure.AsyncMultiProcedure;
+import org.simantics.db.service.ClusterUID;
+import org.simantics.utils.datastructures.Callback;
+
+import fi.vtt.simantics.procore.DebugPolicy;
+import fi.vtt.simantics.procore.internal.ClusterChange;
+import fi.vtt.simantics.procore.internal.ClusterStream;
+import fi.vtt.simantics.procore.internal.SessionImplSocket;
+
+final public class ClusterBig 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;
+    final private ResourceTable resourceTable;
+    //final private ResourceTable movedResourceTable;
+    final private PredicateTable predicateTable;
+    final private ObjectTable objectTable;
+    final private ValueTable valueTable;
+    final private FlatTable flatTable;
+    final private ForeignTable foreignTable;
+    final private CompleteTable completeTable;
+    final private ClusterMap clusterMap;
+    final private int[] headerTable;
+    final private ClusterSupport clusterSupport;
+    public ClusterBig(ClusterUID clusterUID, int clusterKey, ClusterSupport support) {
+        super(clusterUID, clusterKey, support);
+        if(DebugPolicy.REPORT_CLUSTER_EVENTS)
+            new Exception(getClusterUID().toString()).printStackTrace();
+        this.headerTable = new int[INT_HEADER_SIZE];
+        this.resourceTable = new ResourceTable(this, headerTable, RESOURCE_TABLE_OFFSET);
+        this.foreignTable = new ForeignTable(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 ValueTable(this, headerTable, VALUE_TABLE_OFFSET);
+        this.completeTable = new CompleteTable(this, headerTable, COMPLETE_TABLE_OFFSET);
+        this.flatTable = null;
+        this.clusterMap = new ClusterMap(foreignTable, flatTable);
+        this.clusterSupport = support;
+        this.clusterBits = ClusterTraitsBase.getClusterBits(clusterKey);
+        this.importance = 0;
+//        clusterTable.setDirtySizeInBytes(true);
+    }
+    protected ClusterBig(long[] longs, int[] ints, byte[] bytes, ClusterSupport support, int clusterKey)
+    throws DatabaseException {
+        super(checkValidity(0, longs, ints, bytes), clusterKey, support);
+        if(DebugPolicy.REPORT_CLUSTER_EVENTS)
+            new Exception(getClusterUID().toString()).printStackTrace();
+        if (ints.length < INT_HEADER_SIZE)
+            throw new IllegalArgumentException("Too small integer table for cluster.");
+        this.headerTable = ints;
+        this.resourceTable = new ResourceTable(this, ints, RESOURCE_TABLE_OFFSET, longs);
+        this.foreignTable = new ForeignTable(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 ValueTable(this, ints, VALUE_TABLE_OFFSET, bytes);
+        this.flatTable = null;
+        this.completeTable = new CompleteTable(this, headerTable, COMPLETE_TABLE_OFFSET, ints);
+        this.clusterMap = new ClusterMap(foreignTable, flatTable);
+        this.clusterSupport = support;
+        this.clusterBits = ClusterTraitsBase.getClusterBits(clusterKey);
+        this.importance = clusterTable.timeCounter();
+        clusterTable.markImmutable(this, getImmutable());
+    }
+    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);
+        int completeRef = resourceTable.getCompleteObjectRef(resourceRef);
+        CompleteTypeEnum ct = ClusterTraits.completeReferenceGetType(completeRef);
+        if (DEBUG)
+            System.out.println("Cluster.getCompleteType rk=" + resourceKey + " ct=" + ct);
+        int i = ct.getValue();
+        switch (i) {
+            case 0: return CompleteTypeEnum.NotComplete;
+            case 1: return CompleteTypeEnum.InstanceOf;
+            case 2: return CompleteTypeEnum.Inherits;
+            case 3: return CompleteTypeEnum.SubrelationOf;
+            default: throw new DatabaseException("Illegal complete type enumeration.");
+        }
+    }
+
+    @Override
+    public int getCompleteObjectKey(int resourceKey, ClusterSupport support)
+    throws DatabaseException {
+        final int resourceRef = getLocalReference(resourceKey);
+        int completeRef = resourceTable.getCompleteObjectRef(resourceRef);
+        int clusterIndex;
+        int resourceIndex = ClusterTraits.completeReferenceGetResourceIndex(completeRef);
+
+        ClusterI.CompleteTypeEnum completeType = ClusterTraits.completeReferenceGetType(completeRef);
+        if (completeType == ClusterI.CompleteTypeEnum.NotComplete)
+            throw new DatabaseException("Resource has multiple complete objects. Resource key=" + resourceKey + ".");
+
+        if (ClusterTraits.completeReferenceIsLocal(completeRef)) {
+            clusterIndex = clusterKey;
+        } else {
+            int foreignIndex = ClusterTraits.completeReferenceGetForeignIndex(completeRef);
+//            System.err.println("completeRef=" + completeRef + " foreignIndex=" + foreignIndex );
+            ClusterUID clusterUID = foreignTable.getResourceUID(foreignIndex).asCID();
+            ClusterI c = support.getClusterByClusterUIDOrMake(clusterUID);
+            clusterIndex = c.getClusterKey();
+        }
+        int key = ClusterTraits.createResourceKey(clusterIndex, resourceIndex);
+        if (DEBUG)
+            System.out.println("Cluster.complete object rk=" + resourceKey + " ck=" + key);
+        return key;
+    }
+
+    @Override
+    public boolean isComplete(int resourceKey, ClusterSupport support)
+    throws DatabaseException {
+        final int resourceRef = getLocalReference(resourceKey);
+        int completeRef = resourceTable.getCompleteObjectRef(resourceRef);
+        ClusterI.CompleteTypeEnum completeType = ClusterTraits.completeReferenceGetType(completeRef);
+        boolean complete = completeType != ClusterI.CompleteTypeEnum.NotComplete;
+        if (DEBUG)
+            System.out.println("Cluster.key=" + resourceKey + " isComplete=" + complete);
+        return complete;
+    }
+
+    public int getSingleObject(int resourceKey, int predicateKey, int objectIndex, ClusterSupport support) throws DatabaseException {
+        if (DEBUG)
+            System.out.println("Cluster.getSingleObject: rk=" + resourceKey + " pk=" + predicateKey);
+        if (0 == objectIndex) {
+            final int resourceIndex = getLocalReference(resourceKey);
+            final int pRef = getInternalReferenceOrZero(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(int resourceKey, int predicateKey, int objectIndex, QueryProcessor processor, ReadGraphImpl graph, AsyncMultiProcedure<Resource> procedure,
+            ClusterSupport support) throws DatabaseException {
+        if (DEBUG)
+            System.out.println("Cluster.forObjects1: rk=" + resourceKey + " pk=" + predicateKey);
+        if (0 == objectIndex) {
+            final int resourceIndex = getLocalReference(resourceKey);
+            final int pRef = getInternalReferenceOrZero(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 <C> void forObjects(int resourceKey, int predicateKey, int objectIndex, QueryProcessor processor, ReadGraphImpl graph, C context, AsyncContextMultiProcedure<C, Resource> procedure,
+            ClusterSupport support) throws DatabaseException {
+        if (DEBUG)
+            System.out.println("Cluster.forObjects1: rk=" + resourceKey + " pk=" + predicateKey);
+        if (0 == objectIndex) {
+            final int resourceIndex = getLocalReference(resourceKey);
+            final int pRef = getInternalReferenceOrZero(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 <Context> boolean forObjects(int resourceKey, int predicateKey, int objectIndex, ObjectProcedure<Context> procedure,
+            Context context, ClusterSupport support) throws DatabaseException {
+        if (DEBUG)
+            System.out.println("Cluster.forObjects2: rk=" + resourceKey + " pk=" + predicateKey);
+        if (0 == objectIndex) {
+            final int resourceIndex = getLocalReference(resourceKey);
+            final int pRef = getInternalReferenceOrZero(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("Cluster.getSingleObject2: rk=" + resourceKey + " pk=" + predicateKey);
+        final int resourceIndex = getLocalReference(resourceKey);
+        final int pRef = getInternalReferenceOrZero(predicateKey, support);
+        final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey);
+        if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType)
+            return resourceTable.getSingleObject(resourceIndex, support, pRef, pCompleteType, completeTable, this);
+        final int predicateIndex = resourceTable.getPredicateIndex(resourceIndex);
+        if (0 == predicateIndex)
+            return resourceTable.getSingleObject(resourceIndex, support, pRef, pCompleteType, completeTable, this);
+        int objectIndex = predicateTable.getObjectIndex(predicateIndex, pRef);
+        return getSingleObject(resourceKey, predicateKey, objectIndex, support);
+    }
+
+    @Override
+    public <T> int getSingleObject(int resourceKey, ForPossibleRelatedValueProcedure<T> procedure, ClusterSupport support) throws DatabaseException {
+        final int predicateKey = procedure.predicateKey;
+        if (DEBUG)
+            System.out.println("Cluster.getSingleObject2: rk=" + resourceKey + " pk=" + predicateKey);
+        final int resourceIndex = getLocalReference(resourceKey);
+        final int pRef = getInternalReferenceOrZero(predicateKey, support);
+        final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey);
+        if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType)
+            return resourceTable.getSingleObject(resourceIndex, support, pRef, pCompleteType, completeTable, this);
+        final int predicateIndex = resourceTable.getPredicateIndex(resourceIndex);
+        if (0 == predicateIndex)
+            return resourceTable.getSingleObject(resourceIndex, support, pRef, pCompleteType, completeTable, this);
+        int objectIndex = predicateTable.getObjectIndex(predicateIndex, pRef);
+        return getSingleObject(resourceKey, predicateKey, objectIndex, support);
+    }
+
+    @Override
+    public <C, T> int getSingleObject(int resourceKey, ForPossibleRelatedValueContextProcedure<C, T> procedure, ClusterSupport support) throws DatabaseException {
+        final int predicateKey = procedure.predicateKey;
+        if (DEBUG)
+            System.out.println("Cluster.getSingleObject2: rk=" + resourceKey + " pk=" + predicateKey);
+        final int resourceIndex = getLocalReference(resourceKey);
+        final int pRef = getInternalReferenceOrZero(predicateKey, support);
+        final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey);
+        if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType)
+            return resourceTable.getSingleObject(resourceIndex, support, pRef, pCompleteType, completeTable, this);
+        final int predicateIndex = resourceTable.getPredicateIndex(resourceIndex);
+        if (0 == predicateIndex)
+            return resourceTable.getSingleObject(resourceIndex, support, pRef, pCompleteType, completeTable, this);
+        int objectIndex = predicateTable.getObjectIndex(predicateIndex, pRef);
+        return getSingleObject(resourceKey, predicateKey, objectIndex, support);
+    }
+
+    @Override
+    public void forObjects(ReadGraphImpl graph, int resourceKey,
+            int predicateKey, AsyncMultiProcedure<Resource> procedure)
+            throws DatabaseException {
+
+        SessionImplSocket session = (SessionImplSocket)graph.getSession();
+        ClusterSupport support = session.clusterTranslator;
+
+        if (DEBUG)
+            System.out.println("Cluster.forObjects3: rk=" + resourceKey + " pk=" + predicateKey);
+        final int resourceIndex = getLocalReference(resourceKey);
+        final int pRef = getInternalReferenceOrZero(predicateKey, support);
+        final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey);
+        if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType) {
+            resourceTable.foreachObject(resourceIndex, graph, procedure, support, pRef, pCompleteType, completeTable, this);
+            return;
+        }
+        final int predicateIndex = resourceTable.getPredicateIndex(resourceIndex);
+        if (0 == predicateIndex) {
+            resourceTable.foreachObject(resourceIndex, graph, procedure, support, pRef, pCompleteType, completeTable, this);
+            return;
+        }
+        int objectIndex = predicateTable.getObjectIndex(predicateIndex, pRef);
+        forObjects(resourceKey, predicateKey, objectIndex, graph.processor, graph, procedure, support);
+
+    }
+
+    @Override
+    public void forObjects(ReadGraphImpl graph, int resourceKey, ForEachObjectProcedure procedure) throws DatabaseException {
+        SessionImplSocket session = (SessionImplSocket)graph.getSession();
+        ClusterSupport support = session.clusterTranslator;
+        final int predicateKey = procedure.predicateKey;
+        if (DEBUG)
+            System.out.println("Cluster.forObjects3: rk=" + resourceKey + " pk=" + predicateKey);
+        final int resourceIndex = getLocalReference(resourceKey);
+        final int pRef = getInternalReferenceOrZero(predicateKey, support);
+        final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey);
+        if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType) {
+            resourceTable.foreachObject(resourceIndex, graph, procedure, support, pRef, pCompleteType, completeTable, this);
+            return;
+        }
+        final int predicateIndex = resourceTable.getPredicateIndex(resourceIndex);
+        if (0 == predicateIndex) {
+            resourceTable.foreachObject(resourceIndex, graph, procedure, support, pRef, pCompleteType, completeTable, this);
+            return;
+        }
+        int objectIndex = predicateTable.getObjectIndex(predicateIndex, pRef);
+        forObjects(resourceKey, predicateKey, objectIndex, graph.processor, graph, procedure, support);
+
+    }
+    @Override
+    public <C> void forObjects(ReadGraphImpl graph, int resourceKey, C context,
+            ForEachObjectContextProcedure<C> procedure) throws DatabaseException {
+
+        SessionImplSocket session = (SessionImplSocket)graph.getSession();
+        ClusterSupport support = session.clusterTranslator;
+
+        final int predicateKey = procedure.predicateKey;
+
+        if (DEBUG)
+            System.out.println("Cluster.forObjects3: rk=" + resourceKey + " pk=" + predicateKey);
+        final int resourceIndex = getLocalReference(resourceKey);
+        final int pRef = getInternalReferenceOrZero(predicateKey, support);
+        final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey);
+        if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType) {
+            resourceTable.foreachObject(resourceIndex, graph, context, procedure, support, pRef, pCompleteType, completeTable, this);
+            return;
+        }
+        final int predicateIndex = resourceTable.getPredicateIndex(resourceIndex);
+        if (0 == predicateIndex) {
+            resourceTable.foreachObject(resourceIndex, graph, context, procedure, support, pRef, pCompleteType, completeTable, this);
+            return;
+        }
+        int objectIndex = predicateTable.getObjectIndex(predicateIndex, pRef);
+        forObjects(resourceKey, predicateKey, objectIndex, graph.processor, graph, context, procedure, support);
+
+    }
+
+    @Override
+    public <Context> boolean forObjects(int resourceKey, int predicateKey,
+            ObjectProcedure<Context> procedure, Context context, ClusterSupport support)
+    throws DatabaseException {
+        if (DEBUG)
+            System.out.println("Cluster.forObjects4: rk=" + resourceKey + " pk=" + predicateKey);
+        final int resourceIndex = getLocalReference(resourceKey);
+        final int pRef = getInternalReferenceOrZero(predicateKey, support);
+        final ClusterI.CompleteTypeEnum pCompleteType = ClusterTraitsBase.getCompleteTypeFromResourceKey(predicateKey);
+        if (ClusterI.CompleteTypeEnum.NotComplete != pCompleteType)
+            return resourceTable.foreachObject(resourceIndex, procedure, context, support, this, pRef, pCompleteType, completeTable);
+        final int predicateIndex = resourceTable.getPredicateIndex(resourceIndex);
+        if (0 == predicateIndex)
+            return resourceTable.foreachObject(resourceIndex, procedure, context, support, this, pRef, pCompleteType, completeTable);
+        int objectIndex = predicateTable.getObjectIndex(predicateIndex, pRef);
+        return forObjects(resourceKey, predicateKey, objectIndex, procedure, context, support);
+    }
+    @Override
+    public <Context> boolean forPredicates(int resourceKey,
+            PredicateProcedure<Context> procedure, Context context, ClusterSupport support)
+    throws DatabaseException {
+        if (DEBUG)
+            System.out.println("Cluster.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, int pResourceKey, int oResourceKey, ClusterSupport support)
+    throws DatabaseException {
+        if (DEBUG)
+            System.out.println("add rk=" + sResourceKey + " pk=" + pResourceKey + " ok=" + oResourceKey);
+        int sri = getLocalReferenceAnd(sResourceKey, support, ClusterChange.ADD_OPERATION);
+        int pri = getReferenceOrCreateIfForeign(pResourceKey, support, ClusterStream.NULL_OPERATION);
+        int ori = getReferenceOrCreateIfForeign(oResourceKey, support, ClusterStream.NULL_OPERATION);
+        ClusterI.CompleteTypeEnum completeType = ClusterTraitsBase.getCompleteTypeFromResourceKey(pResourceKey);
+        boolean ret = addRelationInternal(sri, pri, ori, completeType);
+//      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();
+        int sri = getLocalReferenceAnd(sResourceKey, support, ClusterChange.REMOVE_OPERATION);
+        int pri = getInternalReferenceOrZeroAnd(pResourceKey, support, ClusterStream.NULL_OPERATION);
+        int 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);
+        }
+        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 {
+        int sri = checkResourceKeyIsOursAndGetResourceIndexIf(sResourceKey, support);
+        ResourceIndexAndId p = checkResourceKeyAndGetResourceIndexIf(pResourceKey, support);
+        ResourceIndexAndId o = checkResourceKeyAndGetResourceIndexIf(oResourceKey, support);
+        if (0 == sri || 0 == p.index || 0 == o.index)
+            return;
+//        check();
+        ClusterI.CompleteTypeEnum completeType = ClusterTraitsBase.getCompleteTypeFromResourceKey(pResourceKey);
+        boolean ret = removeRelationInternal(sri, 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);
+        }
+//        check();
+        return;
+    }
+    @Override
+    public InputStream getValueStream(int rResourceId, ClusterSupport support) throws DatabaseException {
+        if (DEBUG)
+            System.out.println("ClusterBig.getValue " + rResourceId);
+        int resourceIndex = getLocalReference(rResourceId);
+        try {
+            byte[] buffer = resourceTable.getValue(valueTable, resourceIndex);
+            if(buffer == null) return null;
+            return new ByteArrayInputStream(buffer);
+        } catch (ExternalValueException e) {
+            return support.getValueStreamEx(resourceIndex, clusterId);
+        }
+    }
+    @Override
+    public byte[] getValue(int rResourceId, ClusterSupport support)
+    throws DatabaseException {
+        if (DEBUG)
+            System.out.println("ClusterBig.getValue " + rResourceId);
+        int resourceIndex = getLocalReference(rResourceId);
+        try {
+            return resourceTable.getValue(valueTable, resourceIndex);
+        } catch (ExternalValueException e) {
+            return support.getValueEx(resourceIndex, clusterId);
+        }
+    }
+    @Override
+    public boolean hasValue(int rResourceId, ClusterSupport support)
+    throws DatabaseException {
+        int resourceIndex = getLocalReference(rResourceId);
+        return resourceTable.hasValue(resourceIndex);
+    }
+    @Override
+    public boolean removeValue(int rResourceId, ClusterSupport support)
+    throws DatabaseException {
+        int resourceIndex = getLocalReferenceAnd(rResourceId, support, ClusterChange.DELETE_OPERATION);
+        support.removeValue(this);
+        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);
+        resourceTable.setValue(valueTable, resourceIndex, value, length);
+        return this;
+    }
+    @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);
+        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 long getValueSizeEx(int resourceKey, ClusterSupport support)
+    throws DatabaseException, ExternalValueException {
+        int resourceIndex = getLocalReference(resourceKey);
+        boolean isExternal = resourceTable.isValueEx(valueTable, resourceIndex);
+        if (!isExternal)
+            throw new ExternalValueException("ClusterI.getSize supported only for external value. Resource key=" + resourceKey);
+        return support.getValueSizeEx(resourceIndex, getClusterId());
+    }
+    public boolean isValueEx(int resourceKey)
+    throws DatabaseException {
+        int resourceIndex = getLocalReference(resourceKey);
+        return resourceTable.isValueEx(valueTable, resourceIndex);
+    }
+    @Override
+    public void setValueEx(int resourceKey)
+    throws DatabaseException {
+        int resourceIndex = getLocalReference(resourceKey);
+        resourceTable.setValueEx(valueTable, resourceIndex);
+    }
+    @Override
+    public int createResource(ClusterSupport support)
+    throws DatabaseException {
+        short resourceIndex = resourceTable.createResource();
+
+        if(DebugPolicy.REPORT_RESOURCE_ID_ALLOCATION)
+            System.out.println("[RID_ALLOCATION]: ClusterBig[" + clusterId + "] allocates " + resourceIndex);
+
+        support.createResource(this, resourceIndex, clusterId);
+        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) {
+        return resourceTable.getUsedSize();
+    }
+    @Override
+    public long getUsedSpace() {
+        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;
+//        System.out.println("resource table " + rt);
+//        System.out.println("foreign table (non flat cluster table) " + ft);
+//        System.out.println("predicate table " + pt);
+//        long pt2 = getRealSizeOfPredicateTable() * 4;
+//        System.out.println("predicate table real size " + pt2);
+//        System.out.println("object table " + ot);
+//        long ot2 = getRealSizeOfObjectTable() * 4;
+//        System.out.println("object table real size " + ot2);
+//        System.out.println("value table " + vt);
+    }
+    int getRealSizeOfPredicateTable() throws DatabaseException {
+        SizeOfPredicateTable proc = new SizeOfPredicateTable(resourceTable, predicateTable);
+        resourceTable.foreachResource(proc, 0, null, null);
+        return proc.getSize();
+    }
+    int getRealSizeOfObjectTable() throws DatabaseException {
+        SizeOfObjectTable proc = new SizeOfObjectTable(resourceTable, predicateTable, objectTable);
+        resourceTable.foreachResource(proc, 0, null, null);
+        return proc.getSize();
+    }
+    @Override
+    public boolean isEmpty() {
+        return resourceTable.getTableCount() == 0;
+    }
+    @Override
+    public void printDebugInfo(String message, ClusterSupport support)
+    throws DatabaseException {
+        predicateTable.printDebugInfo();
+        objectTable.printDebugInfo();
+        ClusterPrintDebugInfo proc = new ClusterPrintDebugInfo(this
+                , resourceTable, predicateTable, support, objectTable);
+        resourceTable.foreachResource(proc, 0, null, null);
+    }
+    private int getInternalReferenceOrZero(int resourceKey, ClusterSupport support)
+    throws DatabaseException {
+        int clusterKey = ClusterTraits.getClusterKeyFromResourceKey(resourceKey);
+        int resourceIndex = ClusterTraits.getResourceIndexFromResourceKey(resourceKey);
+        if (this.clusterKey != clusterKey) { // foreign resource
+            ClusterI foreignCluster = support.getClusterByClusterKey(clusterKey);
+            ClusterUID clusterUID = foreignCluster.getClusterUID();
+            int foreignResourceIndex = clusterMap.getForeignReferenceOrZero(resourceIndex, clusterUID);
+            return foreignResourceIndex;
+        }
+        return resourceIndex;
+    }
+    private int 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
+            ClusterI foreignCluster = support.getClusterByClusterKey(clusterKey);
+            ClusterUID clusterUID = foreignCluster.getClusterUID();
+            int foreignResourceIndex = clusterMap.getForeignReferenceOrZero(resourceIndex, clusterUID);
+            support.addStatementIndex(this, resourceKey, clusterUID, op);
+            return foreignResourceIndex;
+        }
+        support.addStatementIndex(this, resourceKey, getClusterUID(), op);
+        return resourceIndex;
+    }
+    private short getLocalReference(int resourceKey) throws DatabaseException {
+        return ClusterTraitsBase.getResourceIndexFromResourceKeyNoThrow(resourceKey);
+    }
+    private int getLocalReferenceAnd(int resourceKey, ClusterSupport support, byte op)
+    throws DatabaseException {
+        int resourceIndex = getLocalReference(resourceKey);
+        support.addStatementIndex(this, resourceKey, getClusterUID(), op);
+        return resourceIndex;
+    }
+    private int checkResourceKeyIsOursAndGetResourceIndexIf(int resourceKey, ClusterSupport support)
+    throws DatabaseException {
+        int clusterShortId = ClusterTraits.getClusterKeyFromResourceKey(resourceKey);
+        if (this.clusterKey != clusterShortId)
+            return 0;
+        int resourceIndex = ClusterTraits.getResourceIndexFromResourceKey(resourceKey);
+        return resourceIndex;
+    }
+    private int getReferenceOrCreateIfForeign(int resourceKey, ClusterSupport support, byte op)
+    throws DatabaseException {
+        int clusterKey = ClusterTraits.getClusterKeyFromResourceKey(resourceKey);
+        int resourceIndex = ClusterTraits.getResourceIndexFromResourceKey(resourceKey);
+        if (this.clusterKey != clusterKey) {
+            ClusterI foreignCluster = support.getClusterByClusterKey(clusterKey);
+            ClusterUID clusterUID = foreignCluster.getClusterUID();
+            support.addStatementIndex(this, resourceKey, clusterUID, op);
+            return clusterMap.getForeignReferenceOrCreateByResourceKey(resourceKey, clusterUID);
+        }
+        support.addStatementIndex(this, resourceKey, getClusterUID(), op);
+        return resourceIndex;
+    }
+    private class ResourceIndexAndId {
+        ResourceIndexAndId(int reference, int index, ClusterUID clusterUID) {
+            this.reference = reference;
+            this.index = index;
+            this.clusterUID = clusterUID;
+        }
+        public final int reference;
+        public final int index;
+        public final ClusterUID clusterUID;
+    }
+    private ResourceIndexAndId checkResourceKeyAndGetResourceIndexIf(int resourceKey, ClusterSupport support)
+    throws DatabaseException {
+        int clusterKey = ClusterTraits.getClusterKeyFromResourceKey(resourceKey);
+        int resourceIndex = ClusterTraits.getResourceIndexFromResourceKey(resourceKey);
+        if (this.clusterKey != clusterKey) { // foreign resource
+            ClusterI foreignCluster = support.getClusterByClusterKey(clusterKey);
+            ClusterUID clusterUID = foreignCluster.getClusterUID();
+            int ref = clusterMap.getForeignReferenceOrCreateByResourceIndex(resourceIndex, clusterUID);
+            return new ResourceIndexAndId(ref, resourceIndex, clusterUID);
+        }
+        return new ResourceIndexAndId(resourceIndex, resourceIndex, getClusterUID());
+    }
+
+    @Override
+    final public int execute(int resourceIndex) throws DatabaseException {
+        int key;
+        if(resourceIndex > 0) {
+            key = clusterBits | resourceIndex;
+        } else {
+            ClusterUID clusterUID = clusterMap.getResourceUID(resourceIndex).asCID();
+            ClusterI cluster = clusterSupport.getClusterByClusterUIDOrMake(clusterUID);
+            int foreingResourceIndex =  clusterMap.getForeignResourceIndex(resourceIndex);
+            key = ClusterTraits.createResourceKey(cluster.getClusterKey(), foreingResourceIndex);
+        }
+        if (DEBUG)
+            System.out.println("Cluster.execute key=" + key);
+        return key;
+    }
+
+    private boolean addRelationInternal(int sReference, int pReference, int 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,
+                pReference, oReference, objectTable);
+        if (0 == newPredicateIndex)
+            return false;
+        if (predicateIndex != newPredicateIndex)
+            resourceTable.setPredicateIndex(sReference, newPredicateIndex);
+        return true;
+    }
+    private boolean removeRelationInternal(int sResourceIndex, int pResourceIndex,
+            int 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, pResourceIndex, 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, this, support);
+        return true;
+    }
+    @Override
+    public void load() {
+        throw new Error("Not supported.");
+    }
+
+    @Override
+    public void load(Callback<DatabaseException> r) {
+        throw new Error("Not supported.");
+    }
+
+    public int makeResourceKey(int resourceIndex) throws DatabaseException {
+        int key = 0;
+//        if (ClusterTraitsBase.isIllegalResourceIndex(resourceIndex))
+//            throw new DatabaseException("Illegal resource key " + resourceIndex);
+        if (resourceIndex > 0) // local resource
+            key = ClusterTraits.createResourceKey(clusterKey, resourceIndex);
+        else {
+            ClusterUID clusterUID = clusterMap.getResourceUID(resourceIndex).asCID();
+            ClusterI cluster = clusterSupport.getClusterByClusterUIDOrMake(clusterUID);
+            int foreingResourceIndex =  clusterMap.getForeignResourceIndex(resourceIndex);
+            key = ClusterTraits.createResourceKey(cluster.getClusterKey(), foreingResourceIndex);
+        }
+        if (0 == key)
+            throw new DatabaseException("Failed to make resource key from " + resourceIndex);
+        return key;
+    }
+    @Override
+    public ClusterBig toBig(ClusterSupport support) throws DatabaseException {
+        throw new Error("Not implemented");
+    }
+    @Override
+    public void load(ClusterSupport session, Runnable callback) {
+        throw new Error("Not implemented");
+    }
+    @Override
+    public ClusterI getClusterByResourceKey(int resourceKey,
+            ClusterSupport support) {
+        throw new Error("Not implemented");
+    }
+    @Override
+    public void increaseReferenceCount(int amount) {
+        throw new Error("Not implemented");
+    }
+    @Override
+
+    public void decreaseReferenceCount(int amount) {
+        throw new Error("Not implemented");
+    }
+    @Override
+    public int getReferenceCount() {
+        throw new Error("Not implemented");
+    }
+    @Override
+    public void releaseMemory() {
+    }
+    @Override
+    public void compact() {
+        clusterMap.compact();
+    }
+    public boolean contains(int resourceKey) {
+        return ClusterTraitsBase.isCluster(clusterBits, resourceKey);
+    }
+    @Override
+    public ClusterTypeEnum getType() {
+        return ClusterTypeEnum.BIG;
+    }
+    @Override
+    public boolean getImmutable() {
+        int status = resourceTable.getClusterStatus();
+        return (status & ClusterStatus.ImmutableMaskSet) == ClusterStatus.ImmutableMaskSet;
+    }
+    @Override
+    public void setImmutable(boolean immutable, ClusterSupport support) {
+        int status = resourceTable.getClusterStatus();
+        if (immutable)
+            status |= ClusterStatus.ImmutableMaskSet;
+        else
+            status &= ClusterStatus.ImmutableMaskClear;
+        resourceTable.setClusterStatus(status);
+        support.setImmutable(this, immutable);
+    }
+    @Override
+    public boolean getDeleted() {
+        int status = resourceTable.getClusterStatus();
+        return (status & ClusterStatus.DeletedMaskSet) == ClusterStatus.DeletedMaskSet;
+    }
+    @Override
+    public void setDeleted(boolean deleted, ClusterSupport support) {
+        int status = resourceTable.getClusterStatus();
+        if (deleted)
+            status |= ClusterStatus.DeletedMaskSet;
+        else
+            status &= ClusterStatus.DeletedMaskClear;
+        resourceTable.setClusterStatus(status);
+        support.setDeleted(this, deleted);
+    }
+    @Override
+    public Table<?> getPredicateTable() {
+        return predicateTable;
+    }
+    @Override
+    public Table<?> getForeignTable() {
+        return foreignTable;
+    }
+    @Override
+    public Table<?> getCompleteTable() {
+        return completeTable;
+    }
+    @Override
+    public Table<?> getValueTable() {
+        return valueTable;
+    }
+    @Override
+    public Table<?> getObjectTable() {
+        return objectTable;
+    }
+}
+
+class SizeOfPredicateTable implements ClusterI.ObjectProcedure<Integer> {
+    private final ResourceTable mrResourceTable;
+    private final PredicateTable mrPredicateTable;
+    private int size = 0;
+    SizeOfPredicateTable(ResourceTable resourceTable
+            , PredicateTable predicateTable) {
+        mrResourceTable = resourceTable;
+        mrPredicateTable = predicateTable;
+    }
+    @Override
+    public boolean execute(Integer i, int resourceRef) {
+        int predicateIndex = mrResourceTable.getPredicateIndex(resourceRef);
+        if (0 == predicateIndex)
+            return false; // continue loop
+        size += mrPredicateTable.getPredicateSetSize(predicateIndex);
+        return false; // continue loop
+    }
+
+    public int getSize() {
+        return size;
+    }
+}
+
+class SizeOfObjectTable implements ClusterI.ObjectProcedure<Integer> {
+    private final ResourceTable mrResourceTable;
+    private final PredicateTable mrPredicateTable;
+    private final ObjectTable mrObjectTable;
+    private int size = 0;
+    SizeOfObjectTable(ResourceTable resourceTable
+            , PredicateTable predicateTable, ObjectTable objectTable) {
+        mrResourceTable = resourceTable;
+        mrPredicateTable = predicateTable;
+        mrObjectTable = objectTable;
+    }
+
+    @Override
+    public boolean execute(Integer i, int resourceRef) {
+        int predicateIndex = mrResourceTable.getPredicateIndex(resourceRef);
+        if (0 == predicateIndex)
+            return false; // continue loop
+        ClusterI.PredicateProcedure<Object> procedure = new PredicateProcedure<Object>() {
+            @Override
+            public boolean execute(Object context, int pRef, int oIndex) {
+                if (ClusterTraits.statementIndexIsDirect(oIndex))
+                    return false; // no table space reserved, continue looping
+                int objectIndex;
+                try {
+                    objectIndex = ClusterTraits.statementIndexGet(oIndex);
+                    size += mrObjectTable.getObjectSetSize(objectIndex);
+                } catch (DatabaseException e) {
+                    e.printStackTrace();
+                }
+                return false; // continue looping
+            }
+        };
+        try {
+            mrPredicateTable.foreachPredicate(predicateIndex, procedure, null, null, null);
+        } catch (DatabaseException e) {
+            e.printStackTrace();
+        }
+        return false; // continue loop
+    }
+
+    public int getSize() {
+        return size;
+    }
+
 }
\ No newline at end of file