/******************************************************************************* * Copyright (c) 2007, 2010 Association for Decentralized Information Management * in Industry THTH ry. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.acorn.internal; final public class ClusterStream { // // public static long duration2 = 0; // public static final boolean DEBUG = false; public static final byte NULL_OPERATION = 0; public static final byte CREATE_OPERATION = 1; public static final byte SET_OPERATION = 4; public static final byte MODI_OPERATION = 6; public static final byte KILL_OPERATION = 7; // boolean off = false; // public GraphSession graphSession; // final SessionImplSocket session; //// private int flushCount = 0; // final private boolean alwaysOff; // private int stamp; // private int acceptedStamp; // private boolean dirty = false; //// final private ArrayList clusterChanges = new ArrayList(); // // final ClusterChangeManager changes = new ClusterChangeManager(); // //// final TLongObjectHashMap clusterChanges = new TLongObjectHashMap(); // // // private final Change lastChange = new Change(); // ClusterStream(SessionImplSocket session, GraphSession graphSession, // boolean alwaysOff) { // this.session = session; // this.graphSession = graphSession; // this.alwaysOff = alwaysOff; // } // // // boolean isDirty() { // return dirty; // } // // void markDirty() { // dirty = true; // } // // void setOff(boolean value) { // if (alwaysOff) { // off = true; // } else { // off = value; // } // } // // boolean getOff() { // return off; // } // // void createResource(ClusterChange cc, short operationIndex, ClusterUID clusterUID) { // if (off) // return; // assert (null != cc); // assert (0 != operationIndex); // assert (!ClusterUID.Null.equals(clusterUID)); // if (DEBUG) // System.out.println("DEBUG: Created resource index=" + operationIndex + " cluster=" + clusterUID); // cc.createResource(operationIndex); // } // // final void addStatementIndex(Change change, int key, ClusterUID clusterUID, byte op) { // if (off) // return; // assert (key > 0); // assert (null != change); // assert (!ClusterUID.Null.equals(clusterUID)); // change.addStatementIndex(key, clusterUID, op); // } // // void addStatement(ClusterChange cc, Change change) { // if (off) // return; // assert (null != cc); // assert (null != change); // cc.addChange(change); // } // // void cancelStatement(Change change) { // if (off) // return; // assert (null != change); // change.init(); // } // // void removeStatement(ClusterChange cc, Change change, long clusterId) { // if (off) // return; // assert (null != cc); // assert (null != change); // cc.addChange(change); // } // // void cancelValue(Change change) { // if (off) // return; // assert (null != change); // change.init(); // } // // void removeValue(ClusterChange cc, Change change, long clusterId) { // if (off) // return; // // ClusterChange cc = getClusterChange(clusterId); // assert (null != cc); // assert (null != change); // cc.addChange(change); // } // // void setValue(ClusterChange cc, Change change, long clusterId, byte[] bytes, int length) { // if (off) // return; // assert (null != cc); // assert (null != change); // // ClusterChange cc = getClusterChange(clusterId); // cc.setValue(change, bytes, length); // } // // void modiValue(ClusterChange cc, Change change, long clusterId, // long voffset, int length, byte[] bytes, int offset) { // assert (null != cc); // assert (null != change); // cc.modiValue(change, voffset, length, bytes, offset); // } // // void undoValueEx(ClusterChange cc, Change change, int resourceIndex) { // cc.undoValueEx(resourceIndex); // } // void setImmutable(ClusterChange cc, Change change, long clusterId, boolean immutable) { // if (off) // return; // cc.setImmutable(immutable); // } // public void corruptCluster(ClusterChange cc, long clusterId) // throws DatabaseException { // if (off) // return; // if (DEBUG) // System.out.println("ClusterStream.corrupt cid=" + clusterId + "."); // assert (null != cc); // cc.corrupt(); // } // // int getStamp() { // return stamp; // } // // void flush() { // if (off) // return; //// flushCount++; // return; // } // // void flush(long clusterId) { // if (off) // return; // ClusterUID clusterUID = session.clusterTable.clusterIds.getClusterUID(clusterId); // ArrayList ccs = new ArrayList(); // for(ClusterChange cc : changes.get()) { // if(cc.clusterUID.equals(clusterUID)) { // if (cc.flush(graphSession, cc.clusterUID)) { // ccs.add(cc); // if (stamp == acceptedStamp) // ++stamp; // } else { //// System.err.println("kasdi"); // } // } // } // changes.remove(ccs); // } // // /** // * @return true if the stream has accepted all changes // */ // public boolean reallyFlush() { // // Last possibility to mark clusters immutable before write only clusters are gone // session.handleCreatedClusters(); // // These shall be requested from server // session.clusterTable.removeWriteOnlyClusters(); // if (!off && changes.size() > 0) { // for(ClusterChange cc : changes.get()) { // if (cc.flush(graphSession, cc.clusterUID)) // if (stamp == acceptedStamp) // ++stamp; // } // changes.clear(); // } // dirty = false; // return hasAcceptedAllChanges(); // } // // /** // * Clear all changes and set stream status to empty. // */ // public void clear() { // changes.clear(); // acceptedStamp = stamp; // dirty = false; // } // // private boolean hasAcceptedAllChanges() { // return stamp == acceptedStamp; // } // // void accept() { // acceptedStamp = stamp; // } // // static class DebugInfo { long nStms; long nLocal; long nPartly; long nForeign; long nValues; long sValues; long sForeign; long tot; void clear() { nStms = 0; nLocal = 0; nPartly = 0; nForeign = 0; sForeign = 0; nValues = 0; sValues = 0; tot = 0; } void add(DebugInfo di) { nStms += di.nStms; nLocal += di.nLocal; nPartly += di.nPartly; nForeign += di.nForeign; sForeign += di.sForeign; nValues += di.nValues; sValues += di.sValues; tot += di.tot; } @Override public String toString() { return "val=" + nValues + " stm=" + nStms + " loc=" + nLocal + " par=" + nPartly + " ful=" + nForeign + " for=" + sForeign + " vat=" + sValues + " tot=" + tot; } } enum StmEnum { Add(0, (byte) 0), Remove(1, (byte) 0x20); StmEnum(int ordinal, byte mask) { this.ordinal = ordinal; this.mask = mask; } public int ordinal; private byte mask; byte getOrMask() { return mask; } } final static class Data { final byte mask; // or mask for operation code (don't care bits are zero) final short bits; // how many bits are reserved for resource index (0,2,4,6) final int bytes; Data(int mask, int bits, ClusterEnum a, ClusterEnum b) { this.mask = (byte) (mask << bits); this.bits = (short) bits; this.bytes = bytes(bits, a, b); } private static int bytes(int bits, ClusterEnum a, ClusterEnum b) { int left = 6 - bits; if (a != ClusterEnum.ForeignShort) { left += 6; } if (b != ClusterEnum.ForeignShort) { left += 6; } int bytes = left >>> 3; if ((left & 7) != 0) bytes++; return bytes; } } enum ClusterEnum { Local(0), ForeignShort(1), ForeignLong(2); public int ordinal; ClusterEnum(int ordinal) { this.ordinal = ordinal; } static Data[][][] maps = new Data[2][3][3]; static { // mask: 00000000 // op: 000000|r12-13 // p1 // o1 // r0-7 // o2 | p2 | r8-11 maps[StmEnum.Add.ordinal][Local.ordinal][Local.ordinal] = new Data( 0, 2, Local, Local); // mask: 11000000 // op: 1100 | r10-13 // p1 // o for index // r0-7 // p2 | ri 8-9 maps[StmEnum.Add.ordinal][Local.ordinal][ForeignShort.ordinal] = new Data( 12, 4, Local, ForeignShort); // mask: 00001000 // op: 000010 | r12-13 maps[StmEnum.Add.ordinal][Local.ordinal][ForeignLong.ordinal] = new Data( 2, 2, Local, ForeignLong); // mask: 11010000 // op: 1101 | r10-13 maps[StmEnum.Add.ordinal][ForeignShort.ordinal][Local.ordinal] = new Data( 13, 4, ForeignShort, Local); // mask: 01000000 // op: 01 | r8-13 // p for index // o for index // r0-7 maps[StmEnum.Add.ordinal][ForeignShort.ordinal][ForeignShort.ordinal] = new Data( 1, 6, ForeignShort, ForeignShort); // mask: 11100000 // op: 1110 | r10-13 maps[StmEnum.Add.ordinal][ForeignShort.ordinal][ForeignLong.ordinal] = new Data( 14, 4, ForeignShort, ForeignLong); // mask: 00010000 // op: 000100 | r12-13 maps[StmEnum.Add.ordinal][ForeignLong.ordinal][Local.ordinal] = new Data( 4, 2, ForeignLong, Local); // mask: 11110000 // op: 1111 | r10-13 maps[StmEnum.Add.ordinal][ForeignLong.ordinal][ForeignShort.ordinal] = new Data( 15, 4, ForeignLong, ForeignShort); // mask: 00011000 // op: 000110 | r12-13 maps[StmEnum.Add.ordinal][ForeignLong.ordinal][ForeignLong.ordinal] = new Data( 6, 2, ForeignLong, ForeignLong); // mask: 00000100 // op: 000001 | r12-13 maps[StmEnum.Remove.ordinal][Local.ordinal][Local.ordinal] = new Data( 1, 2, Local, Local); // mask: 01100001 // op: 01100001 // p1 // o for index // r0-7 // p2 | ri 8-13 maps[StmEnum.Remove.ordinal][Local.ordinal][ForeignShort.ordinal] = new Data( 49, 0, Local, ForeignShort); // mask: 00001100 // op: 000011 | r12-13 maps[StmEnum.Remove.ordinal][Local.ordinal][ForeignLong.ordinal] = new Data( 3, 2, Local, ForeignLong); // mask: 00100000 // op: 0010 | r10-13 maps[StmEnum.Remove.ordinal][ForeignShort.ordinal][Local.ordinal] = new Data( 2, 4, ForeignShort, Local); // mask: 10000000 // op: 10 | r8-13 maps[StmEnum.Remove.ordinal][ForeignShort.ordinal][ForeignShort.ordinal] = new Data( 2, 6, ForeignShort, ForeignShort); // mask: 00110010 // op: 00110010 maps[StmEnum.Remove.ordinal][ForeignShort.ordinal][ForeignLong.ordinal] = new Data( 50, 0, ForeignShort, ForeignLong); // mask: 00010100 // op: 000101 | r12-13 maps[StmEnum.Remove.ordinal][ForeignLong.ordinal][Local.ordinal] = new Data( 5, 2, ForeignLong, Local); // mask: 00110011 // op: 00110011 maps[StmEnum.Remove.ordinal][ForeignLong.ordinal][ForeignShort.ordinal] = new Data( 51, 0, ForeignLong, ForeignShort); // mask: 00011100 // op: 000111 | r12-13 maps[StmEnum.Remove.ordinal][ForeignLong.ordinal][ForeignLong.ordinal] = new Data( 7, 2, ForeignLong, ForeignLong); } static Data getData(StmEnum s, ClusterEnum a, ClusterEnum b) { return maps[s.ordinal][a.ordinal][b.ordinal]; // return maps.get(s).get(a).get(b); } } enum OpEnum { Create((byte) 52), Set((byte) 53), SetShort((byte) 56), Delete( (byte) 54), Modify((byte) 55); OpEnum(byte mask) { this.mask = mask; } public byte getOrMask() { return mask; } private byte mask; } }