API Changes
[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
51     public Set<KeyValue> getkeyValueUpdateSet() {
52         return keyValueUpdateSet;
53     }
54
55     public Set<KeyValue> getkeyValueGuardSet() {
56         return keyValueGuardSet;
57     }
58
59     public boolean evaluateGuard(Map<IoTString, KeyValue> keyValTableCommitted, Map<IoTString, KeyValue> keyValTableSpeculative) {
60         for (KeyValue kvGuard : keyValueGuardSet) {
61
62             // First check if the key is in the speculative table, this is the value of the latest assumption
63             KeyValue kv = null;
64
65             // If we have a speculation table then use it first
66             if (keyValTableSpeculative != null) {
67                 kv = keyValTableSpeculative.get(kvGuard.getKey());
68             }
69
70             if (kv == null) {
71
72                 // if it is not in the speculative table then check the committed table and use that
73                 // value as our latest assumption
74                 kv = keyValTableCommitted.get(kvGuard.getKey());
75             }
76
77             if (kvGuard.getValue() != null) {
78                 if ((kv == null) || (!kvGuard.getValue().equals(kv.getValue()))) {
79                     return false;
80                 }
81             } else {
82                 if (kv != null) {
83                     return false;
84                 }
85             }
86         }
87         return true;
88     }
89
90     public byte getType() {
91         return Entry.TypeTransaction;
92     }
93
94     public int getSize() {
95         int size = 3 * Long.BYTES + Byte.BYTES; // seq, machine id, entry type
96         size += Integer.BYTES; // number of KV's
97         size += Integer.BYTES; // number of Guard KV's
98
99         // Size of each KV
100         for (KeyValue kv : keyValueUpdateSet) {
101             size += kv.getSize();
102         }
103
104         // Size of each Guard KV
105         for (KeyValue kv : keyValueGuardSet) {
106             size += kv.getSize();
107         }
108
109         return size;
110     }
111
112     public void encode(ByteBuffer bb) {
113         bb.put(Entry.TypeTransaction);
114         bb.putLong(seqnum);
115         bb.putLong(machineid);
116         bb.putLong(arbitrator);
117
118         bb.putInt(keyValueUpdateSet.size());
119         for (KeyValue kv : keyValueUpdateSet) {
120             kv.encode(bb);
121         }
122
123         bb.putInt(keyValueGuardSet.size());
124         for (KeyValue kv : keyValueGuardSet) {
125             kv.encode(bb);
126         }
127     }
128
129     static Entry decode(Slot slot, ByteBuffer bb) {
130         long seqnum = bb.getLong();
131         long machineid = bb.getLong();
132         long arbitrator = bb.getLong();
133         int numberOfKeys = bb.getInt();
134
135         Set<KeyValue> kvSetUpdates = new HashSet<KeyValue>();
136         for (int i = 0; i < numberOfKeys; i++) {
137             KeyValue kv = KeyValue.decode(bb);
138             kvSetUpdates.add(kv);
139         }
140
141         int numberOfGuards = bb.getInt();
142         Set<KeyValue> kvSetGuards = new HashSet<KeyValue>();
143         for (int i = 0; i < numberOfGuards; i++) {
144             KeyValue kv = KeyValue.decode(bb);
145             kvSetGuards.add(kv);
146         }
147
148         return new Transaction(slot, seqnum, machineid, arbitrator, kvSetUpdates, kvSetGuards);
149     }
150
151     public Entry getCopy(Slot s) {
152         return new Transaction(s, seqnum, machineid, arbitrator, keyValueUpdateSet, keyValueGuardSet);
153     }
154 }