aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/consistent/impl
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/consistent/impl')
-rw-r--r--framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/consistent/impl/DefaultAsyncConsistentMap.java49
-rw-r--r--framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/consistent/impl/MappingSet.java131
2 files changed, 164 insertions, 16 deletions
diff --git a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/consistent/impl/DefaultAsyncConsistentMap.java b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/consistent/impl/DefaultAsyncConsistentMap.java
index c6d300c9..af2bb74d 100644
--- a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/consistent/impl/DefaultAsyncConsistentMap.java
+++ b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/consistent/impl/DefaultAsyncConsistentMap.java
@@ -20,6 +20,7 @@ import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.Maps;
+
import org.onlab.util.HexString;
import org.onlab.util.SharedExecutors;
import org.onlab.util.Tools;
@@ -33,6 +34,7 @@ import org.onosproject.store.service.Versioned;
import org.slf4j.Logger;
import java.util.Collection;
+import java.util.Collections;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
@@ -92,18 +94,25 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V
private static final String ERROR_NULL_KEY = "Key cannot be null";
private static final String ERROR_NULL_VALUE = "Null values are not allowed";
- private final LoadingCache<K, String> keyCache = CacheBuilder.newBuilder()
+ // String representation of serialized byte[] -> original key Object
+ private final LoadingCache<String, K> keyCache = CacheBuilder.newBuilder()
.softValues()
- .build(new CacheLoader<K, String>() {
+ .build(new CacheLoader<String, K>() {
@Override
- public String load(K key) {
- return HexString.toHexString(serializer.encode(key));
+ public K load(String key) {
+ return serializer.decode(HexString.fromHexString(key));
}
});
+ protected String sK(K key) {
+ String s = HexString.toHexString(serializer.encode(key));
+ keyCache.put(s, key);
+ return s;
+ }
+
protected K dK(String key) {
- return serializer.decode(HexString.fromHexString(key));
+ return keyCache.getUnchecked(key);
}
public DefaultAsyncConsistentMap(String name,
@@ -207,7 +216,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V
public CompletableFuture<Boolean> containsKey(K key) {
checkNotNull(key, ERROR_NULL_KEY);
final MeteringAgent.Context timer = monitor.startTimer(CONTAINS_KEY);
- return database.mapContainsKey(name, keyCache.getUnchecked(key))
+ return database.mapContainsKey(name, sK(key))
.whenComplete((r, e) -> timer.stop(e));
}
@@ -223,7 +232,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V
public CompletableFuture<Versioned<V>> get(K key) {
checkNotNull(key, ERROR_NULL_KEY);
final MeteringAgent.Context timer = monitor.startTimer(GET);
- return database.mapGet(name, keyCache.getUnchecked(key))
+ return database.mapGet(name, sK(key))
.whenComplete((r, e) -> timer.stop(e))
.thenApply(v -> v != null ? v.map(serializer::decode) : null);
}
@@ -328,10 +337,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V
public CompletableFuture<Set<K>> keySet() {
final MeteringAgent.Context timer = monitor.startTimer(KEY_SET);
return database.mapKeySet(name)
- .thenApply(s -> s
- .stream()
- .map(this::dK)
- .collect(Collectors.toSet()))
+ .thenApply(s -> newMappingKeySet(s))
.whenComplete((r, e) -> timer.stop(e));
}
@@ -351,10 +357,7 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V
final MeteringAgent.Context timer = monitor.startTimer(ENTRY_SET);
return database.mapEntrySet(name)
.whenComplete((r, e) -> timer.stop(e))
- .thenApply(s -> s
- .stream()
- .map(this::mapRawEntry)
- .collect(Collectors.toSet()));
+ .thenApply(s -> newMappingEntrySet(s));
}
@Override
@@ -413,17 +416,31 @@ public class DefaultAsyncConsistentMap<K, V> implements AsyncConsistentMap<K, V
checkIfUnmodifiable();
}
+ private Set<K> newMappingKeySet(Set<String> s) {
+ return new MappingSet<>(s, Collections::unmodifiableSet,
+ this::sK, this::dK);
+ }
+
+ private Set<Entry<K, Versioned<V>>> newMappingEntrySet(Set<Entry<String, Versioned<byte[]>>> s) {
+ return new MappingSet<>(s, Collections::unmodifiableSet,
+ this::reverseMapRawEntry, this::mapRawEntry);
+ }
+
private Map.Entry<K, Versioned<V>> mapRawEntry(Map.Entry<String, Versioned<byte[]>> e) {
return Maps.immutableEntry(dK(e.getKey()), e.getValue().<V>map(serializer::decode));
}
+ private Map.Entry<String, Versioned<byte[]>> reverseMapRawEntry(Map.Entry<K, Versioned<V>> e) {
+ return Maps.immutableEntry(sK(e.getKey()), e.getValue().map(serializer::encode));
+ }
+
private CompletableFuture<UpdateResult<K, V>> updateAndGet(K key,
Match<V> oldValueMatch,
Match<Long> oldVersionMatch,
V value) {
beforeUpdate(key);
return database.mapUpdate(name,
- keyCache.getUnchecked(key),
+ sK(key),
oldValueMatch.map(serializer::encode),
oldVersionMatch,
value == null ? null : serializer.encode(value))
diff --git a/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/consistent/impl/MappingSet.java b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/consistent/impl/MappingSet.java
new file mode 100644
index 00000000..9bf80a73
--- /dev/null
+++ b/framework/src/onos/core/store/dist/src/main/java/org/onosproject/store/consistent/impl/MappingSet.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.store.consistent.impl;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+import com.google.common.collect.Iterators;
+
+/**
+ * Set view backed by Set with element type {@code <BACK>} but returns
+ * element as {@code <OUT>} for convenience.
+ *
+ * @param <BACK> Backing {@link Set} element type.
+ * MappingSet will follow this type's equality behavior.
+ * @param <OUT> external facing element type.
+ * MappingSet will ignores equality defined by this type.
+ */
+class MappingSet<BACK, OUT> implements Set<OUT> {
+
+ private final Set<BACK> backedSet;
+ private final Function<OUT, BACK> toBack;
+ private final Function<BACK, OUT> toOut;
+
+ public MappingSet(Set<BACK> backedSet,
+ Function<Set<BACK>, Set<BACK>> supplier,
+ Function<OUT, BACK> toBack, Function<BACK, OUT> toOut) {
+ this.backedSet = supplier.apply(backedSet);
+ this.toBack = toBack;
+ this.toOut = toOut;
+ }
+
+ @Override
+ public int size() {
+ return backedSet.size();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return backedSet.isEmpty();
+ }
+
+ @Override
+ public boolean contains(Object o) {
+ return backedSet.contains(toBack.apply((OUT) o));
+ }
+
+ @Override
+ public Iterator<OUT> iterator() {
+ return Iterators.transform(backedSet.iterator(), toOut::apply);
+ }
+
+ @Override
+ public Object[] toArray() {
+ return backedSet.stream()
+ .map(toOut)
+ .toArray();
+ }
+
+ @Override
+ public <T> T[] toArray(T[] a) {
+ return backedSet.stream()
+ .map(toOut)
+ .toArray(size -> {
+ if (size < a.length) {
+ return (T[]) new Object[size];
+ } else {
+ Arrays.fill(a, null);
+ return a;
+ }
+ });
+ }
+
+ @Override
+ public boolean add(OUT e) {
+ return backedSet.add(toBack.apply(e));
+ }
+
+ @Override
+ public boolean remove(Object o) {
+ return backedSet.remove(toBack.apply((OUT) o));
+ }
+
+ @Override
+ public boolean containsAll(Collection<?> c) {
+ return c.stream()
+ .map(e -> toBack.apply((OUT) e))
+ .allMatch(backedSet::contains);
+ }
+
+ @Override
+ public boolean addAll(Collection<? extends OUT> c) {
+ return backedSet.addAll(c.stream().map(toBack).collect(Collectors.toList()));
+ }
+
+ @Override
+ public boolean retainAll(Collection<?> c) {
+ return backedSet.retainAll(c.stream()
+ .map(x -> toBack.apply((OUT) x))
+ .collect(Collectors.toList()));
+ }
+
+ @Override
+ public boolean removeAll(Collection<?> c) {
+ return backedSet.removeAll(c.stream()
+ .map(x -> toBack.apply((OUT) x))
+ .collect(Collectors.toList()));
+ }
+
+ @Override
+ public void clear() {
+ backedSet.clear();
+ }
+}