moving out OptionalCacheLoader
Change-Id: If929ed119df1a0282e311188a00776e971f78991
diff --git a/core/store/src/main/java/org/onlab/onos/store/cluster/impl/package-info.java b/core/store/src/main/java/org/onlab/onos/store/cluster/impl/package-info.java
index fe3df5d..9f36b88 100644
--- a/core/store/src/main/java/org/onlab/onos/store/cluster/impl/package-info.java
+++ b/core/store/src/main/java/org/onlab/onos/store/cluster/impl/package-info.java
@@ -1,4 +1,4 @@
/**
* Implementation of a distributed cluster node store using Hazelcast.
*/
-package org.onlab.onos.store.cluster.impl;
\ No newline at end of file
+package org.onlab.onos.store.cluster.impl;
diff --git a/core/store/src/main/java/org/onlab/onos/store/device/impl/DistributedDeviceStore.java b/core/store/src/main/java/org/onlab/onos/store/device/impl/DistributedDeviceStore.java
index a4eb027..207036c 100644
--- a/core/store/src/main/java/org/onlab/onos/store/device/impl/DistributedDeviceStore.java
+++ b/core/store/src/main/java/org/onlab/onos/store/device/impl/DistributedDeviceStore.java
@@ -2,7 +2,6 @@
import com.google.common.base.Optional;
import com.google.common.cache.CacheBuilder;
-import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
@@ -13,6 +12,7 @@
import com.hazelcast.core.IMap;
import com.hazelcast.core.ISet;
import com.hazelcast.core.MapEvent;
+
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
@@ -33,6 +33,7 @@
import org.onlab.onos.net.provider.ProviderId;
import org.onlab.onos.store.StoreService;
import org.onlab.onos.store.impl.AbsentInvalidatingLoadingCache;
+import org.onlab.onos.store.impl.OptionalCacheLoader;
import org.slf4j.Logger;
import java.util.ArrayList;
@@ -78,7 +79,6 @@
private IMap<byte[], byte[]> rawDevicePorts;
private LoadingCache<DeviceId, Optional<Map<PortNumber, Port>>> devicePorts;
- // FIXME change to protected once we remove DistributedDeviceManagerTest.
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected StoreService storeService;
@@ -95,30 +95,36 @@
// TODO decide on Map name scheme to avoid collision
rawDevices = theInstance.getMap("devices");
+ final OptionalCacheLoader<DeviceId, DefaultDevice> deviceLoader
+ = new OptionalCacheLoader<>(storeService, rawDevices);
devices = new AbsentInvalidatingLoadingCache<>(
CacheBuilder.newBuilder()
- .build(new OptionalCacheLoader<DeviceId, DefaultDevice>(rawDevices)));
+ .build(deviceLoader));
// refresh/populate cache based on notification from other instance
rawDevices.addEntryListener(
new RemoteEventHandler<>(devices),
includeValue);
rawRoles = theInstance.getMap("roles");
+ final OptionalCacheLoader<DeviceId, MastershipRole> rolesLoader
+ = new OptionalCacheLoader<>(storeService, rawRoles);
roles = new AbsentInvalidatingLoadingCache<>(
CacheBuilder.newBuilder()
- .build(new OptionalCacheLoader<DeviceId, MastershipRole>(rawRoles)));
+ .build(rolesLoader));
// refresh/populate cache based on notification from other instance
rawRoles.addEntryListener(
new RemoteEventHandler<>(roles),
includeValue);
- // TODO cache avai
+ // TODO cache availableDevices
availableDevices = theInstance.getSet("availableDevices");
rawDevicePorts = theInstance.getMap("devicePorts");
+ final OptionalCacheLoader<DeviceId, Map<PortNumber, Port>> devicePortLoader
+ = new OptionalCacheLoader<>(storeService, rawDevicePorts);
devicePorts = new AbsentInvalidatingLoadingCache<>(
CacheBuilder.newBuilder()
- .build(new OptionalCacheLoader<DeviceId, Map<PortNumber, Port>>(rawDevicePorts)));
+ .build(devicePortLoader));
// refresh/populate cache based on notification from other instance
rawDevicePorts.addEntryListener(
new RemoteEventHandler<>(devicePorts),
@@ -439,7 +445,7 @@
@Override
public void entryRemoved(EntryEvent<byte[], byte[]> event) {
- cache.invalidate(storeService.<DeviceId>deserialize(event.getKey()));
+ cache.invalidate(storeService.<K>deserialize(event.getKey()));
}
@Override
@@ -447,37 +453,4 @@
entryUpdated(event);
}
}
-
- /**
- * CacheLoader to wrap Map value with Optional,
- * to handle negative hit on underlying IMap.
- *
- * @param <K> IMap key type after deserialization
- * @param <V> IMap value type after deserialization
- */
- public final class OptionalCacheLoader<K, V> extends
- CacheLoader<K, Optional<V>> {
-
- private IMap<byte[], byte[]> rawMap;
-
- /**
- * Constructor.
- *
- * @param rawMap underlying IMap
- */
- public OptionalCacheLoader(IMap<byte[], byte[]> rawMap) {
- this.rawMap = checkNotNull(rawMap);
- }
-
- @Override
- public Optional<V> load(K key) throws Exception {
- byte[] keyBytes = storeService.serialize(key);
- byte[] valBytes = rawMap.get(keyBytes);
- if (valBytes == null) {
- return Optional.absent();
- }
- V dev = deserialize(valBytes);
- return Optional.of(dev);
- }
- }
}
diff --git a/core/store/src/main/java/org/onlab/onos/store/impl/AbsentInvalidatingLoadingCache.java b/core/store/src/main/java/org/onlab/onos/store/impl/AbsentInvalidatingLoadingCache.java
index 1834a50..df4e70a 100644
--- a/core/store/src/main/java/org/onlab/onos/store/impl/AbsentInvalidatingLoadingCache.java
+++ b/core/store/src/main/java/org/onlab/onos/store/impl/AbsentInvalidatingLoadingCache.java
@@ -7,9 +7,24 @@
import com.google.common.cache.ForwardingLoadingCache.SimpleForwardingLoadingCache;
import com.google.common.cache.LoadingCache;
+/**
+ * Wrapper around LoadingCache to handle negative hit scenario.
+ * <p>
+ * When the LoadingCache returned Absent,
+ * this implementation will invalidate the entry immediately to avoid
+ * caching negative hits.
+ *
+ * @param <K> Cache key type
+ * @param <V> Cache value type. (Optional{@literal <V>})
+ */
public class AbsentInvalidatingLoadingCache<K, V> extends
SimpleForwardingLoadingCache<K, Optional<V>> {
+ /**
+ * Constructor.
+ *
+ * @param delegate actual {@link LoadingCache} to delegate loading.
+ */
public AbsentInvalidatingLoadingCache(LoadingCache<K, Optional<V>> delegate) {
super(delegate);
}
diff --git a/core/store/src/main/java/org/onlab/onos/store/impl/OptionalCacheLoader.java b/core/store/src/main/java/org/onlab/onos/store/impl/OptionalCacheLoader.java
new file mode 100644
index 0000000..47a42ee
--- /dev/null
+++ b/core/store/src/main/java/org/onlab/onos/store/impl/OptionalCacheLoader.java
@@ -0,0 +1,45 @@
+package org.onlab.onos.store.impl;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import org.onlab.onos.store.StoreService;
+
+import com.google.common.base.Optional;
+import com.google.common.cache.CacheLoader;
+import com.hazelcast.core.IMap;
+
+/**
+ * CacheLoader to wrap Map value with Optional,
+ * to handle negative hit on underlying IMap.
+ *
+ * @param <K> IMap key type after deserialization
+ * @param <V> IMap value type after deserialization
+ */
+public final class OptionalCacheLoader<K, V> extends
+ CacheLoader<K, Optional<V>> {
+
+ private final StoreService storeService;
+ private IMap<byte[], byte[]> rawMap;
+
+ /**
+ * Constructor.
+ *
+ * @param storeService to use for serialization
+ * @param rawMap underlying IMap
+ */
+ public OptionalCacheLoader(StoreService storeService, IMap<byte[], byte[]> rawMap) {
+ this.storeService = checkNotNull(storeService);
+ this.rawMap = checkNotNull(rawMap);
+ }
+
+ @Override
+ public Optional<V> load(K key) throws Exception {
+ byte[] keyBytes = storeService.serialize(key);
+ byte[] valBytes = rawMap.get(keyBytes);
+ if (valBytes == null) {
+ return Optional.absent();
+ }
+ V dev = storeService.deserialize(valBytes);
+ return Optional.of(dev);
+ }
+}
diff --git a/core/store/src/main/java/org/onlab/onos/store/serializers/package-info.java b/core/store/src/main/java/org/onlab/onos/store/serializers/package-info.java
index 55f9fcf..c66304f 100644
--- a/core/store/src/main/java/org/onlab/onos/store/serializers/package-info.java
+++ b/core/store/src/main/java/org/onlab/onos/store/serializers/package-info.java
@@ -1,4 +1,4 @@
/**
* Various Kryo serializers for use in distributed stores.
*/
-package org.onlab.onos.store.serializers;
\ No newline at end of file
+package org.onlab.onos.store.serializers;