]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.acorn/src/org/simantics/acorn/internal/ClusterStream.java
Sharing org.simantics.acorn for everyone to use
[simantics/platform.git] / bundles / org.simantics.acorn / src / org / simantics / acorn / internal / ClusterStream.java
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 (file)
index 0000000..2b1ae19
--- /dev/null
@@ -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<ClusterChange> clusterChanges = new ArrayList<ClusterChange>();
+//    
+//    final ClusterChangeManager changes = new ClusterChangeManager();
+//    
+////    final TLongObjectHashMap<ClusterChange> clusterChanges = new TLongObjectHashMap<ClusterChange>();
+//
+//    // 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<ClusterChange> ccs = new ArrayList<ClusterChange>();
+//        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;
+    }
+}