Madan Jampani
Committed by Gerrit Code Review

Support for building a immutable ConsistentMap and DistributedSet

Change-Id: Ic34684551f5c7d1f4fdc4cd3fc1a7bfabc5681f5
...@@ -56,6 +56,15 @@ public interface ConsistentMapBuilder<K, V> { ...@@ -56,6 +56,15 @@ public interface ConsistentMapBuilder<K, V> {
56 public ConsistentMapBuilder<K, V> withPartitionsDisabled(); 56 public ConsistentMapBuilder<K, V> withPartitionsDisabled();
57 57
58 /** 58 /**
59 + * Disables map updates.
60 + * <p>
61 + * Attempt to update the built map will throw {@code UnsupportedOperationException}.
62 + *
63 + * @return this ConsistentMapBuilder
64 + */
65 + public ConsistentMapBuilder<K, V> withUpdatesDisabled();
66 +
67 + /**
59 * Builds an consistent map based on the configuration options 68 * Builds an consistent map based on the configuration options
60 * supplied to this builder. 69 * supplied to this builder.
61 * 70 *
......
...@@ -53,6 +53,15 @@ public interface SetBuilder<E> { ...@@ -53,6 +53,15 @@ public interface SetBuilder<E> {
53 public SetBuilder<E> withSerializer(Serializer serializer); 53 public SetBuilder<E> withSerializer(Serializer serializer);
54 54
55 /** 55 /**
56 + * Disables set updates.
57 + * <p>
58 + * Attempt to update the built set will throw {@code UnsupportedOperationException}.
59 + *
60 + * @return this SetBuilder
61 + */
62 + SetBuilder<E> withUpdatesDisabled();
63 +
64 + /**
56 * Builds an set based on the configuration options 65 * Builds an set based on the configuration options
57 * supplied to this builder. 66 * supplied to this builder.
58 * 67 *
......
...@@ -48,6 +48,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V> ...@@ -48,6 +48,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V>
48 private final String name; 48 private final String name;
49 private final Database database; 49 private final Database database;
50 private final Serializer serializer; 50 private final Serializer serializer;
51 + private final boolean readOnly;
51 52
52 private static final String ERROR_NULL_KEY = "Key cannot be null"; 53 private static final String ERROR_NULL_KEY = "Key cannot be null";
53 private static final String ERROR_NULL_VALUE = "Null values are not allowed"; 54 private static final String ERROR_NULL_VALUE = "Null values are not allowed";
...@@ -68,10 +69,12 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V> ...@@ -68,10 +69,12 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V>
68 69
69 public DefaultAsyncConsistentMap(String name, 70 public DefaultAsyncConsistentMap(String name,
70 Database database, 71 Database database,
71 - Serializer serializer) { 72 + Serializer serializer,
73 + boolean readOnly) {
72 this.name = checkNotNull(name, "map name cannot be null"); 74 this.name = checkNotNull(name, "map name cannot be null");
73 this.database = checkNotNull(database, "database cannot be null"); 75 this.database = checkNotNull(database, "database cannot be null");
74 this.serializer = checkNotNull(serializer, "serializer cannot be null"); 76 this.serializer = checkNotNull(serializer, "serializer cannot be null");
77 + this.readOnly = readOnly;
75 } 78 }
76 79
77 @Override 80 @Override
...@@ -108,6 +111,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V> ...@@ -108,6 +111,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V>
108 public CompletableFuture<Versioned<V>> put(K key, V value) { 111 public CompletableFuture<Versioned<V>> put(K key, V value) {
109 checkNotNull(key, ERROR_NULL_KEY); 112 checkNotNull(key, ERROR_NULL_KEY);
110 checkNotNull(value, ERROR_NULL_VALUE); 113 checkNotNull(value, ERROR_NULL_VALUE);
114 + checkIfUnmodifiable();
111 return database.put(name, keyCache.getUnchecked(key), serializer.encode(value)) 115 return database.put(name, keyCache.getUnchecked(key), serializer.encode(value))
112 .thenApply(this::unwrapResult) 116 .thenApply(this::unwrapResult)
113 .thenApply(v -> v != null 117 .thenApply(v -> v != null
...@@ -117,6 +121,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V> ...@@ -117,6 +121,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V>
117 @Override 121 @Override
118 public CompletableFuture<Versioned<V>> remove(K key) { 122 public CompletableFuture<Versioned<V>> remove(K key) {
119 checkNotNull(key, ERROR_NULL_KEY); 123 checkNotNull(key, ERROR_NULL_KEY);
124 + checkIfUnmodifiable();
120 return database.remove(name, keyCache.getUnchecked(key)) 125 return database.remove(name, keyCache.getUnchecked(key))
121 .thenApply(this::unwrapResult) 126 .thenApply(this::unwrapResult)
122 .thenApply(v -> v != null 127 .thenApply(v -> v != null
...@@ -125,6 +130,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V> ...@@ -125,6 +130,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V>
125 130
126 @Override 131 @Override
127 public CompletableFuture<Void> clear() { 132 public CompletableFuture<Void> clear() {
133 + checkIfUnmodifiable();
128 return database.clear(name).thenApply(this::unwrapResult); 134 return database.clear(name).thenApply(this::unwrapResult);
129 } 135 }
130 136
...@@ -157,6 +163,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V> ...@@ -157,6 +163,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V>
157 public CompletableFuture<Versioned<V>> putIfAbsent(K key, V value) { 163 public CompletableFuture<Versioned<V>> putIfAbsent(K key, V value) {
158 checkNotNull(key, ERROR_NULL_KEY); 164 checkNotNull(key, ERROR_NULL_KEY);
159 checkNotNull(value, ERROR_NULL_VALUE); 165 checkNotNull(value, ERROR_NULL_VALUE);
166 + checkIfUnmodifiable();
160 return database.putIfAbsent(name, 167 return database.putIfAbsent(name,
161 keyCache.getUnchecked(key), 168 keyCache.getUnchecked(key),
162 serializer.encode(value)) 169 serializer.encode(value))
...@@ -169,6 +176,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V> ...@@ -169,6 +176,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V>
169 public CompletableFuture<Boolean> remove(K key, V value) { 176 public CompletableFuture<Boolean> remove(K key, V value) {
170 checkNotNull(key, ERROR_NULL_KEY); 177 checkNotNull(key, ERROR_NULL_KEY);
171 checkNotNull(value, ERROR_NULL_VALUE); 178 checkNotNull(value, ERROR_NULL_VALUE);
179 + checkIfUnmodifiable();
172 return database.remove(name, keyCache.getUnchecked(key), serializer.encode(value)) 180 return database.remove(name, keyCache.getUnchecked(key), serializer.encode(value))
173 .thenApply(this::unwrapResult); 181 .thenApply(this::unwrapResult);
174 } 182 }
...@@ -176,6 +184,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V> ...@@ -176,6 +184,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V>
176 @Override 184 @Override
177 public CompletableFuture<Boolean> remove(K key, long version) { 185 public CompletableFuture<Boolean> remove(K key, long version) {
178 checkNotNull(key, ERROR_NULL_KEY); 186 checkNotNull(key, ERROR_NULL_KEY);
187 + checkIfUnmodifiable();
179 return database.remove(name, keyCache.getUnchecked(key), version) 188 return database.remove(name, keyCache.getUnchecked(key), version)
180 .thenApply(this::unwrapResult); 189 .thenApply(this::unwrapResult);
181 190
...@@ -185,6 +194,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V> ...@@ -185,6 +194,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V>
185 public CompletableFuture<Boolean> replace(K key, V oldValue, V newValue) { 194 public CompletableFuture<Boolean> replace(K key, V oldValue, V newValue) {
186 checkNotNull(key, ERROR_NULL_KEY); 195 checkNotNull(key, ERROR_NULL_KEY);
187 checkNotNull(newValue, ERROR_NULL_VALUE); 196 checkNotNull(newValue, ERROR_NULL_VALUE);
197 + checkIfUnmodifiable();
188 byte[] existing = oldValue != null ? serializer.encode(oldValue) : null; 198 byte[] existing = oldValue != null ? serializer.encode(oldValue) : null;
189 return database.replace(name, keyCache.getUnchecked(key), existing, serializer.encode(newValue)) 199 return database.replace(name, keyCache.getUnchecked(key), existing, serializer.encode(newValue))
190 .thenApply(this::unwrapResult); 200 .thenApply(this::unwrapResult);
...@@ -194,6 +204,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V> ...@@ -194,6 +204,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V>
194 public CompletableFuture<Boolean> replace(K key, long oldVersion, V newValue) { 204 public CompletableFuture<Boolean> replace(K key, long oldVersion, V newValue) {
195 checkNotNull(key, ERROR_NULL_KEY); 205 checkNotNull(key, ERROR_NULL_KEY);
196 checkNotNull(newValue, ERROR_NULL_VALUE); 206 checkNotNull(newValue, ERROR_NULL_VALUE);
207 + checkIfUnmodifiable();
197 return database.replace(name, keyCache.getUnchecked(key), oldVersion, serializer.encode(newValue)) 208 return database.replace(name, keyCache.getUnchecked(key), oldVersion, serializer.encode(newValue))
198 .thenApply(this::unwrapResult); 209 .thenApply(this::unwrapResult);
199 } 210 }
...@@ -216,4 +227,10 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V> ...@@ -216,4 +227,10 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V>
216 throw new IllegalStateException("Must not be here"); 227 throw new IllegalStateException("Must not be here");
217 } 228 }
218 } 229 }
230 +
231 + private void checkIfUnmodifiable() {
232 + if (readOnly) {
233 + throw new UnsupportedOperationException();
234 + }
235 + }
219 } 236 }
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -45,8 +45,9 @@ public class DefaultConsistentMap<K, V> implements ConsistentMap<K, V> { ...@@ -45,8 +45,9 @@ public class DefaultConsistentMap<K, V> implements ConsistentMap<K, V> {
45 45
46 public DefaultConsistentMap(String name, 46 public DefaultConsistentMap(String name,
47 Database database, 47 Database database,
48 - Serializer serializer) { 48 + Serializer serializer,
49 - asyncMap = new DefaultAsyncConsistentMap<>(name, database, serializer); 49 + boolean readOnly) {
50 + asyncMap = new DefaultAsyncConsistentMap<>(name, database, serializer, readOnly);
50 } 51 }
51 52
52 @Override 53 @Override
......
...@@ -19,6 +19,7 @@ public class DefaultConsistentMapBuilder<K, V> implements ConsistentMapBuilder<K ...@@ -19,6 +19,7 @@ public class DefaultConsistentMapBuilder<K, V> implements ConsistentMapBuilder<K
19 private Serializer serializer; 19 private Serializer serializer;
20 private String name; 20 private String name;
21 private boolean partitionsEnabled = true; 21 private boolean partitionsEnabled = true;
22 + private boolean readOnly = false;
22 private final Database partitionedDatabase; 23 private final Database partitionedDatabase;
23 private final Database inMemoryDatabase; 24 private final Database inMemoryDatabase;
24 25
...@@ -47,6 +48,12 @@ public class DefaultConsistentMapBuilder<K, V> implements ConsistentMapBuilder<K ...@@ -47,6 +48,12 @@ public class DefaultConsistentMapBuilder<K, V> implements ConsistentMapBuilder<K
47 return this; 48 return this;
48 } 49 }
49 50
51 + @Override
52 + public ConsistentMapBuilder<K, V> withUpdatesDisabled() {
53 + readOnly = true;
54 + return this;
55 + }
56 +
50 private boolean validInputs() { 57 private boolean validInputs() {
51 return name != null && serializer != null; 58 return name != null && serializer != null;
52 } 59 }
...@@ -57,7 +64,8 @@ public class DefaultConsistentMapBuilder<K, V> implements ConsistentMapBuilder<K ...@@ -57,7 +64,8 @@ public class DefaultConsistentMapBuilder<K, V> implements ConsistentMapBuilder<K
57 return new DefaultConsistentMap<>( 64 return new DefaultConsistentMap<>(
58 name, 65 name,
59 partitionsEnabled ? partitionedDatabase : inMemoryDatabase, 66 partitionsEnabled ? partitionedDatabase : inMemoryDatabase,
60 - serializer); 67 + serializer,
68 + readOnly);
61 } 69 }
62 70
63 @Override 71 @Override
...@@ -66,6 +74,7 @@ public class DefaultConsistentMapBuilder<K, V> implements ConsistentMapBuilder<K ...@@ -66,6 +74,7 @@ public class DefaultConsistentMapBuilder<K, V> implements ConsistentMapBuilder<K
66 return new DefaultAsyncConsistentMap<>( 74 return new DefaultAsyncConsistentMap<>(
67 name, 75 name,
68 partitionsEnabled ? partitionedDatabase : inMemoryDatabase, 76 partitionsEnabled ? partitionedDatabase : inMemoryDatabase,
69 - serializer); 77 + serializer,
78 + readOnly);
70 } 79 }
71 } 80 }
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -33,8 +33,8 @@ public class DefaultDistributedSet<E> implements Set<E> { ...@@ -33,8 +33,8 @@ public class DefaultDistributedSet<E> implements Set<E> {
33 33
34 private final ConsistentMap<E, Boolean> backingMap; 34 private final ConsistentMap<E, Boolean> backingMap;
35 35
36 - public DefaultDistributedSet(String name, Database database, Serializer serializer) { 36 + public DefaultDistributedSet(String name, Database database, Serializer serializer, boolean readOnly) {
37 - backingMap = new DefaultConsistentMap<>(name, database, serializer); 37 + backingMap = new DefaultConsistentMap<>(name, database, serializer, readOnly);
38 } 38 }
39 39
40 @Override 40 @Override
......
...@@ -34,6 +34,7 @@ public class DefaultSetBuilder<E> implements SetBuilder<E> { ...@@ -34,6 +34,7 @@ public class DefaultSetBuilder<E> implements SetBuilder<E> {
34 private Serializer serializer; 34 private Serializer serializer;
35 private String name; 35 private String name;
36 private final Database database; 36 private final Database database;
37 + private boolean readOnly;
37 38
38 public DefaultSetBuilder(Database database) { 39 public DefaultSetBuilder(Database database) {
39 this.database = checkNotNull(database); 40 this.database = checkNotNull(database);
...@@ -53,6 +54,12 @@ public class DefaultSetBuilder<E> implements SetBuilder<E> { ...@@ -53,6 +54,12 @@ public class DefaultSetBuilder<E> implements SetBuilder<E> {
53 return this; 54 return this;
54 } 55 }
55 56
57 + @Override
58 + public SetBuilder<E> withUpdatesDisabled() {
59 + readOnly = true;
60 + return this;
61 + }
62 +
56 private boolean validInputs() { 63 private boolean validInputs() {
57 return name != null && serializer != null; 64 return name != null && serializer != null;
58 } 65 }
...@@ -60,6 +67,6 @@ public class DefaultSetBuilder<E> implements SetBuilder<E> { ...@@ -60,6 +67,6 @@ public class DefaultSetBuilder<E> implements SetBuilder<E> {
60 @Override 67 @Override
61 public Set<E> build() { 68 public Set<E> build() {
62 checkState(validInputs()); 69 checkState(validInputs());
63 - return new DefaultDistributedSet<>(name, database, serializer); 70 + return new DefaultDistributedSet<>(name, database, serializer, readOnly);
64 } 71 }
65 } 72 }
......
...@@ -72,7 +72,7 @@ public class DefaultTransactionContext implements TransactionContext { ...@@ -72,7 +72,7 @@ public class DefaultTransactionContext implements TransactionContext {
72 checkNotNull(serializer); 72 checkNotNull(serializer);
73 return txMaps.computeIfAbsent(mapName, name -> new DefaultTransactionalMap<>( 73 return txMaps.computeIfAbsent(mapName, name -> new DefaultTransactionalMap<>(
74 name, 74 name,
75 - new DefaultConsistentMap<>(name, database, serializer), 75 + new DefaultConsistentMap<>(name, database, serializer, false),
76 this, 76 this,
77 serializer)); 77 serializer));
78 } 78 }
...@@ -99,4 +99,4 @@ public class DefaultTransactionContext implements TransactionContext { ...@@ -99,4 +99,4 @@ public class DefaultTransactionContext implements TransactionContext {
99 checkState(isOpen, TX_NOT_OPEN_ERROR); 99 checkState(isOpen, TX_NOT_OPEN_ERROR);
100 txMaps.values().forEach(m -> m.rollback()); 100 txMaps.values().forEach(m -> m.rollback());
101 } 101 }
102 -}
...\ No newline at end of file ...\ No newline at end of file
102 +}
......
...@@ -60,7 +60,7 @@ public class TransactionManager { ...@@ -60,7 +60,7 @@ public class TransactionManager {
60 */ 60 */
61 public TransactionManager(Database database) { 61 public TransactionManager(Database database) {
62 this.database = checkNotNull(database, "database cannot be null"); 62 this.database = checkNotNull(database, "database cannot be null");
63 - this.transactions = new DefaultAsyncConsistentMap<>("onos-transactions", this.database, serializer); 63 + this.transactions = new DefaultAsyncConsistentMap<>("onos-transactions", this.database, serializer, false);
64 } 64 }
65 65
66 /** 66 /**
...@@ -121,4 +121,4 @@ public class TransactionManager { ...@@ -121,4 +121,4 @@ public class TransactionManager {
121 transaction.transition(Transaction.State.ROLLEDBACK))) 121 transaction.transition(Transaction.State.ROLLEDBACK)))
122 .thenApply(v -> true); 122 .thenApply(v -> true);
123 } 123 }
124 -}
...\ No newline at end of file ...\ No newline at end of file
124 +}
......