3 import java.nio.ByteBuffer;
5 import java.util.HashSet;
8 class Transaction extends Entry {
11 private long machineid;
12 private Set<KeyValue> keyValueUpdateSet = null;
13 private Set<KeyValue> keyValueGuardSet = null;
14 private Long arbitrator;
16 public Transaction(Slot slot, long _seqnum, long _machineid, Long _arbitrator, Set<KeyValue> _keyValueUpdateSet, Set<KeyValue> _keyValueGuardSet) {
19 machineid = _machineid;
20 arbitrator = _arbitrator;
21 // keyValueUpdateSet = new HashSet<KeyValue>();
22 // keyValueGuardSet = new HashSet<KeyValue>();
24 // for (KeyValue kv : _keyValueUpdateSet) {
25 // KeyValue kvCopy = kv.getCopy();
26 // keyValueUpdateSet.add(kvCopy);
29 // for (KeyValue kv : _keyValueGuardSet) {
30 // KeyValue kvCopy = kv.getCopy();
31 // keyValueGuardSet.add(kvCopy);
34 keyValueUpdateSet = _keyValueUpdateSet;
35 keyValueGuardSet = _keyValueGuardSet;
38 public long getMachineID() {
42 public long getArbitrator() {
46 public long getSequenceNumber() {
50 public Set<KeyValue> getkeyValueUpdateSet() {
51 return keyValueUpdateSet;
54 public Set<KeyValue> getkeyValueGuardSet() {
55 return keyValueGuardSet;
58 public boolean evaluateGuard(Map<IoTString, KeyValue> keyValTableCommitted, Map<IoTString, KeyValue> keyValTableSpeculative) {
59 for (KeyValue kvGuard : keyValueGuardSet) {
61 // First check if the key is in the speculative table, this is the value of the latest assumption
62 KeyValue kv = keyValTableSpeculative.get(kvGuard.getKey());
66 // if it is not in the speculative table then check the committed table and use that
67 // value as our latest assumption
68 kv = keyValTableCommitted.get(kvGuard.getKey());
69 // System.out.println("Replaced With Commit Table");
72 if (kvGuard.getValue() != null) {
73 if ((kv == null) || (!kvGuard.getValue().equals(kv.getValue()))) {
74 // System.out.println("Fail 1 " + (kv == null) + " " + kvGuard.getValue() + " " + kv.getValue());
79 // System.out.println("Fail 2 " + kv.getValue());
87 public byte getType() {
88 return Entry.TypeTransaction;
91 public int getSize() {
92 int size = 3 * Long.BYTES + Byte.BYTES; // seq, machine id, entry type
93 size += Integer.BYTES; // number of KV's
94 size += Integer.BYTES; // number of Guard KV's
97 for (KeyValue kv : keyValueUpdateSet) {
101 // Size of each Guard KV
102 for (KeyValue kv : keyValueGuardSet) {
103 size += kv.getSize();
109 public void encode(ByteBuffer bb) {
110 bb.put(Entry.TypeTransaction);
112 bb.putLong(machineid);
113 bb.putLong(arbitrator);
115 bb.putInt(keyValueUpdateSet.size());
116 for (KeyValue kv : keyValueUpdateSet) {
120 bb.putInt(keyValueGuardSet.size());
121 for (KeyValue kv : keyValueGuardSet) {
126 static Entry decode(Slot slot, ByteBuffer bb) {
127 long seqnum = bb.getLong();
128 long machineid = bb.getLong();
129 long arbitrator = bb.getLong();
130 int numberOfKeys = bb.getInt();
132 Set<KeyValue> kvSetUpdates = new HashSet<KeyValue>();
133 for (int i = 0; i < numberOfKeys; i++) {
134 KeyValue kv = KeyValue.decode(bb);
135 kvSetUpdates.add(kv);
138 int numberOfGuards = bb.getInt();
139 Set<KeyValue> kvSetGuards = new HashSet<KeyValue>();
140 for (int i = 0; i < numberOfGuards; i++) {
141 KeyValue kv = KeyValue.decode(bb);
145 return new Transaction(slot, seqnum, machineid, arbitrator, kvSetUpdates, kvSetGuards);
148 public Entry getCopy(Slot s) {
149 return new Transaction(s, seqnum, machineid, arbitrator, keyValueUpdateSet, keyValueGuardSet);