5 class PendingTransaction {
7 Set<KeyValue> keyValueUpdateSet = NULL;
8 Set<KeyValue> keyValueGuardSet = NULL;
9 int64_t arbitrator = -1;
10 int64_t clientLocalSequenceNumber = -1;
11 int64_t machineId = -1;
13 int currentDataSize = 0;
15 PendingTransaction(int64_t _machineId) {
16 machineId = _machineId;
17 keyValueUpdateSet = new HashSet<KeyValue>();
18 keyValueGuardSet = new HashSet<KeyValue>();
22 * Add a new key value to the updates
25 void addKV(KeyValue newKV) {
29 // Make sure there are no duplicates
30 for (KeyValue kv : keyValueUpdateSet) {
31 if (kv.getKey().equals(newKV.getKey())) {
33 // Remove key if we are adding a newer version of the same key
39 // Remove key if we are adding a newer version of the same key
41 keyValueUpdateSet.remove(rmKV);
42 currentDataSize -= rmKV.getSize();
45 // Add the key to the hash set
46 keyValueUpdateSet.add(newKV);
47 currentDataSize += newKV.getSize();
51 * Add a new key value to the guard set
54 void addKVGuard(KeyValue newKV) {
55 // Add the key to the hash set
56 keyValueGuardSet.add(newKV);
57 currentDataSize += newKV.getSize();
61 * Checks if the arbitrator is the same
63 bool checkArbitrator(int64_t arb) {
64 if (arbitrator == -1) {
69 return arb == arbitrator;
73 * Get the transaction arbitrator
75 int64_t getArbitrator() {
80 * Get the key value update set
82 Set<KeyValue> getKVUpdates() {
83 return keyValueUpdateSet;
87 * Get the key value update set
89 Set<KeyValue> getKVGuard() {
90 return keyValueGuardSet;
93 void setClientLocalSequenceNumber(int64_t _clientLocalSequenceNumber) {
94 clientLocalSequenceNumber = _clientLocalSequenceNumber;
97 int64_t getClientLocalSequenceNumber() {
98 return clientLocalSequenceNumber;
101 int64_t getMachineId() {
105 bool evaluateGuard(Map<IoTString, KeyValue> keyValTableCommitted, Map<IoTString, KeyValue> keyValTableSpeculative, Map<IoTString, KeyValue> keyValTablePendingTransSpeculative) {
106 for (KeyValue kvGuard : keyValueGuardSet) {
108 // First check if the key is in the speculative table, this is the value of the latest assumption
109 KeyValue kv = keyValTablePendingTransSpeculative.get(kvGuard.getKey());
113 // if it is not in the pending trans table then check the speculative table and use that
114 // value as our latest assumption
115 kv = keyValTableSpeculative.get(kvGuard.getKey());
120 // if it is not in the speculative table then check the committed table and use that
121 // value as our latest assumption
122 kv = keyValTableCommitted.get(kvGuard.getKey());
125 if (kvGuard.getValue() != NULL) {
126 if ((kv == NULL) || (!kvGuard.getValue().equals(kv.getValue()))) {
138 Transaction createTransaction() {
140 Transaction newTransaction = new Transaction();
141 int transactionPartCount = 0;
143 // Convert all the data into a char array so we can start partitioning
144 char[] charData = convertDataToBytes();
146 int currentPosition = 0;
147 int remaining = charData.length;
149 while (remaining > 0) {
151 Boolean isLastPart = false;
152 // determine how much to copy
153 int copySize = TransactionPart.MAX_NON_HEADER_SIZE;
154 if (remaining <= TransactionPart.MAX_NON_HEADER_SIZE) {
155 copySize = remaining;
156 isLastPart = true; // last bit of data so last part
159 // Copy to a smaller version
160 char[] partData = new char[copySize];
161 System.arraycopy(charData, currentPosition, partData, 0, copySize);
163 TransactionPart part = new TransactionPart(NULL, machineId, arbitrator, clientLocalSequenceNumber, transactionPartCount, partData, isLastPart);
164 newTransaction.addPartEncode(part);
166 // Update position, count and remaining
167 currentPosition += copySize;
168 transactionPartCount++;
169 remaining -= copySize;
172 // Add the Guard Conditions
173 for (KeyValue kv : keyValueGuardSet) {
174 newTransaction.addGuardKV(kv);
178 for (KeyValue kv : keyValueUpdateSet) {
179 newTransaction.addUpdateKV(kv);
182 return newTransaction;
185 char[] convertDataToBytes() {
187 // Calculate the size of the data
188 int sizeOfData = 2 * sizeof(int32_t); // Number of Update KV's and Guard KV's
189 sizeOfData += currentDataSize;
191 // Data handlers and storage
192 char[] dataArray = new char[sizeOfData];
193 ByteBuffer bbEncode = ByteBuffer.wrap(dataArray);
195 // Encode the size of the updates and guard sets
196 bbEncode.putInt(keyValueGuardSet.size());
197 bbEncode.putInt(keyValueUpdateSet.size());
199 // Encode all the guard conditions
200 for (KeyValue kv : keyValueGuardSet) {
204 // Encode all the updates
205 for (KeyValue kv : keyValueUpdateSet) {
209 return bbEncode.array();