X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.db.procore%2Fsrc%2Forg%2Fsimantics%2Fdb%2Fprocore%2Fcluster%2FClusterChangeSet.java;fp=bundles%2Forg.simantics.db.procore%2Fsrc%2Forg%2Fsimantics%2Fdb%2Fprocore%2Fcluster%2FClusterChangeSet.java;h=172af9ca8de7859424e51aaee59b9cddccb9ce14;hp=0000000000000000000000000000000000000000;hb=969bd23cab98a79ca9101af33334000879fb60c5;hpb=866dba5cd5a3929bbeae85991796acb212338a08 diff --git a/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ClusterChangeSet.java b/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ClusterChangeSet.java new file mode 100644 index 000000000..172af9ca8 --- /dev/null +++ b/bundles/org.simantics.db.procore/src/org/simantics/db/procore/cluster/ClusterChangeSet.java @@ -0,0 +1,358 @@ +/******************************************************************************* + * 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, contact application support."); + } + } + 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(); + 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 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(); +}