Committed by
Gerrit Code Review
Support for building a immutable ConsistentMap and DistributedSet
Change-Id: Ic34684551f5c7d1f4fdc4cd3fc1a7bfabc5681f5
Showing
9 changed files
with
64 additions
and
12 deletions
... | @@ -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 | ... | ... |
core/store/dist/src/main/java/org/onosproject/store/consistent/impl/DefaultConsistentMapBuilder.java
... | @@ -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 | +} | ... | ... |
-
Please register or login to post a comment