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() {
51 public Set<KeyValue> getkeyValueUpdateSet() {
52 return keyValueUpdateSet;
55 public Set<KeyValue> getkeyValueGuardSet() {
56 return keyValueGuardSet;
59 public boolean evaluateGuard(Map<IoTString, KeyValue> keyValTableCommitted, Map<IoTString, KeyValue> keyValTableSpeculative) {
60 for (KeyValue kvGuard : keyValueGuardSet) {
62 // First check if the key is in the speculative table, this is the value of the latest assumption
65 // If we have a speculation table then use it first
66 if (keyValTableSpeculative != null) {
67 kv = keyValTableSpeculative.get(kvGuard.getKey());
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());
77 if (kvGuard.getValue() != null) {
78 if ((kv == null) || (!kvGuard.getValue().equals(kv.getValue()))) {
90 public byte getType() {
91 return Entry.TypeTransaction;
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
100 for (KeyValue kv : keyValueUpdateSet) {
101 size += kv.getSize();
104 // Size of each Guard KV
105 for (KeyValue kv : keyValueGuardSet) {
106 size += kv.getSize();
112 public void encode(ByteBuffer bb) {
113 bb.put(Entry.TypeTransaction);
115 bb.putLong(machineid);
116 bb.putLong(arbitrator);
118 bb.putInt(keyValueUpdateSet.size());
119 for (KeyValue kv : keyValueUpdateSet) {
123 bb.putInt(keyValueGuardSet.size());
124 for (KeyValue kv : keyValueGuardSet) {
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();
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);
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);
148 return new Transaction(slot, seqnum, machineid, arbitrator, kvSetUpdates, kvSetGuards);
151 public Entry getCopy(Slot s) {
152 return new Transaction(s, seqnum, machineid, arbitrator, keyValueUpdateSet, keyValueGuardSet);