Provide consistent hash code for enums and use it too 92/1292/2
authorGiovanni Meo <gmeo@cisco.com>
Thu, 19 Sep 2013 09:33:45 +0000 (11:33 +0200)
committerGerrit Code Review <gerrit@opendaylight.org>
Thu, 19 Sep 2013 14:37:58 +0000 (14:37 +0000)
- 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 <gmeo@cisco.com>
opendaylight/forwardingrulesmanager/implementation/src/main/java/org/opendaylight/controller/forwardingrulesmanager/implementation/data/FlowEntryDistributionOrder.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/Action.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/action/ActionType.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/UpdateType.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/match/Match.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/match/MatchType.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/Status.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/StatusCode.java

index 672a290a2427f6bb1676ab31f3b72e21ffaa922e..b55a7e372b83d29bb7f52b50fc8548d5f0afc09f 100644 (file)
@@ -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());
         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;
     }
 
         return result;
     }
 
index 515a61eab75c53e03582c0434e8b724b88428432..a1bf55ddaf54f519b22504eb0a18c2068216c03d 100644 (file)
@@ -125,7 +125,7 @@ public abstract class Action implements Serializable {
     public int hashCode() {
         final int prime = 31;
         int result = 1;
     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;
     }
 
         return result;
     }
 
index 7da6fa911514d252bee6e647b5eae655420ff0cf..b491c5fcea2e4b53914102a91e88a76591ac5d22 100644 (file)
@@ -75,4 +75,12 @@ public enum ActionType {
             return true;
         }
     }
             return true;
         }
     }
-}
\ No newline at end of file
+
+    public int calculateConsistentHashCode() {
+        if (this.id != null) {
+            return this.id.hashCode();
+        } else {
+            return 0;
+        }
+    }
+}
index 2e9058abe8c781cf57de9cd0ff51bf5d7de9b554..6642eaf44bb1a489d8ab06cb3717c980b251ff89 100644 (file)
@@ -28,4 +28,12 @@ public enum UpdateType {
     public String getName() {
         return this.name;
     }
     public String getName() {
         return this.name;
     }
+
+    public int calculateConsistentHashCode() {
+        if (this.name != null) {
+            return this.name.hashCode();
+        } else {
+            return 0;
+        }
+    }
 }
 }
index b6381cc7d8fbe089cc96dbea518e82be27c06817..b8f776fc176d49085487d556dcd4e11a353751cd 100644 (file)
@@ -441,7 +441,17 @@ public class Match implements Cloneable, Serializable {
     public int hashCode() {
         final int prime = 31;
         int result = 1;
     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;
     }
         result = prime * result + matches;
         return result;
     }
index f4c8f4ae8039e8c18fbe35adb277de8c1db053df..800f6d5972bc257c8aecf1ad14b0d650b3797641 100644 (file)
@@ -235,7 +235,7 @@ public enum MatchType {
     public int hashCode(Object v, Object m) {
         final int prime = 31;
         int result = 1;
     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:
 
         switch (this) {
         case DL_SRC:
@@ -316,4 +316,12 @@ public enum MatchType {
             return (this.equalValues(value1, value2) && this.equalMasks(mask1, mask2));
         }
     }
             return (this.equalValues(value1, value2) && this.equalMasks(mask1, mask2));
         }
     }
+
+    public int calculateConsistentHashCode() {
+        if (this.id != null) {
+            return this.id.hashCode();
+        } else {
+            return 0;
+        }
+    }
 }
 }
index a7a44456cc3011ec6e1957395f65dbcf2fccd9af..04364bbeb472fbc5a1e973aff3980ce98ba46efe 100644 (file)
@@ -123,7 +123,7 @@ public class Status implements Serializable {
     public int hashCode() {
         final int prime = 31;
         int result = 1;
     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;
     }
 
         return result;
     }
 
index ce91ff440d1f70f4dba814700e7d65c34c1873af..86b0d53fba70a797dac4059102f007a1d4805137 100644 (file)
@@ -41,8 +41,16 @@ public enum StatusCode {
         /**
          * Prints the description associated to the code value
          */
         /**
          * Prints the description associated to the code value
          */
+        @Override
         public String toString() {
                 return description;
         }
 
         public String toString() {
                 return description;
         }
 
+    public int calculateConsistentHashCode() {
+        if (this.description != null) {
+            return this.description.hashCode();
+        } else {
+            return 0;
+        }
+    }
 }
 }