Explicitly disallow null values in the map
Change-Id: I3b8d287a534e85d9454ca261a8eb666c477c43c1
Showing
2 changed files
with
21 additions
and
3 deletions
... | @@ -21,19 +21,22 @@ import java.util.Set; | ... | @@ -21,19 +21,22 @@ import java.util.Set; |
21 | 21 | ||
22 | /** | 22 | /** |
23 | * A distributed, eventually consistent map. | 23 | * A distributed, eventually consistent map. |
24 | - * | 24 | + * <p> |
25 | * This map does not offer read after writes consistency. Operations are | 25 | * This map does not offer read after writes consistency. Operations are |
26 | * serialized via the timestamps issued by the clock service. If two updates | 26 | * serialized via the timestamps issued by the clock service. If two updates |
27 | * are in conflict, the update with the more recent timestamp will endure. | 27 | * are in conflict, the update with the more recent timestamp will endure. |
28 | - * | 28 | + * </p><p> |
29 | * The interface is mostly similar to {@link java.util.Map} with some minor | 29 | * The interface is mostly similar to {@link java.util.Map} with some minor |
30 | * semantic changes and the addition of a listener framework (because the map | 30 | * semantic changes and the addition of a listener framework (because the map |
31 | * can be mutated by clients on other instances, not only through the local Java | 31 | * can be mutated by clients on other instances, not only through the local Java |
32 | * API). | 32 | * API). |
33 | - * | 33 | + * </p><p> |
34 | * Clients are expected to register an | 34 | * Clients are expected to register an |
35 | * {@link org.onosproject.store.impl.EventuallyConsistentMapListener} if they | 35 | * {@link org.onosproject.store.impl.EventuallyConsistentMapListener} if they |
36 | * are interested in receiving notifications of update to the map. | 36 | * are interested in receiving notifications of update to the map. |
37 | + * </p><p> | ||
38 | + * Null values are not allowed in this map. | ||
39 | + * </p> | ||
37 | */ | 40 | */ |
38 | public interface EventuallyConsistentMap<K, V> { | 41 | public interface EventuallyConsistentMap<K, V> { |
39 | 42 | ||
... | @@ -84,6 +87,8 @@ public interface EventuallyConsistentMap<K, V> { | ... | @@ -84,6 +87,8 @@ public interface EventuallyConsistentMap<K, V> { |
84 | * Clients are expected to register an | 87 | * Clients are expected to register an |
85 | * {@link org.onosproject.store.impl.EventuallyConsistentMapListener} if | 88 | * {@link org.onosproject.store.impl.EventuallyConsistentMapListener} if |
86 | * they are interested in receiving notification of updates to the map. | 89 | * they are interested in receiving notification of updates to the map. |
90 | + * </p><p> | ||
91 | + * Null values are not allowed in the map. | ||
87 | * </p> | 92 | * </p> |
88 | * | 93 | * |
89 | * @param key the key to add a mapping for in this map | 94 | * @param key the key to add a mapping for in this map | ... | ... |
... | @@ -85,6 +85,9 @@ public class EventuallyConsistentMapImpl<K, V> | ... | @@ -85,6 +85,9 @@ public class EventuallyConsistentMapImpl<K, V> |
85 | private volatile boolean destroyed = false; | 85 | private volatile boolean destroyed = false; |
86 | private static final String ERROR_DESTROYED = " map is already destroyed"; | 86 | private static final String ERROR_DESTROYED = " map is already destroyed"; |
87 | 87 | ||
88 | + private static final String ERROR_NULL_KEY = "Key cannot be null"; | ||
89 | + private static final String ERROR_NULL_VALUE = "Null values are not allowed"; | ||
90 | + | ||
88 | // TODO: Make these anti-entropy params configurable | 91 | // TODO: Make these anti-entropy params configurable |
89 | private long initialDelaySec = 5; | 92 | private long initialDelaySec = 5; |
90 | private long periodSec = 5; | 93 | private long periodSec = 5; |
... | @@ -193,12 +196,14 @@ public class EventuallyConsistentMapImpl<K, V> | ... | @@ -193,12 +196,14 @@ public class EventuallyConsistentMapImpl<K, V> |
193 | @Override | 196 | @Override |
194 | public boolean containsKey(K key) { | 197 | public boolean containsKey(K key) { |
195 | checkState(!destroyed, mapName + ERROR_DESTROYED); | 198 | checkState(!destroyed, mapName + ERROR_DESTROYED); |
199 | + checkNotNull(key, ERROR_NULL_KEY); | ||
196 | return items.containsKey(key); | 200 | return items.containsKey(key); |
197 | } | 201 | } |
198 | 202 | ||
199 | @Override | 203 | @Override |
200 | public boolean containsValue(V value) { | 204 | public boolean containsValue(V value) { |
201 | checkState(!destroyed, mapName + ERROR_DESTROYED); | 205 | checkState(!destroyed, mapName + ERROR_DESTROYED); |
206 | + checkNotNull(value, ERROR_NULL_VALUE); | ||
202 | 207 | ||
203 | return items.values().stream() | 208 | return items.values().stream() |
204 | .anyMatch(timestamped -> timestamped.value().equals(value)); | 209 | .anyMatch(timestamped -> timestamped.value().equals(value)); |
... | @@ -207,6 +212,7 @@ public class EventuallyConsistentMapImpl<K, V> | ... | @@ -207,6 +212,7 @@ public class EventuallyConsistentMapImpl<K, V> |
207 | @Override | 212 | @Override |
208 | public V get(K key) { | 213 | public V get(K key) { |
209 | checkState(!destroyed, mapName + ERROR_DESTROYED); | 214 | checkState(!destroyed, mapName + ERROR_DESTROYED); |
215 | + checkNotNull(key, ERROR_NULL_KEY); | ||
210 | 216 | ||
211 | Timestamped<V> value = items.get(key); | 217 | Timestamped<V> value = items.get(key); |
212 | if (value != null) { | 218 | if (value != null) { |
... | @@ -218,6 +224,8 @@ public class EventuallyConsistentMapImpl<K, V> | ... | @@ -218,6 +224,8 @@ public class EventuallyConsistentMapImpl<K, V> |
218 | @Override | 224 | @Override |
219 | public void put(K key, V value) { | 225 | public void put(K key, V value) { |
220 | checkState(!destroyed, mapName + ERROR_DESTROYED); | 226 | checkState(!destroyed, mapName + ERROR_DESTROYED); |
227 | + checkNotNull(key, ERROR_NULL_KEY); | ||
228 | + checkNotNull(value, ERROR_NULL_VALUE); | ||
221 | 229 | ||
222 | Timestamp timestamp = clockService.getTimestamp(key); | 230 | Timestamp timestamp = clockService.getTimestamp(key); |
223 | if (putInternal(key, value, timestamp)) { | 231 | if (putInternal(key, value, timestamp)) { |
... | @@ -250,6 +258,7 @@ public class EventuallyConsistentMapImpl<K, V> | ... | @@ -250,6 +258,7 @@ public class EventuallyConsistentMapImpl<K, V> |
250 | @Override | 258 | @Override |
251 | public void remove(K key) { | 259 | public void remove(K key) { |
252 | checkState(!destroyed, mapName + ERROR_DESTROYED); | 260 | checkState(!destroyed, mapName + ERROR_DESTROYED); |
261 | + checkNotNull(key, ERROR_NULL_KEY); | ||
253 | 262 | ||
254 | Timestamp timestamp = clockService.getTimestamp(key); | 263 | Timestamp timestamp = clockService.getTimestamp(key); |
255 | if (removeInternal(key, timestamp)) { | 264 | if (removeInternal(key, timestamp)) { |
... | @@ -282,6 +291,10 @@ public class EventuallyConsistentMapImpl<K, V> | ... | @@ -282,6 +291,10 @@ public class EventuallyConsistentMapImpl<K, V> |
282 | for (Map.Entry<? extends K, ? extends V> entry : m.entrySet()) { | 291 | for (Map.Entry<? extends K, ? extends V> entry : m.entrySet()) { |
283 | K key = entry.getKey(); | 292 | K key = entry.getKey(); |
284 | V value = entry.getValue(); | 293 | V value = entry.getValue(); |
294 | + | ||
295 | + checkNotNull(key, ERROR_NULL_KEY); | ||
296 | + checkNotNull(value, ERROR_NULL_VALUE); | ||
297 | + | ||
285 | Timestamp timestamp = clockService.getTimestamp(entry.getKey()); | 298 | Timestamp timestamp = clockService.getTimestamp(entry.getKey()); |
286 | 299 | ||
287 | if (putInternal(key, value, timestamp)) { | 300 | if (putInternal(key, value, timestamp)) { | ... | ... |
-
Please register or login to post a comment