Support for a java.util.Map implementation backed by ConsistentMap
Change-Id: I73240b69d0913f7534bd4006411ab217a40b254c
diff --git a/core/api/src/main/java/org/onosproject/store/service/ConsistentMap.java b/core/api/src/main/java/org/onosproject/store/service/ConsistentMap.java
index f1ef356..289da20 100644
--- a/core/api/src/main/java/org/onosproject/store/service/ConsistentMap.java
+++ b/core/api/src/main/java/org/onosproject/store/service/ConsistentMap.java
@@ -17,6 +17,7 @@
package org.onosproject.store.service;
import java.util.Collection;
+import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.function.BiFunction;
@@ -281,4 +282,10 @@
* @param listener listener to unregister
*/
void removeListener(MapEventListener<K, V> listener);
-}
+
+ /**
+ * Returns a java.util.Map instance backed by this ConsistentMap.
+ * @return java.util.Map
+ */
+ Map<K, V> asJavaMap();
+}
\ No newline at end of file
diff --git a/core/api/src/test/java/org/onosproject/store/service/ConsistentMapAdapter.java b/core/api/src/test/java/org/onosproject/store/service/ConsistentMapAdapter.java
index e6df572..d0c1adf 100644
--- a/core/api/src/test/java/org/onosproject/store/service/ConsistentMapAdapter.java
+++ b/core/api/src/test/java/org/onosproject/store/service/ConsistentMapAdapter.java
@@ -141,4 +141,9 @@
public void removeListener(MapEventListener<K, V> listener) {
}
+
+ @Override
+ public Map<K, V> asJavaMap() {
+ return null;
+ }
}
diff --git a/core/store/dist/src/main/java/org/onosproject/store/consistent/impl/ConsistentMapBackedJavaMap.java b/core/store/dist/src/main/java/org/onosproject/store/consistent/impl/ConsistentMapBackedJavaMap.java
new file mode 100644
index 0000000..58aca31
--- /dev/null
+++ b/core/store/dist/src/main/java/org/onosproject/store/consistent/impl/ConsistentMapBackedJavaMap.java
@@ -0,0 +1,145 @@
+package org.onosproject.store.consistent.impl;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.BiConsumer;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+import org.onosproject.store.service.ConsistentMap;
+import org.onosproject.store.service.Versioned;
+
+import com.google.common.collect.Collections2;
+import com.google.common.collect.Maps;
+
+/**
+ * Standard java Map backed by a ConsistentMap.
+ *
+ * @param <K> key type
+ * @param <V> value type
+ */
+public final class ConsistentMapBackedJavaMap<K, V> implements Map<K, V> {
+
+ private final ConsistentMap<K, V> backingMap;
+
+ public ConsistentMapBackedJavaMap(ConsistentMap<K, V> backingMap) {
+ this.backingMap = backingMap;
+ }
+
+ @Override
+ public int size() {
+ return backingMap.size();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return backingMap.isEmpty();
+ }
+
+ @Override
+ public boolean containsKey(Object key) {
+ return backingMap.containsKey((K) key);
+ }
+
+ @Override
+ public boolean containsValue(Object value) {
+ return backingMap.containsValue((V) value);
+ }
+
+ @Override
+ public V get(Object key) {
+ return Versioned.valueOrElse(backingMap.get((K) key), null);
+ }
+
+ @Override
+ public V getOrDefault(Object key, V defaultValue) {
+ return Versioned.valueOrElse(backingMap.get((K) key), defaultValue);
+ }
+
+ @Override
+ public V put(K key, V value) {
+ return Versioned.valueOrElse(backingMap.put(key, value), null);
+ }
+
+ @Override
+ public V putIfAbsent(K key, V value) {
+ return Versioned.valueOrElse(backingMap.putIfAbsent(key, value), null);
+ }
+
+ @Override
+ public V remove(Object key) {
+ return Versioned.valueOrElse(backingMap.remove((K) key), null);
+ }
+
+ @Override
+ public boolean remove(Object key, Object value) {
+ return backingMap.remove((K) key, (V) value);
+ }
+
+ @Override
+ public V replace(K key, V value) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean replace(K key, V oldValue, V newValue) {
+ return backingMap.replace(key, oldValue, newValue);
+ }
+
+ @Override
+ public void putAll(Map<? extends K, ? extends V> m) {
+ m.forEach((k, v) -> {
+ backingMap.put(k, v);
+ });
+ }
+
+ @Override
+ public void clear() {
+ backingMap.clear();
+ }
+
+ @Override
+ public V compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
+ return Versioned.valueOrElse(backingMap.compute(key, remappingFunction), null);
+ }
+
+ @Override
+ public V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
+ return Versioned.valueOrElse(backingMap.computeIfAbsent(key, mappingFunction), null);
+ }
+
+ @Override
+ public V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
+ return Versioned.valueOrElse(backingMap.computeIfPresent(key, remappingFunction), null);
+ }
+
+ @Override
+ public Set<K> keySet() {
+ return backingMap.keySet();
+ }
+
+ @Override
+ public Collection<V> values() {
+ return Collections2.transform(backingMap.values(), v -> v.value());
+ }
+
+ @Override
+ public Set<java.util.Map.Entry<K, V>> entrySet() {
+ return backingMap.entrySet()
+ .stream()
+ .map(entry -> Maps.immutableEntry(entry.getKey(), entry.getValue().value()))
+ .collect(Collectors.toSet());
+ }
+
+ @Override
+ public void forEach(BiConsumer<? super K, ? super V> action) {
+ entrySet().forEach(e -> action.accept(e.getKey(), e.getValue()));
+ }
+
+ @Override
+ public V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
+ return computeIfPresent(key, (k, v) -> v == null ? value : remappingFunction.apply(v, value));
+ }
+}
\ No newline at end of file
diff --git a/core/store/dist/src/main/java/org/onosproject/store/consistent/impl/DefaultConsistentMap.java b/core/store/dist/src/main/java/org/onosproject/store/consistent/impl/DefaultConsistentMap.java
index d6a657c..6f7b548 100644
--- a/core/store/dist/src/main/java/org/onosproject/store/consistent/impl/DefaultConsistentMap.java
+++ b/core/store/dist/src/main/java/org/onosproject/store/consistent/impl/DefaultConsistentMap.java
@@ -17,6 +17,7 @@
package org.onosproject.store.consistent.impl;
import java.util.Collection;
+import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
@@ -44,6 +45,7 @@
private static final int OPERATION_TIMEOUT_MILLIS = 5000;
private final DefaultAsyncConsistentMap<K, V> asyncMap;
+ private Map<K, V> javaMap;
public String name() {
return asyncMap.name();
@@ -189,4 +191,14 @@
public void removeListener(MapEventListener<K, V> listener) {
asyncMap.addListener(listener);
}
+
+ @Override
+ public Map<K, V> asJavaMap() {
+ synchronized (this) {
+ if (javaMap == null) {
+ javaMap = new ConsistentMapBackedJavaMap<>(this);
+ }
+ }
+ return javaMap;
+ }
}
\ No newline at end of file