Offline support added
[iotcloud.git] / version2 / src / java / iotcloud / PendingTransaction.java
1 package iotcloud;
2
3 import java.util.Set;
4 import java.util.Map;
5 import java.util.HashSet;
6
7 import javax.script.ScriptException;
8 import java.lang.NullPointerException;
9
10
11 class PendingTransaction {
12
13     private Set<KeyValue> keyValueUpdateSet = null;
14     private Set<KeyValue> keyValueGuardSet = null;
15     private long arbitrator = -1;
16
17     public PendingTransaction() {
18         keyValueUpdateSet = new HashSet<KeyValue>();
19         keyValueGuardSet = new HashSet<KeyValue>();
20     }
21
22     /**
23      * Add a new key value to the updates
24      *
25      */
26     public void addKV(KeyValue newKV) {
27
28         KeyValue rmKV = null;
29
30         // Make sure there are no duplicates
31         for (KeyValue kv : keyValueUpdateSet) {
32             if (kv.getKey().equals(newKV.getKey())) {
33
34                 // Remove key if we are adding a newer version of the same key
35                 rmKV = kv;
36                 break;
37             }
38         }
39
40         // Remove key if we are adding a newer version of the same key
41         if (rmKV != null) {
42             keyValueUpdateSet.remove(rmKV);
43         }
44
45         // Add the key to the hash set
46         keyValueUpdateSet.add(newKV);
47     }
48
49
50     /**
51      * Add a new key value to the guard set
52      *
53      */
54     public void addKVGuard(KeyValue newKV) {
55         // Add the key to the hash set
56         keyValueGuardSet.add(newKV);
57     }
58
59     /**
60      * Checks if the arbitrator is the same
61      *
62      */
63     public boolean checkArbitrator(long arb) {
64         if (arbitrator == -1) {
65             arbitrator = arb;
66             return true;
67         }
68
69         return arb == arbitrator;
70     }
71
72     /**
73      * Get the transaction arbitrator
74      *
75      */
76     public long getArbitrator() {
77         return arbitrator;
78     }
79
80     /**
81      * Get the key value update set
82      *
83      */
84     public Set<KeyValue> getKVUpdates() {
85         return keyValueUpdateSet;
86     }
87
88
89     /**
90        * Get the key value update set
91        *
92        */
93     public Set<KeyValue> getKVGuard() {
94         return keyValueGuardSet;
95     }
96
97     public boolean evaluateGuard(Map<IoTString, KeyValue> keyValTableCommitted, Map<IoTString, KeyValue> keyValTableSpeculative, Map<IoTString, KeyValue> keyValTablePendingTransSpeculative) {
98         for (KeyValue kvGuard : keyValueGuardSet) {
99
100             // First check if the key is in the speculative table, this is the value of the latest assumption
101             KeyValue kv = keyValTablePendingTransSpeculative.get(kvGuard.getKey());
102
103
104             if (kv == null) {
105                 // if it is not in the pending trans table then check the speculative table and use that
106                 // value as our latest assumption
107                 kv = keyValTableSpeculative.get(kvGuard.getKey());
108             }
109
110
111             if (kv == null) {
112                 // if it is not in the speculative table then check the committed table and use that
113                 // value as our latest assumption
114                 kv = keyValTableCommitted.get(kvGuard.getKey());
115             }
116
117             if (kvGuard.getValue() != null) {
118                 if ((kv == null) || (!kvGuard.getValue().equals(kv.getValue()))) {
119                     return false;
120                 }
121             } else {
122                 if (kv != null) {
123                     return false;
124                 }
125             }
126         }
127         return true;
128     }
129 }