]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ClusterChangeSet.java
Removed contact application support prints
[simantics/platform.git] / bundles / org.simantics.db.procore / src / org / simantics / db / procore / cluster / ClusterChangeSet.java
index 172af9ca8de7859424e51aaee59b9cddccb9ce14..3afb92fc862b8e43be09ea58161494e17399dab0 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.util.Vector;\r
-\r
-import org.simantics.db.exception.InternalException;\r
-import org.simantics.db.exception.RuntimeDatabaseException;\r
-import org.simantics.db.procore.cluster.CCSParser.ReferenceType;\r
-import org.simantics.db.procore.cluster.CCSParser.StmEnum;\r
-import org.simantics.db.service.ClusterUID;\r
-\r
-public class ClusterChangeSet implements ClusterChangeSetI {\r
-    static interface IteratorI {\r
-    }\r
-    static private final boolean DEBUG = false;\r
-    static private final int HEADER_SIZE = 20;\r
-    private final int version;\r
-    private final ClusterUID clusterUID;\r
-    private final byte[] bytes;\r
-\r
-    public static ClusterChangeSetI create(byte[] rawData, String compressionCodec)\r
-    throws InternalException {\r
-        \r
-        // TODO: Find maybe a better way to do this\r
-        byte[] bytes;\r
-        if (compressionCodec.equals("LZ4")) {\r
-            LZ4.DecompressStruct data = LZ4.decompress(rawData);\r
-            bytes = data.bytes;\r
-        } else if (compressionCodec.equals("FLZ")) {\r
-            FastLZ.DecompressStruct data = FastLZ.decompress(rawData);\r
-            bytes = data.bytes;\r
-        } else {\r
-            throw new RuntimeDatabaseException("No compressionCodec given!");\r
-        }\r
-        return new ClusterChangeSet(bytes);\r
-    }\r
-    @Override\r
-    public String toString() {\r
-        return "cid=" + clusterUID + " len=" + bytes.length; \r
-    }\r
-    private ClusterChangeSet(byte[] abytes) {\r
-        this.bytes = abytes;\r
-        if (bytes.length < HEADER_SIZE + 4)\r
-            throw new RuntimeDatabaseException("Cluster change must contain header and size. length=" + bytes.length);\r
-        version = CCSParser.getInt(bytes, 0);\r
-        if (version <1 || version > 2)\r
-            throw new RuntimeDatabaseException("Unsupported cluster change set version=" + version);\r
-        clusterUID = ClusterUID.make(abytes, 4);\r
-        if (ClusterUID.Null.equals(clusterUID))\r
-            throw new RuntimeDatabaseException("Cluster uid can not be null.");\r
-        if (DEBUG)\r
-            System.out.println("DEBUG: Cluster uid=" + clusterUID);\r
-        int p = HEADER_SIZE;\r
-        int size = CCSParser.getInt(bytes, p);\r
-        if (2 == version) {\r
-            System.out.println("Cluster change set version=2 is not supported. skipping...");\r
-            return;\r
-        }\r
-        for (; size > 0; size = CCSParser.getInt(bytes, p)) {\r
-            mBlocks.push_back(new ClusterChangeSetBlock(p+=4, size, bytes));\r
-            p += size; // skip block data\r
-        } \r
-    }\r
-    @Override\r
-    public ClusterUID getClusterUID() {\r
-        return clusterUID;\r
-    }\r
-    private boolean updateRequired() {\r
-        return false;\r
-    }\r
-    private void update() {\r
-    }\r
-    @Override\r
-    public void getNextOperation(Operation ar) {\r
-        Iterator pIterator = null;\r
-        if (null == ar.iterator) {\r
-            if (updateRequired())\r
-                this.update();\r
-            int N = mBlocks.size();\r
-            if (0 ==  N) {\r
-                ar.type = OperationEnum.EndOf;\r
-                return;\r
-            }\r
-            pIterator = new Iterator(N-1);\r
-            ar.iterator = pIterator;\r
-        } else\r
-            pIterator = (Iterator)ar.iterator;\r
-        if (pIterator.block > pIterator.lastBlock) {\r
-            ar.type = OperationEnum.EndOf;\r
-            ar.iterator = null;\r
-            return;\r
-        } else if (pIterator.offset >= mBlocks.get(pIterator.block).size) {\r
-            ++pIterator.block;\r
-            pIterator.foreignTable.init();\r
-            pIterator.offset = 0;\r
-            if (pIterator.block > pIterator.lastBlock) {\r
-                ar.type = OperationEnum.EndOf;\r
-                ar.iterator = null;\r
-                return;\r
-            }\r
-        }\r
-        if (pIterator.offset >= mBlocks.get(pIterator.block).size) {\r
-            ++pIterator.block;\r
-            pIterator.foreignTable.init();\r
-            pIterator.offset = 0;\r
-            if (pIterator.block > pIterator.lastBlock) {\r
-                ar.type = OperationEnum.EndOf;\r
-                ar.iterator = null;\r
-                return;\r
-            }\r
-        }\r
-        ClusterChangeSetBlock r = mBlocks.get(pIterator.block);\r
-        int inc = next(ar, pIterator, r.bytes, r.offset + pIterator.offset, r.offset + r.size);\r
-        if (inc <= 0) {\r
-            if (inc < 0)\r
-                System.out.println("Iterarto offset increment is negative!");\r
-            ar.type = OperationEnum.EndOf;\r
-            ar.iterator = null;\r
-        } else\r
-            pIterator.offset += inc;\r
-    }\r
-    private int next(Operation ar, Iterator pIterator, byte[] bytes, int ab, int ae) {\r
-        CCSParser.Args args = new CCSParser.Args(clusterUID, pIterator.foreignTable, ar);\r
-        final int pe = ae;\r
-        final int pb = ab;\r
-        int p = pb;\r
-        if (p < pe) {\r
-            if (DEBUG)\r
-                System.out.println("CCS.next offset=" + p);\r
-            short ri = 0; // resource index\r
-            short kraa = (short)(bytes[p] & 0xFF); \r
-            switch (kraa) {\r
-                case 0: case 1: case 2: case 3:\r
-                    //0x000000?? add - ri12 + pi14 + oi14 = 40 / 8 = 5\r
-                    p = CCSParser.parseStm(StmEnum.Add, args, bytes, p, 2, ReferenceType.Local, ReferenceType.Local);\r
-                    break;\r
-                case 4: case 5: case 6: case 7:\r
-                    //0x000001?? rem - ri12 + pi14 + oi14 = 40 / 8 = 5\r
-                    p = CCSParser.parseStm(StmEnum.Remove, args, bytes, p, 2, ReferenceType.Local, ReferenceType.Local);\r
-                    break;\r
-                case 8: case 9: case 10: case 11:\r
-                    //0x000010?? add - ri12 + pi14 + oc62 = 88 / 8 = 11\r
-                    p = CCSParser.parseStm(StmEnum.Add, args, bytes, p, 2, ReferenceType.Local, ReferenceType.ForeignLong);\r
-                    break;\r
-                case 12: case 13: case 14: case 15:\r
-                    //0x000011?? rem - ri12 + pi14 + oc62 = 88 / 8 = 11\r
-                    p = CCSParser.parseStm(StmEnum.Remove, args, bytes, p, 2, ReferenceType.Local, ReferenceType.ForeignLong);\r
-                    break;\r
-                case 16: case 17: case 18: case 19:\r
-                    //0x000100?? add - ri12 + pc62 + oi14 = 88 / 8 = 11\r
-                    p = CCSParser.parseStm(StmEnum.Add, args, bytes, p, 2, ReferenceType.ForeignLong, ReferenceType.Local);\r
-                    break;\r
-                case 20: case 21: case 22: case 23:\r
-                    //0x000101?? rem - ri12 + pc62 + oi14 = 88 / 8 = 11\r
-                    p = CCSParser.parseStm(StmEnum.Remove, args, bytes, p, 2, ReferenceType.ForeignLong, ReferenceType.Local);\r
-                    break;\r
-                case 24: case 25: case 26: case 27:\r
-                    //0x000110?? add - ri12 + pc62 + oc62 = 136 / 8 = 17\r
-                    p = CCSParser.parseStm(StmEnum.Add, args, bytes, p, 2, ReferenceType.ForeignLong, ReferenceType.ForeignLong);\r
-                    break;\r
-                case 28: case 29: case 30: case 31:\r
-                    //0x000111?? rem - ri12 + pc62 + oc62 = 136 / 8 = 17\r
-                    p = CCSParser.parseStm(StmEnum.Remove, args, bytes, p, 2, ReferenceType.ForeignLong, ReferenceType.ForeignLong);\r
-                    break;\r
-                case 32: case 33: case 34: case 35:\r
-                case 36: case 37: case 38: case 39:\r
-                case 40: case 41: case 42: case 43:\r
-                case 44: case 45: case 46: case 47: case 48:\r
-                    //0x0010???? rem - ri10 + pr08 + oi14 = 32 / 8 = 4\r
-                    p = CCSParser.parseStm(StmEnum.Remove, args, bytes, p, 4, ReferenceType.ForeignShort, ReferenceType.Local);\r
-                    break;\r
-                case 49:\r
-                    //0x00110001 rem - ri14 + pi14 + pr08 + pad4 = 40 / 8 = 5\r
-                    p = CCSParser.parseStm(StmEnum.Remove, args, bytes, p, 0, ReferenceType.Local, ReferenceType.ForeignShort);\r
-                    break;\r
-                case 50:\r
-                    //0x00110010 rem - ri14 + pr08 + oc62 + pad4 = 88 / 8 = 11\r
-                    p = CCSParser.parseStm(StmEnum.Remove, args, bytes, p, 0, ReferenceType.ForeignShort, ReferenceType.ForeignLong);\r
-                    break;\r
-                case 51:\r
-                    //0x00110011 rem - ri14 + pc62 + or08 + pad4 = 88 / 8 = 11\r
-                    p = CCSParser.parseStm(StmEnum.Remove, args, bytes, p, 0, ReferenceType.ForeignLong, ReferenceType.ForeignShort);\r
-                    break;\r
-                case 52: //0x00110100 cre - ri14 + pad2 = 16 / 8 = 2\r
-                    ri = CCSParser.getShort(bytes, p+1);\r
-                    if (DEBUG)\r
-                        System.out.println("Creating resource r=" + ri + " rc=" + clusterUID);\r
-                    args.createResource(ri);\r
-                    p += 3;\r
-                    break;\r
-                case 53: {\r
-                    //0x00110101 set - ri14 + sz18 = 32 / 8 = 4 + sz * bytes\r
-                    int t = CCSParser.getInt(bytes, p + 1);\r
-                    ri = (short)(t & 0x3FFF); \r
-                    int s = t >>> 14;\r
-                    args.setValue(ri, bytes, p + 5, s);\r
-                    p += 5 + s;\r
-                    break; }\r
-                case 54: //0x00110110 del - ri14 + pad2 = 16 / 8 = 2\r
-                    ri = CCSParser.getShort(bytes, p+1);\r
-                    args.deleteValue(ri);\r
-                    p += 3;\r
-                    break;\r
-                case 55: {\r
-                    //0x00110111 mod - ri14 + of58 + sz16  = 88 / 8 = 11 + sz * bytes\r
-                    ri = CCSParser.getShort(bytes, p+1);\r
-                    ri &= (1<<14)-1; // mask top 2 bits\r
-                    long vo = CCSParser.getLongN(bytes, p+3, 7); // get low 7 bytes\r
-                    vo |= (long)(bytes[p+2] & 0xC0) << (56-6); // add the top 2 bits\r
-                    p += 10;\r
-                    int vsize = CCSParser.getShort(bytes, p);\r
-                    if (vsize < 0)\r
-                        vsize += 65536;\r
-                    p += 2;\r
-                    if (DEBUG)\r
-                        System.out.println("Modifying value r=" + ri + " rc=" + args.clusterUID +\r
-                        " value offset=" + vo + " size=" + vsize);\r
-                    if (pe - p < vsize)\r
-                        throw new RuntimeException("Illegal size=" + vsize + " limit=" + (pe - p));\r
-                    args.modifyValue(ri, vo, vsize, bytes, p);\r
-                    p += vsize;\r
-                    break; }\r
-                case 56: case 57: case 58: case 59:\r
-                case 60: case 61: case 62: case 63: {\r
-                    //0x00111??? set - ri14 + sz2 = 16 / 8 = 2 + sz * bytes;\r
-                    byte s = (byte)(bytes[p] & 0x7);\r
-                    s <<= 2;\r
-                    ri = CCSParser.getShort(bytes, p+1);\r
-                    ri &= 0x3FFF; \r
-                    byte t = bytes[p + 2];\r
-                    s |= (t &0xFF) >> 6;\r
-                    args.setValue(ri, bytes, p + 3, s);\r
-                    p += 3 + s;\r
-                    break; }\r
-                case 64: case 65: case 66: case 67:\r
-                case 68: case 69: case 70: case 71:\r
-                case 72: case 73: case 74: case 75:\r
-                case 76: case 77: case 78: case 79:\r
-                case 80: case 81: case 82: case 83:\r
-                case 84: case 85: case 86: case 87:\r
-                case 88: case 89: case 90: case 91:\r
-                case 92: case 93: case 94: case 95:\r
-                case 96: case 97: case 98: case 99:\r
-                case 100: case 101: case 102: case 103:\r
-                case 104: case 105: case 106: case 107:\r
-                case 108: case 109: case 110: case 111:\r
-                case 112: case 113: case 114: case 115:\r
-                case 116: case 117: case 118: case 119:\r
-                case 120: case 121: case 122: case 123:\r
-                case 124: case 125: case 126: case 127:\r
-                    //0x01?????? add - ri08 + pr08 + or08 = 24 / 8 = 3\r
-                    p = CCSParser.parseStm(StmEnum.Add, args, bytes, p, 6, ReferenceType.ForeignShort, ReferenceType.ForeignShort);\r
-                    break;\r
-                case 128: case 129: case 130: case 131:\r
-                case 132: case 133: case 134: case 135:\r
-                case 136: case 137: case 138: case 139:\r
-                case 140: case 141: case 142: case 143:\r
-                case 144: case 145: case 146: case 147:\r
-                case 148: case 149: case 150: case 151:\r
-                case 152: case 153: case 154: case 155:\r
-                case 156: case 157: case 158: case 159:\r
-                case 160: case 161: case 162: case 163:\r
-                case 164: case 165: case 166: case 167:\r
-                case 168: case 169: case 170: case 171:\r
-                case 172: case 173: case 174: case 175:\r
-                case 176: case 177: case 178: case 179:\r
-                case 180: case 181: case 182: case 183:\r
-                case 184: case 185: case 186: case 187:\r
-                case 188: case 189: case 190:case 191:\r
-                    //0x10?????? rem - ri08 + pr08 + or08 = 24 / 8 = 3\r
-                    p = CCSParser.parseStm(StmEnum.Remove, args, bytes, p, 6, ReferenceType.ForeignShort, ReferenceType.ForeignShort);\r
-                    break;\r
-                case 192: case 193: case 194: case 195:\r
-                case 196: case 197: case 198: case 199:\r
-                case 200: case 201: case 202: case 203:\r
-                case 204: case 205: case 206: case 207:\r
-                    //0x1100???? add - ri10 + pi14 + pr08 = 32 / 8 = 4\r
-                    p = CCSParser.parseStm(StmEnum.Add, args, bytes, p, 4, ReferenceType.Local, ReferenceType.ForeignShort);\r
-                    break;\r
-                case 208: case 209: case 210: case 211:\r
-                case 212: case 213: case 214: case 215:\r
-                case 216: case 217: case 218: case 219:\r
-                case 220: case 221: case 222: case 223:\r
-                    //0x1101???? add - ri10 + pr08 + oi14 = 32 / 8 = 4\r
-                    p = CCSParser.parseStm(StmEnum.Add, args, bytes, p, 4, ReferenceType.ForeignShort, ReferenceType.Local);\r
-                    break;\r
-                case 224: case 225: case 226: case 227:\r
-                case 228: case 229: case 230: case 231:\r
-                case 232: case 233: case 234: case 235:\r
-                case 236: case 237: case 238: case 239:\r
-                    //0x1110???? add - ri10 + pr08 + oc62 = 80 / 8 = 10 \r
-                    p = CCSParser.parseStm(StmEnum.Add, args, bytes, p, 4, ReferenceType.ForeignShort, ReferenceType.ForeignLong);\r
-                    break;\r
-                case 240: case 241: case 242: case 243:\r
-                case 244: case 245: case 246: case 247:\r
-                case 248: case 249: case 250: case 251:\r
-                case 252: case 253: case 254: case 255:\r
-                    //0x1111???? add - ri10 + pc62 + or08 = 80 / 8 = 10 \r
-                    p = CCSParser.parseStm(StmEnum.Add, args, bytes, p, 4, ReferenceType.ForeignLong, ReferenceType.ForeignShort);\r
-                    break;\r
-                default:\r
-                    throw new RuntimeException("Internal error, contact application support.");\r
-            }\r
-        }\r
-        return p - pb;\r
-    }\r
-    private static class ClusterChangeSetBlock {\r
-        ClusterChangeSetBlock(int offset, int size, byte[] bytes) {\r
-            this.bytes = bytes;\r
-            this.offset = offset;\r
-            this.size = size;\r
-        }\r
-        byte[] bytes;\r
-        int offset;\r
-        int size;\r
-    }\r
-    private static class Blocks {\r
-        Blocks() {\r
-            mBlocks = new Vector<ClusterChangeSetBlock>();\r
-            mBlocks.ensureCapacity(BLOCK_INCREMENT);\r
-        }\r
-        int size() {\r
-            return mBlocks.size();\r
-        }\r
-        void push_back(ClusterChangeSetBlock ar) {\r
-            if (mBlocks.size() == mBlocks.capacity())\r
-                mBlocks.ensureCapacity(mBlocks.size() + BLOCK_INCREMENT);\r
-            mBlocks.add(ar);\r
-        }\r
-        ClusterChangeSetBlock get(int i) {\r
-            return mBlocks.get(i);\r
-        }\r
-        // How many block elements are allocated when out of space.\r
-        private static final int BLOCK_INCREMENT = 10;\r
-        private Vector<ClusterChangeSetBlock> mBlocks;\r
-    }\r
-    private static class Iterator implements IteratorI {\r
-        Iterator(int lastBlock) {\r
-            this.lastBlock = lastBlock;\r
-            this.foreignTable = new CCSParser.ForeignTable(); \r
-        }\r
-        int lastBlock;\r
-        int block;\r
-        int offset;\r
-        CCSParser.ForeignTable foreignTable;\r
-    }\r
-    private Blocks mBlocks = new Blocks();\r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.db.procore.cluster;
+
+import java.util.Vector;
+
+import org.simantics.db.exception.InternalException;
+import org.simantics.db.exception.RuntimeDatabaseException;
+import org.simantics.db.procore.cluster.CCSParser.ReferenceType;
+import org.simantics.db.procore.cluster.CCSParser.StmEnum;
+import org.simantics.db.service.ClusterUID;
+
+public class ClusterChangeSet implements ClusterChangeSetI {
+    static interface IteratorI {
+    }
+    static private final boolean DEBUG = false;
+    static private final int HEADER_SIZE = 20;
+    private final int version;
+    private final ClusterUID clusterUID;
+    private final byte[] bytes;
+
+    public static ClusterChangeSetI create(byte[] rawData, String compressionCodec)
+    throws InternalException {
+        
+        // TODO: Find maybe a better way to do this
+        byte[] bytes;
+        if (compressionCodec.equals("LZ4")) {
+            LZ4.DecompressStruct data = LZ4.decompress(rawData);
+            bytes = data.bytes;
+        } else if (compressionCodec.equals("FLZ")) {
+            FastLZ.DecompressStruct data = FastLZ.decompress(rawData);
+            bytes = data.bytes;
+        } else {
+            throw new RuntimeDatabaseException("No compressionCodec given!");
+        }
+        return new ClusterChangeSet(bytes);
+    }
+    @Override
+    public String toString() {
+        return "cid=" + clusterUID + " len=" + bytes.length; 
+    }
+    private ClusterChangeSet(byte[] abytes) {
+        this.bytes = abytes;
+        if (bytes.length < HEADER_SIZE + 4)
+            throw new RuntimeDatabaseException("Cluster change must contain header and size. length=" + bytes.length);
+        version = CCSParser.getInt(bytes, 0);
+        if (version <1 || version > 2)
+            throw new RuntimeDatabaseException("Unsupported cluster change set version=" + version);
+        clusterUID = ClusterUID.make(abytes, 4);
+        if (ClusterUID.Null.equals(clusterUID))
+            throw new RuntimeDatabaseException("Cluster uid can not be null.");
+        if (DEBUG)
+            System.out.println("DEBUG: Cluster uid=" + clusterUID);
+        int p = HEADER_SIZE;
+        int size = CCSParser.getInt(bytes, p);
+        if (2 == version) {
+            System.out.println("Cluster change set version=2 is not supported. skipping...");
+            return;
+        }
+        for (; size > 0; size = CCSParser.getInt(bytes, p)) {
+            mBlocks.push_back(new ClusterChangeSetBlock(p+=4, size, bytes));
+            p += size; // skip block data
+        } 
+    }
+    @Override
+    public ClusterUID getClusterUID() {
+        return clusterUID;
+    }
+    private boolean updateRequired() {
+        return false;
+    }
+    private void update() {
+    }
+    @Override
+    public void getNextOperation(Operation ar) {
+        Iterator pIterator = null;
+        if (null == ar.iterator) {
+            if (updateRequired())
+                this.update();
+            int N = mBlocks.size();
+            if (0 ==  N) {
+                ar.type = OperationEnum.EndOf;
+                return;
+            }
+            pIterator = new Iterator(N-1);
+            ar.iterator = pIterator;
+        } else
+            pIterator = (Iterator)ar.iterator;
+        if (pIterator.block > pIterator.lastBlock) {
+            ar.type = OperationEnum.EndOf;
+            ar.iterator = null;
+            return;
+        } else if (pIterator.offset >= mBlocks.get(pIterator.block).size) {
+            ++pIterator.block;
+            pIterator.foreignTable.init();
+            pIterator.offset = 0;
+            if (pIterator.block > pIterator.lastBlock) {
+                ar.type = OperationEnum.EndOf;
+                ar.iterator = null;
+                return;
+            }
+        }
+        if (pIterator.offset >= mBlocks.get(pIterator.block).size) {
+            ++pIterator.block;
+            pIterator.foreignTable.init();
+            pIterator.offset = 0;
+            if (pIterator.block > pIterator.lastBlock) {
+                ar.type = OperationEnum.EndOf;
+                ar.iterator = null;
+                return;
+            }
+        }
+        ClusterChangeSetBlock r = mBlocks.get(pIterator.block);
+        int inc = next(ar, pIterator, r.bytes, r.offset + pIterator.offset, r.offset + r.size);
+        if (inc <= 0) {
+            if (inc < 0)
+                System.out.println("Iterarto offset increment is negative!");
+            ar.type = OperationEnum.EndOf;
+            ar.iterator = null;
+        } else
+            pIterator.offset += inc;
+    }
+    private int next(Operation ar, Iterator pIterator, byte[] bytes, int ab, int ae) {
+        CCSParser.Args args = new CCSParser.Args(clusterUID, pIterator.foreignTable, ar);
+        final int pe = ae;
+        final int pb = ab;
+        int p = pb;
+        if (p < pe) {
+            if (DEBUG)
+                System.out.println("CCS.next offset=" + p);
+            short ri = 0; // resource index
+            short kraa = (short)(bytes[p] & 0xFF); 
+            switch (kraa) {
+                case 0: case 1: case 2: case 3:
+                    //0x000000?? add - ri12 + pi14 + oi14 = 40 / 8 = 5
+                    p = CCSParser.parseStm(StmEnum.Add, args, bytes, p, 2, ReferenceType.Local, ReferenceType.Local);
+                    break;
+                case 4: case 5: case 6: case 7:
+                    //0x000001?? rem - ri12 + pi14 + oi14 = 40 / 8 = 5
+                    p = CCSParser.parseStm(StmEnum.Remove, args, bytes, p, 2, ReferenceType.Local, ReferenceType.Local);
+                    break;
+                case 8: case 9: case 10: case 11:
+                    //0x000010?? add - ri12 + pi14 + oc62 = 88 / 8 = 11
+                    p = CCSParser.parseStm(StmEnum.Add, args, bytes, p, 2, ReferenceType.Local, ReferenceType.ForeignLong);
+                    break;
+                case 12: case 13: case 14: case 15:
+                    //0x000011?? rem - ri12 + pi14 + oc62 = 88 / 8 = 11
+                    p = CCSParser.parseStm(StmEnum.Remove, args, bytes, p, 2, ReferenceType.Local, ReferenceType.ForeignLong);
+                    break;
+                case 16: case 17: case 18: case 19:
+                    //0x000100?? add - ri12 + pc62 + oi14 = 88 / 8 = 11
+                    p = CCSParser.parseStm(StmEnum.Add, args, bytes, p, 2, ReferenceType.ForeignLong, ReferenceType.Local);
+                    break;
+                case 20: case 21: case 22: case 23:
+                    //0x000101?? rem - ri12 + pc62 + oi14 = 88 / 8 = 11
+                    p = CCSParser.parseStm(StmEnum.Remove, args, bytes, p, 2, ReferenceType.ForeignLong, ReferenceType.Local);
+                    break;
+                case 24: case 25: case 26: case 27:
+                    //0x000110?? add - ri12 + pc62 + oc62 = 136 / 8 = 17
+                    p = CCSParser.parseStm(StmEnum.Add, args, bytes, p, 2, ReferenceType.ForeignLong, ReferenceType.ForeignLong);
+                    break;
+                case 28: case 29: case 30: case 31:
+                    //0x000111?? rem - ri12 + pc62 + oc62 = 136 / 8 = 17
+                    p = CCSParser.parseStm(StmEnum.Remove, args, bytes, p, 2, ReferenceType.ForeignLong, ReferenceType.ForeignLong);
+                    break;
+                case 32: case 33: case 34: case 35:
+                case 36: case 37: case 38: case 39:
+                case 40: case 41: case 42: case 43:
+                case 44: case 45: case 46: case 47: case 48:
+                    //0x0010???? rem - ri10 + pr08 + oi14 = 32 / 8 = 4
+                    p = CCSParser.parseStm(StmEnum.Remove, args, bytes, p, 4, ReferenceType.ForeignShort, ReferenceType.Local);
+                    break;
+                case 49:
+                    //0x00110001 rem - ri14 + pi14 + pr08 + pad4 = 40 / 8 = 5
+                    p = CCSParser.parseStm(StmEnum.Remove, args, bytes, p, 0, ReferenceType.Local, ReferenceType.ForeignShort);
+                    break;
+                case 50:
+                    //0x00110010 rem - ri14 + pr08 + oc62 + pad4 = 88 / 8 = 11
+                    p = CCSParser.parseStm(StmEnum.Remove, args, bytes, p, 0, ReferenceType.ForeignShort, ReferenceType.ForeignLong);
+                    break;
+                case 51:
+                    //0x00110011 rem - ri14 + pc62 + or08 + pad4 = 88 / 8 = 11
+                    p = CCSParser.parseStm(StmEnum.Remove, args, bytes, p, 0, ReferenceType.ForeignLong, ReferenceType.ForeignShort);
+                    break;
+                case 52: //0x00110100 cre - ri14 + pad2 = 16 / 8 = 2
+                    ri = CCSParser.getShort(bytes, p+1);
+                    if (DEBUG)
+                        System.out.println("Creating resource r=" + ri + " rc=" + clusterUID);
+                    args.createResource(ri);
+                    p += 3;
+                    break;
+                case 53: {
+                    //0x00110101 set - ri14 + sz18 = 32 / 8 = 4 + sz * bytes
+                    int t = CCSParser.getInt(bytes, p + 1);
+                    ri = (short)(t & 0x3FFF); 
+                    int s = t >>> 14;
+                    args.setValue(ri, bytes, p + 5, s);
+                    p += 5 + s;
+                    break; }
+                case 54: //0x00110110 del - ri14 + pad2 = 16 / 8 = 2
+                    ri = CCSParser.getShort(bytes, p+1);
+                    args.deleteValue(ri);
+                    p += 3;
+                    break;
+                case 55: {
+                    //0x00110111 mod - ri14 + of58 + sz16  = 88 / 8 = 11 + sz * bytes
+                    ri = CCSParser.getShort(bytes, p+1);
+                    ri &= (1<<14)-1; // mask top 2 bits
+                    long vo = CCSParser.getLongN(bytes, p+3, 7); // get low 7 bytes
+                    vo |= (long)(bytes[p+2] & 0xC0) << (56-6); // add the top 2 bits
+                    p += 10;
+                    int vsize = CCSParser.getShort(bytes, p);
+                    if (vsize < 0)
+                        vsize += 65536;
+                    p += 2;
+                    if (DEBUG)
+                        System.out.println("Modifying value r=" + ri + " rc=" + args.clusterUID +
+                        " value offset=" + vo + " size=" + vsize);
+                    if (pe - p < vsize)
+                        throw new RuntimeException("Illegal size=" + vsize + " limit=" + (pe - p));
+                    args.modifyValue(ri, vo, vsize, bytes, p);
+                    p += vsize;
+                    break; }
+                case 56: case 57: case 58: case 59:
+                case 60: case 61: case 62: case 63: {
+                    //0x00111??? set - ri14 + sz2 = 16 / 8 = 2 + sz * bytes;
+                    byte s = (byte)(bytes[p] & 0x7);
+                    s <<= 2;
+                    ri = CCSParser.getShort(bytes, p+1);
+                    ri &= 0x3FFF; 
+                    byte t = bytes[p + 2];
+                    s |= (t &0xFF) >> 6;
+                    args.setValue(ri, bytes, p + 3, s);
+                    p += 3 + s;
+                    break; }
+                case 64: case 65: case 66: case 67:
+                case 68: case 69: case 70: case 71:
+                case 72: case 73: case 74: case 75:
+                case 76: case 77: case 78: case 79:
+                case 80: case 81: case 82: case 83:
+                case 84: case 85: case 86: case 87:
+                case 88: case 89: case 90: case 91:
+                case 92: case 93: case 94: case 95:
+                case 96: case 97: case 98: case 99:
+                case 100: case 101: case 102: case 103:
+                case 104: case 105: case 106: case 107:
+                case 108: case 109: case 110: case 111:
+                case 112: case 113: case 114: case 115:
+                case 116: case 117: case 118: case 119:
+                case 120: case 121: case 122: case 123:
+                case 124: case 125: case 126: case 127:
+                    //0x01?????? add - ri08 + pr08 + or08 = 24 / 8 = 3
+                    p = CCSParser.parseStm(StmEnum.Add, args, bytes, p, 6, ReferenceType.ForeignShort, ReferenceType.ForeignShort);
+                    break;
+                case 128: case 129: case 130: case 131:
+                case 132: case 133: case 134: case 135:
+                case 136: case 137: case 138: case 139:
+                case 140: case 141: case 142: case 143:
+                case 144: case 145: case 146: case 147:
+                case 148: case 149: case 150: case 151:
+                case 152: case 153: case 154: case 155:
+                case 156: case 157: case 158: case 159:
+                case 160: case 161: case 162: case 163:
+                case 164: case 165: case 166: case 167:
+                case 168: case 169: case 170: case 171:
+                case 172: case 173: case 174: case 175:
+                case 176: case 177: case 178: case 179:
+                case 180: case 181: case 182: case 183:
+                case 184: case 185: case 186: case 187:
+                case 188: case 189: case 190:case 191:
+                    //0x10?????? rem - ri08 + pr08 + or08 = 24 / 8 = 3
+                    p = CCSParser.parseStm(StmEnum.Remove, args, bytes, p, 6, ReferenceType.ForeignShort, ReferenceType.ForeignShort);
+                    break;
+                case 192: case 193: case 194: case 195:
+                case 196: case 197: case 198: case 199:
+                case 200: case 201: case 202: case 203:
+                case 204: case 205: case 206: case 207:
+                    //0x1100???? add - ri10 + pi14 + pr08 = 32 / 8 = 4
+                    p = CCSParser.parseStm(StmEnum.Add, args, bytes, p, 4, ReferenceType.Local, ReferenceType.ForeignShort);
+                    break;
+                case 208: case 209: case 210: case 211:
+                case 212: case 213: case 214: case 215:
+                case 216: case 217: case 218: case 219:
+                case 220: case 221: case 222: case 223:
+                    //0x1101???? add - ri10 + pr08 + oi14 = 32 / 8 = 4
+                    p = CCSParser.parseStm(StmEnum.Add, args, bytes, p, 4, ReferenceType.ForeignShort, ReferenceType.Local);
+                    break;
+                case 224: case 225: case 226: case 227:
+                case 228: case 229: case 230: case 231:
+                case 232: case 233: case 234: case 235:
+                case 236: case 237: case 238: case 239:
+                    //0x1110???? add - ri10 + pr08 + oc62 = 80 / 8 = 10 
+                    p = CCSParser.parseStm(StmEnum.Add, args, bytes, p, 4, ReferenceType.ForeignShort, ReferenceType.ForeignLong);
+                    break;
+                case 240: case 241: case 242: case 243:
+                case 244: case 245: case 246: case 247:
+                case 248: case 249: case 250: case 251:
+                case 252: case 253: case 254: case 255:
+                    //0x1111???? add - ri10 + pc62 + or08 = 80 / 8 = 10 
+                    p = CCSParser.parseStm(StmEnum.Add, args, bytes, p, 4, ReferenceType.ForeignLong, ReferenceType.ForeignShort);
+                    break;
+                default:
+                    throw new RuntimeException("Internal error in cluster stream (v=" + kraa + ")");
+            }
+        }
+        return p - pb;
+    }
+    private static class ClusterChangeSetBlock {
+        ClusterChangeSetBlock(int offset, int size, byte[] bytes) {
+            this.bytes = bytes;
+            this.offset = offset;
+            this.size = size;
+        }
+        byte[] bytes;
+        int offset;
+        int size;
+    }
+    private static class Blocks {
+        Blocks() {
+            mBlocks = new Vector<ClusterChangeSetBlock>();
+            mBlocks.ensureCapacity(BLOCK_INCREMENT);
+        }
+        int size() {
+            return mBlocks.size();
+        }
+        void push_back(ClusterChangeSetBlock ar) {
+            if (mBlocks.size() == mBlocks.capacity())
+                mBlocks.ensureCapacity(mBlocks.size() + BLOCK_INCREMENT);
+            mBlocks.add(ar);
+        }
+        ClusterChangeSetBlock get(int i) {
+            return mBlocks.get(i);
+        }
+        // How many block elements are allocated when out of space.
+        private static final int BLOCK_INCREMENT = 10;
+        private Vector<ClusterChangeSetBlock> mBlocks;
+    }
+    private static class Iterator implements IteratorI {
+        Iterator(int lastBlock) {
+            this.lastBlock = lastBlock;
+            this.foreignTable = new CCSParser.ForeignTable(); 
+        }
+        int lastBlock;
+        int block;
+        int offset;
+        CCSParser.ForeignTable foreignTable;
+    }
+    private Blocks mBlocks = new Blocks();
+}