Changed way Guard works, Sped up code
[iotcloud.git] / version2 / src / java / iotcloud / Transaction.java
1 package iotcloud;
2
3 import java.nio.ByteBuffer;
4 import java.util.Set;
5 import java.util.HashSet;
6 import java.util.Map;
7
8 class Transaction extends Entry {
9
10     private long seqnum;
11     private long machineid;
12     private Set<KeyValue> keyValueUpdateSet = null;
13     private Set<KeyValue> keyValueGuardSet = null;
14     private Long arbitrator;
15
16     public Transaction(Slot slot, long _seqnum, long _machineid, Long _arbitrator, Set<KeyValue> _keyValueUpdateSet, Set<KeyValue> _keyValueGuardSet) {
17         super(slot);
18         seqnum = _seqnum;
19         machineid = _machineid;
20         arbitrator = _arbitrator;
21         // keyValueUpdateSet = new HashSet<KeyValue>();
22         // keyValueGuardSet = new HashSet<KeyValue>();
23
24         // for (KeyValue kv : _keyValueUpdateSet) {
25         //     KeyValue kvCopy = kv.getCopy();
26         //     keyValueUpdateSet.add(kvCopy);
27         // }
28
29         // for (KeyValue kv : _keyValueGuardSet) {
30         //     KeyValue kvCopy = kv.getCopy();
31         //     keyValueGuardSet.add(kvCopy);
32         // }
33
34         keyValueUpdateSet = _keyValueUpdateSet;
35         keyValueGuardSet = _keyValueGuardSet;
36     }
37
38     public long getMachineID() {
39         return machineid;
40     }
41
42     public long getArbitrator() {
43         return arbitrator;
44     }
45
46     public long getSequenceNumber() {
47         return seqnum;
48     }
49
50     public Set<KeyValue> getkeyValueUpdateSet() {
51         return keyValueUpdateSet;
52     }
53
54     public Set<KeyValue> getkeyValueGuardSet() {
55         return keyValueGuardSet;
56     }
57
58     public boolean evaluateGuard(Map<IoTString, KeyValue> keyValTableCommitted, Map<IoTString, KeyValue> keyValTableSpeculative) {
59         for (KeyValue kvGuard : keyValueGuardSet) {
60
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());
63
64             if (kv == null) {
65
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");
70             }
71
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());
75                     return false;
76                 }
77             } else {
78                 if (kv != null) {
79                     // System.out.println("Fail 2    " + kv.getValue());
80                     return false;
81                 }
82             }
83         }
84         return true;
85     }
86
87     public byte getType() {
88         return Entry.TypeTransaction;
89     }
90
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
95
96         // Size of each KV
97         for (KeyValue kv : keyValueUpdateSet) {
98             size += kv.getSize();
99         }
100
101         // Size of each Guard KV
102         for (KeyValue kv : keyValueGuardSet) {
103             size += kv.getSize();
104         }
105
106         return size;
107     }
108
109     public void encode(ByteBuffer bb) {
110         bb.put(Entry.TypeTransaction);
111         bb.putLong(seqnum);
112         bb.putLong(machineid);
113         bb.putLong(arbitrator);
114
115         bb.putInt(keyValueUpdateSet.size());
116         for (KeyValue kv : keyValueUpdateSet) {
117             kv.encode(bb);
118         }
119
120         bb.putInt(keyValueGuardSet.size());
121         for (KeyValue kv : keyValueGuardSet) {
122             kv.encode(bb);
123         }
124     }
125
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();
131
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);
136         }
137
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);
142             kvSetGuards.add(kv);
143         }
144
145         return new Transaction(slot, seqnum, machineid, arbitrator, kvSetUpdates, kvSetGuards);
146     }
147
148     public Entry getCopy(Slot s) {
149         return new Transaction(s, seqnum, machineid, arbitrator, keyValueUpdateSet, keyValueGuardSet);
150     }
151 }