blob: 4f131eff40e4d0b3370d1910f8e8b620b3d66630 [file] [log] [blame]
Jordan Halterman2bf177c2017-06-29 01:49:08 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2016-present Open Networking Foundation
Jordan Halterman2bf177c2017-06-29 01:49:08 -07003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.store.primitives.resources.impl;
17
Jordan Haltermandae11602018-07-03 00:00:47 -070018import java.util.Collection;
19import java.util.Iterator;
20import java.util.Map;
21
22import com.google.common.collect.Maps;
Jordan Halterman2bf177c2017-06-29 01:49:08 -070023import io.atomix.protocols.raft.operation.OperationId;
24import io.atomix.protocols.raft.operation.OperationType;
Jordan Halterman71635ae2017-07-28 10:35:43 -070025import io.atomix.utils.ArraySizeHashPrinter;
Jordan Halterman2bf177c2017-06-29 01:49:08 -070026import org.onlab.util.KryoNamespace;
27import org.onlab.util.Match;
28import org.onosproject.store.primitives.MapUpdate;
29import org.onosproject.store.primitives.TransactionId;
30import org.onosproject.store.serializers.KryoNamespaces;
31import org.onosproject.store.service.TransactionLog;
32import org.onosproject.store.service.Versioned;
33
Jordan Halterman71635ae2017-07-28 10:35:43 -070034import static com.google.common.base.MoreObjects.toStringHelper;
Jordan Halterman2bf177c2017-06-29 01:49:08 -070035import static com.google.common.base.Preconditions.checkNotNull;
36
37/**
38 * {@link AtomixConsistentMap} resource state machine operations.
39 */
40public enum AtomixConsistentMapOperations implements OperationId {
Jordan Halterman2b7501c2017-11-29 14:05:33 -080041 IS_EMPTY(OperationType.QUERY),
42 SIZE(OperationType.QUERY),
43 CONTAINS_KEY(OperationType.QUERY),
44 CONTAINS_VALUE(OperationType.QUERY),
45 GET(OperationType.QUERY),
46 GET_OR_DEFAULT(OperationType.QUERY),
47 KEY_SET(OperationType.QUERY),
48 VALUES(OperationType.QUERY),
49 ENTRY_SET(OperationType.QUERY),
50 PUT(OperationType.COMMAND),
51 PUT_IF_ABSENT(OperationType.COMMAND),
52 PUT_AND_GET(OperationType.COMMAND),
53 REMOVE(OperationType.COMMAND),
54 REMOVE_VALUE(OperationType.COMMAND),
55 REMOVE_VERSION(OperationType.COMMAND),
56 REPLACE(OperationType.COMMAND),
57 REPLACE_VALUE(OperationType.COMMAND),
58 REPLACE_VERSION(OperationType.COMMAND),
59 CLEAR(OperationType.COMMAND),
60 ADD_LISTENER(OperationType.COMMAND),
61 REMOVE_LISTENER(OperationType.COMMAND),
62 BEGIN(OperationType.COMMAND),
63 PREPARE(OperationType.COMMAND),
64 PREPARE_AND_COMMIT(OperationType.COMMAND),
65 COMMIT(OperationType.COMMAND),
Jordan Haltermandae11602018-07-03 00:00:47 -070066 ROLLBACK(OperationType.COMMAND),
67 OPEN_ITERATOR(OperationType.COMMAND),
68 NEXT(OperationType.QUERY),
69 CLOSE_ITERATOR(OperationType.COMMAND);
Jordan Halterman2bf177c2017-06-29 01:49:08 -070070
Jordan Halterman2bf177c2017-06-29 01:49:08 -070071 private final OperationType type;
72
Jordan Halterman2b7501c2017-11-29 14:05:33 -080073 AtomixConsistentMapOperations(OperationType type) {
Jordan Halterman2bf177c2017-06-29 01:49:08 -070074 this.type = type;
75 }
76
77 @Override
78 public String id() {
Jordan Halterman2b7501c2017-11-29 14:05:33 -080079 return name();
Jordan Halterman2bf177c2017-06-29 01:49:08 -070080 }
81
82 @Override
83 public OperationType type() {
84 return type;
85 }
86
87 public static final KryoNamespace NAMESPACE = KryoNamespace.newBuilder()
88 .register(KryoNamespaces.BASIC)
89 .nextId(KryoNamespaces.BEGIN_USER_CUSTOM_ID)
90 .register(ContainsKey.class)
91 .register(ContainsValue.class)
92 .register(Get.class)
93 .register(GetOrDefault.class)
Jordan Halterman71635ae2017-07-28 10:35:43 -070094 .register(Put.class)
95 .register(Remove.class)
96 .register(RemoveValue.class)
97 .register(RemoveVersion.class)
98 .register(Replace.class)
99 .register(ReplaceValue.class)
100 .register(ReplaceVersion.class)
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700101 .register(TransactionBegin.class)
102 .register(TransactionPrepare.class)
103 .register(TransactionPrepareAndCommit.class)
104 .register(TransactionCommit.class)
105 .register(TransactionRollback.class)
106 .register(TransactionId.class)
107 .register(TransactionLog.class)
108 .register(MapUpdate.class)
109 .register(MapUpdate.Type.class)
110 .register(PrepareResult.class)
111 .register(CommitResult.class)
112 .register(RollbackResult.class)
113 .register(Match.class)
114 .register(MapEntryUpdateResult.class)
115 .register(MapEntryUpdateResult.Status.class)
116 .register(Versioned.class)
117 .register(byte[].class)
Jordan Haltermandae11602018-07-03 00:00:47 -0700118 .register(Maps.immutableEntry("", "").getClass())
119 .register(IteratorBatch.class)
120 .register(IteratorPosition.class)
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700121 .build("AtomixConsistentMapOperations");
122
123 /**
124 * Abstract map command.
125 */
126 @SuppressWarnings("serial")
127 public abstract static class MapOperation {
128 @Override
129 public String toString() {
Jordan Halterman71635ae2017-07-28 10:35:43 -0700130 return toStringHelper(getClass())
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700131 .toString();
132 }
133 }
134
135 /**
136 * Abstract key-based query.
137 */
138 @SuppressWarnings("serial")
139 public abstract static class KeyOperation extends MapOperation {
140 protected String key;
141
142 public KeyOperation() {
143 }
144
145 public KeyOperation(String key) {
146 this.key = checkNotNull(key, "key cannot be null");
147 }
148
149 /**
150 * Returns the key.
151 * @return key
152 */
153 public String key() {
154 return key;
155 }
156
157 @Override
158 public String toString() {
Jordan Halterman71635ae2017-07-28 10:35:43 -0700159 return toStringHelper(getClass())
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700160 .add("key", key)
161 .toString();
162 }
163 }
164
165 /**
166 * Abstract value-based query.
167 */
168 @SuppressWarnings("serial")
169 public abstract static class ValueOperation extends MapOperation {
170 protected byte[] value;
171
172 public ValueOperation() {
173 }
174
175 public ValueOperation(byte[] value) {
Jordan Halterman4922a062017-07-31 15:55:36 -0700176 this.value = value;
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700177 }
178
179 /**
180 * Returns the value.
181 * @return value
182 */
183 public byte[] value() {
184 return value;
185 }
186
187 @Override
188 public String toString() {
Jordan Halterman71635ae2017-07-28 10:35:43 -0700189 return toStringHelper(getClass())
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700190 .add("value", value)
191 .toString();
192 }
193 }
194
195 /**
Jordan Halterman71635ae2017-07-28 10:35:43 -0700196 * Abstract key/value operation.
197 */
198 @SuppressWarnings("serial")
199 public abstract static class KeyValueOperation extends KeyOperation {
200 protected byte[] value;
201
202 public KeyValueOperation() {
203 }
204
205 public KeyValueOperation(String key, byte[] value) {
206 super(key);
207 this.value = value;
208 }
209
210 /**
211 * Returns the value.
212 * @return value
213 */
214 public byte[] value() {
215 return value;
216 }
217
218 @Override
219 public String toString() {
220 return toStringHelper(getClass())
221 .add("key", key)
222 .add("value", ArraySizeHashPrinter.of(value))
223 .toString();
224 }
225 }
226
227 /**
228 * Abstract key/version operation.
229 */
230 @SuppressWarnings("serial")
231 public abstract static class KeyVersionOperation extends KeyOperation {
232 protected long version;
233
234 public KeyVersionOperation() {
235 }
236
237 public KeyVersionOperation(String key, long version) {
238 super(key);
239 this.version = version;
240 }
241
242 /**
243 * Returns the version.
244 * @return version
245 */
246 public long version() {
247 return version;
248 }
249
250 @Override
251 public String toString() {
252 return toStringHelper(getClass())
253 .add("key", key)
254 .add("version", version)
255 .toString();
256 }
257 }
258
259 /**
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700260 * Contains key command.
261 */
262 @SuppressWarnings("serial")
263 public static class ContainsKey extends KeyOperation {
264 public ContainsKey() {
265 }
266
267 public ContainsKey(String key) {
268 super(key);
269 }
270 }
271
272 /**
273 * Contains value command.
274 */
275 @SuppressWarnings("serial")
276 public static class ContainsValue extends ValueOperation {
277 public ContainsValue() {
278 }
279
280 public ContainsValue(byte[] value) {
281 super(value);
282 }
283 }
284
285 /**
Jordan Halterman71635ae2017-07-28 10:35:43 -0700286 * Map put operation.
287 */
288 public static class Put extends KeyValueOperation {
289 public Put() {
290 }
291
292 public Put(String key, byte[] value) {
293 super(key, value);
294 }
295 }
296
297 /**
298 * Remove operation.
299 */
300 public static class Remove extends KeyOperation {
301 public Remove() {
302 }
303
304 public Remove(String key) {
305 super(key);
306 }
307 }
308
309 /**
310 * Remove if value match operation.
311 */
312 public static class RemoveValue extends KeyValueOperation {
313 public RemoveValue() {
314 }
315
316 public RemoveValue(String key, byte[] value) {
317 super(key, value);
318 }
319 }
320
321 /**
322 * Remove if version match operation.
323 */
324 public static class RemoveVersion extends KeyVersionOperation {
325 public RemoveVersion() {
326 }
327
328 public RemoveVersion(String key, long version) {
329 super(key, version);
330 }
331 }
332
333 /**
334 * Replace operation.
335 */
336 public static class Replace extends KeyValueOperation {
337 public Replace() {
338 }
339
340 public Replace(String key, byte[] value) {
341 super(key, value);
342 }
343 }
344
345 /**
346 * Replace by value operation.
347 */
348 public static class ReplaceValue extends KeyOperation {
349 private byte[] oldValue;
350 private byte[] newValue;
351
352 public ReplaceValue() {
353 }
354
355 public ReplaceValue(String key, byte[] oldValue, byte[] newValue) {
356 super(key);
357 this.oldValue = oldValue;
358 this.newValue = newValue;
359 }
360
361 public byte[] oldValue() {
362 return oldValue;
363 }
364
365 public byte[] newValue() {
366 return newValue;
367 }
368
369 @Override
370 public String toString() {
371 return toStringHelper(this)
372 .add("key", key)
373 .add("oldValue", ArraySizeHashPrinter.of(oldValue))
374 .add("newValue", ArraySizeHashPrinter.of(newValue))
375 .toString();
376 }
377 }
378
379 /**
380 * Replace by version operation.
381 */
382 public static class ReplaceVersion extends KeyOperation {
383 private long oldVersion;
384 private byte[] newValue;
385
386 public ReplaceVersion() {
387 }
388
389 public ReplaceVersion(String key, long oldVersion, byte[] newValue) {
390 super(key);
391 this.oldVersion = oldVersion;
392 this.newValue = newValue;
393 }
394
395 public long oldVersion() {
396 return oldVersion;
397 }
398
399 public byte[] newValue() {
400 return newValue;
401 }
402
403 @Override
404 public String toString() {
405 return toStringHelper(this)
406 .add("key", key)
407 .add("oldVersion", oldVersion)
408 .add("newValue", ArraySizeHashPrinter.of(newValue))
409 .toString();
410 }
411 }
412
413 /**
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700414 * Transaction begin command.
415 */
416 public static class TransactionBegin extends MapOperation {
417 private TransactionId transactionId;
418
419 public TransactionBegin() {
420 }
421
422 public TransactionBegin(TransactionId transactionId) {
423 this.transactionId = transactionId;
424 }
425
426 public TransactionId transactionId() {
427 return transactionId;
428 }
429 }
430
431 /**
432 * Map prepare command.
433 */
434 @SuppressWarnings("serial")
435 public static class TransactionPrepare extends MapOperation {
436 private TransactionLog<MapUpdate<String, byte[]>> transactionLog;
437
438 public TransactionPrepare() {
439 }
440
441 public TransactionPrepare(TransactionLog<MapUpdate<String, byte[]>> transactionLog) {
442 this.transactionLog = transactionLog;
443 }
444
445 public TransactionLog<MapUpdate<String, byte[]>> transactionLog() {
446 return transactionLog;
447 }
448
449 @Override
450 public String toString() {
Jordan Halterman71635ae2017-07-28 10:35:43 -0700451 return toStringHelper(getClass())
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700452 .add("transactionLog", transactionLog)
453 .toString();
454 }
455 }
456
457 /**
458 * Map prepareAndCommit command.
459 */
460 @SuppressWarnings("serial")
461 public static class TransactionPrepareAndCommit extends TransactionPrepare {
462 public TransactionPrepareAndCommit() {
463 }
464
465 public TransactionPrepareAndCommit(TransactionLog<MapUpdate<String, byte[]>> transactionLog) {
466 super(transactionLog);
467 }
468 }
469
470 /**
471 * Map transaction commit command.
472 */
473 @SuppressWarnings("serial")
474 public static class TransactionCommit extends MapOperation {
475 private TransactionId transactionId;
476
477 public TransactionCommit() {
478 }
479
480 public TransactionCommit(TransactionId transactionId) {
481 this.transactionId = transactionId;
482 }
483
484 /**
485 * Returns the transaction identifier.
486 * @return transaction id
487 */
488 public TransactionId transactionId() {
489 return transactionId;
490 }
491
492 @Override
493 public String toString() {
Jordan Halterman71635ae2017-07-28 10:35:43 -0700494 return toStringHelper(getClass())
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700495 .add("transactionId", transactionId)
496 .toString();
497 }
498 }
499
500 /**
501 * Map transaction rollback command.
502 */
503 @SuppressWarnings("serial")
504 public static class TransactionRollback extends MapOperation {
505 private TransactionId transactionId;
506
507 public TransactionRollback() {
508 }
509
510 public TransactionRollback(TransactionId transactionId) {
511 this.transactionId = transactionId;
512 }
513
514 /**
515 * Returns the transaction identifier.
516 * @return transaction id
517 */
518 public TransactionId transactionId() {
519 return transactionId;
520 }
521
522 @Override
523 public String toString() {
Jordan Halterman71635ae2017-07-28 10:35:43 -0700524 return toStringHelper(getClass())
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700525 .add("transactionId", transactionId)
526 .toString();
527 }
528 }
529
530 /**
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700531 * Get query.
532 */
533 @SuppressWarnings("serial")
534 public static class Get extends KeyOperation {
535 public Get() {
536 }
537
538 public Get(String key) {
539 super(key);
540 }
541 }
542
543 /**
544 * Get or default query.
545 */
546 @SuppressWarnings("serial")
547 public static class GetOrDefault extends KeyOperation {
548 private byte[] defaultValue;
549
550 public GetOrDefault() {
551 }
552
553 public GetOrDefault(String key, byte[] defaultValue) {
554 super(key);
555 this.defaultValue = defaultValue;
556 }
557
558 /**
559 * Returns the default value.
560 *
561 * @return the default value
562 */
563 public byte[] defaultValue() {
564 return defaultValue;
565 }
Jordan Halterman71635ae2017-07-28 10:35:43 -0700566
567 @Override
568 public String toString() {
569 return toStringHelper(this)
570 .add("key", key)
571 .add("defaultValue", ArraySizeHashPrinter.of(defaultValue))
572 .toString();
573 }
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700574 }
Jordan Haltermandae11602018-07-03 00:00:47 -0700575
576 /**
577 * Iterator position.
578 */
579 public static class IteratorPosition {
580 private long iteratorId;
581 private int position;
582
583 private IteratorPosition() {
584 }
585
586 public IteratorPosition(long iteratorId, int position) {
587 this.iteratorId = iteratorId;
588 this.position = position;
589 }
590
591 public long iteratorId() {
592 return iteratorId;
593 }
594
595 public int position() {
596 return position;
597 }
598 }
599
600 /**
601 * Iterator batch.
602 */
603 public static class IteratorBatch implements Iterator<Map.Entry<String, Versioned<byte[]>>> {
604 private int position;
605 private Collection<Map.Entry<String, Versioned<byte[]>>> entries;
606 private transient volatile Iterator<Map.Entry<String, Versioned<byte[]>>> iterator;
607
608 private IteratorBatch() {
609 }
610
611 public IteratorBatch(int position, Collection<Map.Entry<String, Versioned<byte[]>>> entries) {
612 this.position = position;
613 this.entries = entries;
614 }
615
616 public int position() {
617 return position;
618 }
619
620 public Collection<Map.Entry<String, Versioned<byte[]>>> entries() {
621 return entries;
622 }
623
624 private Iterator<Map.Entry<String, Versioned<byte[]>>> iterator() {
625 Iterator<Map.Entry<String, Versioned<byte[]>>> iterator = this.iterator;
626 if (iterator == null) {
627 synchronized (entries) {
628 iterator = this.iterator;
629 if (iterator == null) {
630 iterator = entries.iterator();
631 this.iterator = iterator;
632 }
633 }
634 }
635 return iterator;
636 }
637
638 @Override
639 public boolean hasNext() {
640 return iterator().hasNext();
641 }
642
643 @Override
644 public Map.Entry<String, Versioned<byte[]>> next() {
645 return iterator().next();
646 }
647 }
Jordan Halterman2bf177c2017-06-29 01:49:08 -0700648}