From 92f103f5cc35c9807ae7717c9d8a25cda73b933c Mon Sep 17 00:00:00 2001 From: Giovanni Meo Date: Thu, 19 Sep 2013 11:33:45 +0200 Subject: [PATCH] Provide consistent hash code for enums and use it too - Java enums if used as key, works well in a single JVM, but across JVM the hashcode generated by them is not guaranteed to be the same and that breaks the calculation of a cluster wide consistent hash code, needed by the clustering services. The fix is to provide a consistent hashcode for the Enum and to use it in the dependent data structures. Change-Id: Iee80f262253a287e8bc8be4d5371d0bd407f0462 Signed-off-by: Giovanni Meo --- .../data/FlowEntryDistributionOrder.java | 2 +- .../opendaylight/controller/sal/action/Action.java | 2 +- .../controller/sal/action/ActionType.java | 10 +++++++++- .../opendaylight/controller/sal/core/UpdateType.java | 8 ++++++++ .../org/opendaylight/controller/sal/match/Match.java | 12 +++++++++++- .../opendaylight/controller/sal/match/MatchType.java | 10 +++++++++- .../opendaylight/controller/sal/utils/Status.java | 2 +- .../controller/sal/utils/StatusCode.java | 8 ++++++++ 8 files changed, 48 insertions(+), 6 deletions(-) diff --git a/opendaylight/forwardingrulesmanager/implementation/src/main/java/org/opendaylight/controller/forwardingrulesmanager/implementation/data/FlowEntryDistributionOrder.java b/opendaylight/forwardingrulesmanager/implementation/src/main/java/org/opendaylight/controller/forwardingrulesmanager/implementation/data/FlowEntryDistributionOrder.java index 672a290a24..b55a7e372b 100644 --- a/opendaylight/forwardingrulesmanager/implementation/src/main/java/org/opendaylight/controller/forwardingrulesmanager/implementation/data/FlowEntryDistributionOrder.java +++ b/opendaylight/forwardingrulesmanager/implementation/src/main/java/org/opendaylight/controller/forwardingrulesmanager/implementation/data/FlowEntryDistributionOrder.java @@ -79,7 +79,7 @@ public final class FlowEntryDistributionOrder implements Serializable { int result = 1; result = (prime * result) + ((entry == null) ? 0 : entry.hashCode()); result = (prime * result) + ((requestorController == null) ? 0 : requestorController.hashCode()); - result = (prime * result) + ((upType == null) ? 0 : upType.hashCode()); + result = (prime * result) + ((upType == null) ? 0 : upType.calculateConsistentHashCode()); return result; } diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/Action.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/Action.java index 515a61eab7..a1bf55ddaf 100644 --- a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/Action.java +++ b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/Action.java @@ -125,7 +125,7 @@ public abstract class Action implements Serializable { public int hashCode() { final int prime = 31; int result = 1; - result = prime * result + ((type == null) ? 0 : type.hashCode()); + result = prime * result + ((type == null) ? 0 : type.calculateConsistentHashCode()); return result; } diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/ActionType.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/ActionType.java index 7da6fa9115..b491c5fcea 100644 --- a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/ActionType.java +++ b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/ActionType.java @@ -75,4 +75,12 @@ public enum ActionType { return true; } } -} \ No newline at end of file + + public int calculateConsistentHashCode() { + if (this.id != null) { + return this.id.hashCode(); + } else { + return 0; + } + } +} diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/UpdateType.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/UpdateType.java index 2e9058abe8..6642eaf44b 100644 --- a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/UpdateType.java +++ b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/UpdateType.java @@ -28,4 +28,12 @@ public enum UpdateType { public String getName() { return this.name; } + + public int calculateConsistentHashCode() { + if (this.name != null) { + return this.name.hashCode(); + } else { + return 0; + } + } } diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/match/Match.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/match/Match.java index b6381cc7d8..b8f776fc17 100644 --- a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/match/Match.java +++ b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/match/Match.java @@ -441,7 +441,17 @@ public class Match implements Cloneable, Serializable { public int hashCode() { final int prime = 31; int result = 1; - result = prime * result + ((fields == null) ? 0 : fields.hashCode()); + if (this.fields == null) { + result = prime * result; + } else { + int sum = 0; + for (MatchType field : this.fields.keySet()) { + MatchField f = this.fields.get(field); + sum = sum + ((field==null ? 0 : field.calculateConsistentHashCode()) ^ + (f==null ? 0 : f.hashCode())); + } + result = prime * result + sum; + } result = prime * result + matches; return result; } diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/match/MatchType.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/match/MatchType.java index f4c8f4ae80..800f6d5972 100644 --- a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/match/MatchType.java +++ b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/match/MatchType.java @@ -235,7 +235,7 @@ public enum MatchType { public int hashCode(Object v, Object m) { final int prime = 31; int result = 1; - result = prime * result + this.hashCode(); + result = prime * result + this.calculateConsistentHashCode(); switch (this) { case DL_SRC: @@ -316,4 +316,12 @@ public enum MatchType { return (this.equalValues(value1, value2) && this.equalMasks(mask1, mask2)); } } + + public int calculateConsistentHashCode() { + if (this.id != null) { + return this.id.hashCode(); + } else { + return 0; + } + } } diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/Status.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/Status.java index a7a44456cc..04364bbeb4 100644 --- a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/Status.java +++ b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/Status.java @@ -123,7 +123,7 @@ public class Status implements Serializable { public int hashCode() { final int prime = 31; int result = 1; - result = prime * result + ((code == null) ? 0 : code.hashCode()); + result = prime * result + ((code == null) ? 0 : code.calculateConsistentHashCode()); return result; } diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/StatusCode.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/StatusCode.java index ce91ff440d..86b0d53fba 100644 --- a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/StatusCode.java +++ b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/StatusCode.java @@ -41,8 +41,16 @@ public enum StatusCode { /** * Prints the description associated to the code value */ + @Override public String toString() { return description; } + public int calculateConsistentHashCode() { + if (this.description != null) { + return this.description.hashCode(); + } else { + return 0; + } + } } -- 2.36.6