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