X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.acorn%2Fsrc%2Forg%2Fsimantics%2Facorn%2Finternal%2FClusterStream.java;fp=bundles%2Forg.simantics.acorn%2Fsrc%2Forg%2Fsimantics%2Facorn%2Finternal%2FClusterStream.java;h=2b1ae1979b1de072faf8c19bc7dc37faa3ac87db;hb=a0687ce02bac73aad9e0d7ddc85625016604f0db;hp=0000000000000000000000000000000000000000;hpb=be5eb160a811a04ecd6364ebb58f24e8218d3f9c;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.acorn/src/org/simantics/acorn/internal/ClusterStream.java b/bundles/org.simantics.acorn/src/org/simantics/acorn/internal/ClusterStream.java new file mode 100644 index 000000000..2b1ae1979 --- /dev/null +++ b/bundles/org.simantics.acorn/src/org/simantics/acorn/internal/ClusterStream.java @@ -0,0 +1,437 @@ +/******************************************************************************* + * 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; + +import java.util.ArrayList; + +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.service.ClusterUID; + +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; + } +}