1 /*******************************************************************************
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.acorn.internal;
14 import java.util.ArrayList;
16 import org.simantics.db.exception.DatabaseException;
17 import org.simantics.db.service.ClusterUID;
19 final public class ClusterStream {
21 // // public static long duration2 = 0;
23 public static final boolean DEBUG = false;
24 public static final byte NULL_OPERATION = 0;
25 public static final byte CREATE_OPERATION = 1;
26 public static final byte SET_OPERATION = 4;
27 public static final byte MODI_OPERATION = 6;
28 public static final byte KILL_OPERATION = 7;
29 // boolean off = false;
30 // public GraphSession graphSession;
31 // final SessionImplSocket session;
32 //// private int flushCount = 0;
33 // final private boolean alwaysOff;
35 // private int acceptedStamp;
36 // private boolean dirty = false;
37 //// final private ArrayList<ClusterChange> clusterChanges = new ArrayList<ClusterChange>();
39 // final ClusterChangeManager changes = new ClusterChangeManager();
41 //// final TLongObjectHashMap<ClusterChange> clusterChanges = new TLongObjectHashMap<ClusterChange>();
43 // // private final Change lastChange = new Change();
44 // ClusterStream(SessionImplSocket session, GraphSession graphSession,
45 // boolean alwaysOff) {
46 // this.session = session;
47 // this.graphSession = graphSession;
48 // this.alwaysOff = alwaysOff;
52 // boolean isDirty() {
60 // void setOff(boolean value) {
72 // void createResource(ClusterChange cc, short operationIndex, ClusterUID clusterUID) {
75 // assert (null != cc);
76 // assert (0 != operationIndex);
77 // assert (!ClusterUID.Null.equals(clusterUID));
79 // System.out.println("DEBUG: Created resource index=" + operationIndex + " cluster=" + clusterUID);
80 // cc.createResource(operationIndex);
83 // final void addStatementIndex(Change change, int key, ClusterUID clusterUID, byte op) {
87 // assert (null != change);
88 // assert (!ClusterUID.Null.equals(clusterUID));
89 // change.addStatementIndex(key, clusterUID, op);
92 // void addStatement(ClusterChange cc, Change change) {
95 // assert (null != cc);
96 // assert (null != change);
97 // cc.addChange(change);
100 // void cancelStatement(Change change) {
103 // assert (null != change);
107 // void removeStatement(ClusterChange cc, Change change, long clusterId) {
110 // assert (null != cc);
111 // assert (null != change);
112 // cc.addChange(change);
115 // void cancelValue(Change change) {
118 // assert (null != change);
122 // void removeValue(ClusterChange cc, Change change, long clusterId) {
125 // // ClusterChange cc = getClusterChange(clusterId);
126 // assert (null != cc);
127 // assert (null != change);
128 // cc.addChange(change);
131 // void setValue(ClusterChange cc, Change change, long clusterId, byte[] bytes, int length) {
134 // assert (null != cc);
135 // assert (null != change);
136 // // ClusterChange cc = getClusterChange(clusterId);
137 // cc.setValue(change, bytes, length);
140 // void modiValue(ClusterChange cc, Change change, long clusterId,
141 // long voffset, int length, byte[] bytes, int offset) {
142 // assert (null != cc);
143 // assert (null != change);
144 // cc.modiValue(change, voffset, length, bytes, offset);
147 // void undoValueEx(ClusterChange cc, Change change, int resourceIndex) {
148 // cc.undoValueEx(resourceIndex);
150 // void setImmutable(ClusterChange cc, Change change, long clusterId, boolean immutable) {
153 // cc.setImmutable(immutable);
155 // public void corruptCluster(ClusterChange cc, long clusterId)
156 // throws DatabaseException {
160 // System.out.println("ClusterStream.corrupt cid=" + clusterId + ".");
161 // assert (null != cc);
176 // void flush(long clusterId) {
179 // ClusterUID clusterUID = session.clusterTable.clusterIds.getClusterUID(clusterId);
180 // ArrayList<ClusterChange> ccs = new ArrayList<ClusterChange>();
181 // for(ClusterChange cc : changes.get()) {
182 // if(cc.clusterUID.equals(clusterUID)) {
183 // if (cc.flush(graphSession, cc.clusterUID)) {
185 // if (stamp == acceptedStamp)
188 //// System.err.println("kasdi");
192 // changes.remove(ccs);
196 // * @return true if the stream has accepted all changes
198 // public boolean reallyFlush() {
199 // // Last possibility to mark clusters immutable before write only clusters are gone
200 // session.handleCreatedClusters();
201 // // These shall be requested from server
202 // session.clusterTable.removeWriteOnlyClusters();
203 // if (!off && changes.size() > 0) {
204 // for(ClusterChange cc : changes.get()) {
205 // if (cc.flush(graphSession, cc.clusterUID))
206 // if (stamp == acceptedStamp)
212 // return hasAcceptedAllChanges();
216 // * Clear all changes and set stream status to empty.
218 // public void clear() {
220 // acceptedStamp = stamp;
224 // private boolean hasAcceptedAllChanges() {
225 // return stamp == acceptedStamp;
229 // acceptedStamp = stamp;
234 static class DebugInfo {
255 void add(DebugInfo di) {
258 nPartly += di.nPartly;
259 nForeign += di.nForeign;
260 sForeign += di.sForeign;
261 nValues += di.nValues;
262 sValues += di.sValues;
267 public String toString() {
268 return "val=" + nValues + " stm=" + nStms + " loc=" + nLocal
269 + " par=" + nPartly + " ful=" + nForeign + " for="
270 + sForeign + " vat=" + sValues + " tot=" + tot;
275 Add(0, (byte) 0), Remove(1, (byte) 0x20);
276 StmEnum(int ordinal, byte mask) {
277 this.ordinal = ordinal;
289 final static class Data {
291 final byte mask; // or mask for operation code (don't care bits are zero)
292 final short bits; // how many bits are reserved for resource index (0,2,4,6)
295 Data(int mask, int bits, ClusterEnum a, ClusterEnum b) {
296 this.mask = (byte) (mask << bits);
297 this.bits = (short) bits;
298 this.bytes = bytes(bits, a, b);
301 private static int bytes(int bits, ClusterEnum a, ClusterEnum b) {
303 if (a != ClusterEnum.ForeignShort) {
306 if (b != ClusterEnum.ForeignShort) {
309 int bytes = left >>> 3;
318 Local(0), ForeignShort(1), ForeignLong(2);
321 ClusterEnum(int ordinal) {
322 this.ordinal = ordinal;
325 static Data[][][] maps = new Data[2][3][3];
333 maps[StmEnum.Add.ordinal][Local.ordinal][Local.ordinal] = new Data(
341 maps[StmEnum.Add.ordinal][Local.ordinal][ForeignShort.ordinal] = new Data(
342 12, 4, Local, ForeignShort);
344 // op: 000010 | r12-13
345 maps[StmEnum.Add.ordinal][Local.ordinal][ForeignLong.ordinal] = new Data(
346 2, 2, Local, ForeignLong);
349 maps[StmEnum.Add.ordinal][ForeignShort.ordinal][Local.ordinal] = new Data(
350 13, 4, ForeignShort, Local);
357 maps[StmEnum.Add.ordinal][ForeignShort.ordinal][ForeignShort.ordinal] = new Data(
358 1, 6, ForeignShort, ForeignShort);
361 maps[StmEnum.Add.ordinal][ForeignShort.ordinal][ForeignLong.ordinal] = new Data(
362 14, 4, ForeignShort, ForeignLong);
364 // op: 000100 | r12-13
365 maps[StmEnum.Add.ordinal][ForeignLong.ordinal][Local.ordinal] = new Data(
366 4, 2, ForeignLong, Local);
369 maps[StmEnum.Add.ordinal][ForeignLong.ordinal][ForeignShort.ordinal] = new Data(
370 15, 4, ForeignLong, ForeignShort);
372 // op: 000110 | r12-13
373 maps[StmEnum.Add.ordinal][ForeignLong.ordinal][ForeignLong.ordinal] = new Data(
374 6, 2, ForeignLong, ForeignLong);
377 // op: 000001 | r12-13
378 maps[StmEnum.Remove.ordinal][Local.ordinal][Local.ordinal] = new Data(
386 maps[StmEnum.Remove.ordinal][Local.ordinal][ForeignShort.ordinal] = new Data(
387 49, 0, Local, ForeignShort);
389 // op: 000011 | r12-13
390 maps[StmEnum.Remove.ordinal][Local.ordinal][ForeignLong.ordinal] = new Data(
391 3, 2, Local, ForeignLong);
394 maps[StmEnum.Remove.ordinal][ForeignShort.ordinal][Local.ordinal] = new Data(
395 2, 4, ForeignShort, Local);
398 maps[StmEnum.Remove.ordinal][ForeignShort.ordinal][ForeignShort.ordinal] = new Data(
399 2, 6, ForeignShort, ForeignShort);
402 maps[StmEnum.Remove.ordinal][ForeignShort.ordinal][ForeignLong.ordinal] = new Data(
403 50, 0, ForeignShort, ForeignLong);
405 // op: 000101 | r12-13
406 maps[StmEnum.Remove.ordinal][ForeignLong.ordinal][Local.ordinal] = new Data(
407 5, 2, ForeignLong, Local);
410 maps[StmEnum.Remove.ordinal][ForeignLong.ordinal][ForeignShort.ordinal] = new Data(
411 51, 0, ForeignLong, ForeignShort);
413 // op: 000111 | r12-13
414 maps[StmEnum.Remove.ordinal][ForeignLong.ordinal][ForeignLong.ordinal] = new Data(
415 7, 2, ForeignLong, ForeignLong);
418 static Data getData(StmEnum s, ClusterEnum a, ClusterEnum b) {
419 return maps[s.ordinal][a.ordinal][b.ordinal];
420 // return maps.get(s).get(a).get(b);
425 Create((byte) 52), Set((byte) 53), SetShort((byte) 56), Delete(
426 (byte) 54), Modify((byte) 55);
431 public byte getOrMask() {