Eliminate the peformance penalty introduced in ReplicaInfoService.getReplicaInfoFor
Change-Id: Ie37d7e80c4dbf37a2ae6f452f6f66f4505d69a29
diff --git a/core/store/dist/src/main/java/org/onosproject/store/flow/ReplicaInfo.java b/core/store/dist/src/main/java/org/onosproject/store/flow/ReplicaInfo.java
index d33ac203..6011c16 100644
--- a/core/store/dist/src/main/java/org/onosproject/store/flow/ReplicaInfo.java
+++ b/core/store/dist/src/main/java/org/onosproject/store/flow/ReplicaInfo.java
@@ -22,6 +22,7 @@
import org.onosproject.cluster.NodeId;
+import com.google.common.base.Objects;
import com.google.common.base.Optional;
/**
@@ -61,6 +62,21 @@
return backups;
}
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(master, backups);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (!(other instanceof ReplicaInfo)) {
+ return false;
+ }
+ ReplicaInfo that = (ReplicaInfo) other;
+ return Objects.equal(this.master, that.master) &&
+ Objects.equal(this.backups, that.backups);
+ }
+
// for Serializer
private ReplicaInfo() {
this.master = Optional.absent();
diff --git a/core/store/dist/src/main/java/org/onosproject/store/flow/impl/ReplicaInfoManager.java b/core/store/dist/src/main/java/org/onosproject/store/flow/impl/ReplicaInfoManager.java
index f94afe0..eaf3f8e 100644
--- a/core/store/dist/src/main/java/org/onosproject/store/flow/impl/ReplicaInfoManager.java
+++ b/core/store/dist/src/main/java/org/onosproject/store/flow/impl/ReplicaInfoManager.java
@@ -22,6 +22,7 @@
import java.util.Collections;
import java.util.List;
+import java.util.Map;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
@@ -43,6 +44,10 @@
import org.onosproject.store.flow.ReplicaInfoService;
import org.slf4j.Logger;
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Maps;
+
/**
* Manages replica placement information.
*/
@@ -63,6 +68,8 @@
protected final AbstractListenerRegistry<ReplicaInfoEvent, ReplicaInfoEventListener>
listenerRegistry = new AbstractListenerRegistry<>();
+ private final Map<DeviceId, ReplicaInfo> deviceReplicaInfoMap = Maps.newConcurrentMap();
+
@Activate
public void activate() {
eventDispatcher.addSink(ReplicaInfoEvent.class, listenerRegistry);
@@ -79,7 +86,9 @@
@Override
public ReplicaInfo getReplicaInfoFor(DeviceId deviceId) {
- return buildFromRoleInfo(mastershipService.getNodesFor(deviceId));
+ return deviceReplicaInfoMap.computeIfAbsent(
+ deviceId,
+ id -> buildFromRoleInfo(mastershipService.getNodesFor(deviceId)));
}
@Override
@@ -94,7 +103,7 @@
private static ReplicaInfo buildFromRoleInfo(RoleInfo roles) {
List<NodeId> backups = roles.backups() == null ?
- Collections.emptyList() : roles.backups();
+ Collections.emptyList() : ImmutableList.copyOf(roles.backups());
return new ReplicaInfo(roles.master(), backups);
}
@@ -102,8 +111,12 @@
@Override
public void event(MastershipEvent event) {
+ final DeviceId deviceId = event.subject();
final ReplicaInfo replicaInfo = buildFromRoleInfo(event.roleInfo());
-
+ ReplicaInfo oldReplicaInfo = deviceReplicaInfoMap.put(deviceId, replicaInfo);
+ if (Objects.equal(oldReplicaInfo, replicaInfo)) {
+ return;
+ }
switch (event.type()) {
case MASTER_CHANGED:
eventDispatcher.post(new ReplicaInfoEvent(MASTER_CHANGED,
diff --git a/core/store/dist/src/main/java/org/onosproject/store/mastership/impl/ConsistentDeviceMastershipStore.java b/core/store/dist/src/main/java/org/onosproject/store/mastership/impl/ConsistentDeviceMastershipStore.java
index bbd7b7a..9aa376a 100644
--- a/core/store/dist/src/main/java/org/onosproject/store/mastership/impl/ConsistentDeviceMastershipStore.java
+++ b/core/store/dist/src/main/java/org/onosproject/store/mastership/impl/ConsistentDeviceMastershipStore.java
@@ -17,6 +17,7 @@
import static org.onlab.util.Tools.groupedThreads;
import static org.onlab.util.Tools.futureGetOrElse;
+import static org.onosproject.mastership.MastershipEvent.Type.BACKUPS_CHANGED;
import static org.onosproject.mastership.MastershipEvent.Type.MASTER_CHANGED;
import static org.slf4j.LoggerFactory.getLogger;
import static com.google.common.base.Preconditions.checkArgument;
@@ -409,6 +410,9 @@
case LEADER_BOOTED:
notifyDelegate(new MastershipEvent(MASTER_CHANGED, deviceId, getNodes(deviceId)));
break;
+ case CANDIDATES_CHANGED:
+ notifyDelegate(new MastershipEvent(BACKUPS_CHANGED, deviceId, getNodes(deviceId)));
+ break;
default:
return;
}