java_gen.HashValueUtils - prefixBit - remove useless hash value, add unit test

Also fix numBits==0 corner case bug discovered by unit test
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/HashValueUtils.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/HashValueUtils.java
index 6780035..15f8a9b 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/HashValueUtils.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/HashValueUtils.java
@@ -14,4 +14,16 @@
         return key ^ (value & valueMask);
     }
 
+    public static int prefixBits(long raw1, int numBits) {
+        Preconditions.checkArgument(numBits >= 0 && numBits <= 32,
+                "numBits must be in range [0, 32]");
+
+        if(numBits == 0)
+            return 0;
+
+        final int shiftDown = 64 - numBits;
+
+        return (int) (raw1 >>> shiftDown);
+    }
+
 }
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/U128.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/U128.java
index 747e566..af76aee 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/U128.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/U128.java
@@ -2,7 +2,6 @@
 
 import org.jboss.netty.buffer.ChannelBuffer;
 
-import com.google.common.base.Preconditions;
 import com.google.common.hash.PrimitiveSink;
 
 public class U128 implements OFValueType<U128>, HashValue<U128> {
@@ -121,15 +120,7 @@
 
     @Override
     public int prefixBits(int numBits) {
-        Preconditions.checkArgument(numBits <= 31, "numBits must be <= 31");
-
-        Preconditions.checkArgument(numBits >= 0 && numBits < 32,
-                "numBits must be in range [0, 32[");
-
-        final int mask = (1 << numBits) -1;
-        final int shiftDown = 64 - numBits;
-
-        return (int) ((raw1 >>> shiftDown) & mask);
+        return HashValueUtils.prefixBits(this.raw1, numBits);
     }
 
     @Override
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/U64.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/U64.java
index dd62cd0..9001eb8 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/U64.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/U64.java
@@ -24,7 +24,6 @@
 import org.projectfloodlight.openflow.protocol.OFMessageReader;
 import org.projectfloodlight.openflow.protocol.Writeable;
 
-import com.google.common.base.Preconditions;
 import com.google.common.hash.PrimitiveSink;
 import com.google.common.primitives.UnsignedLongs;
 
@@ -154,13 +153,7 @@
      */
     @Override
     public int prefixBits(int numBits) {
-        Preconditions.checkArgument(numBits >= 0 && numBits < 32,
-                "numBits must be in range [0, 32[");
-
-        final int mask = (1 << numBits) -1;
-        final int shiftDown = 64 - numBits;
-
-        return (int) ((raw >>> shiftDown) & mask);
+        return HashValueUtils.prefixBits(raw, numBits);
     }
 
     @Override
diff --git a/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/U128Test.java b/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/U128Test.java
index 2313d7c..310dab0 100644
--- a/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/U128Test.java
+++ b/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/U128Test.java
@@ -7,6 +7,7 @@
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 import org.junit.Test;
 
@@ -86,6 +87,42 @@
     }
 
     @Test
+    public void testKeyBits() {
+        U128 zeroU = U128.of(0,0);
+        assertThat(zeroU.prefixBits(0), equalTo(0));
+        assertThat(zeroU.prefixBits(16), equalTo(0));
+        assertThat(zeroU.prefixBits(32), equalTo(0));
+
+        checkInvalidKeyBitSize(zeroU, 33);
+        checkInvalidKeyBitSize(zeroU, 64);
+        assertThat(zeroU.prefixBits(3), equalTo(0));
+
+        U128 positiveU = U128.of(0x1234_5678_1234_5678L, 0x1234_5678_1234_5678L);
+        assertThat(positiveU.prefixBits(0), equalTo(0));
+        assertThat(positiveU.prefixBits(16), equalTo(0x1234));
+        assertThat(positiveU.prefixBits(32), equalTo(0x12345678));
+        checkInvalidKeyBitSize(positiveU, 33);
+        checkInvalidKeyBitSize(positiveU, 64);
+
+        U128 signedBitU = U128.of(0x8765_4321_8765_4321L, 0x1234_5678_1234_5678L);
+        assertThat(signedBitU.prefixBits(0), equalTo(0));
+        assertThat(signedBitU.prefixBits(16), equalTo(0x8765));
+        assertThat(signedBitU.prefixBits(32), equalTo(0x8765_4321));
+        checkInvalidKeyBitSize(signedBitU, 33);
+        checkInvalidKeyBitSize(signedBitU, 64);
+    }
+
+    private void
+    checkInvalidKeyBitSize(U128 u, int prefixBit) {
+        try {
+            u.prefixBits(prefixBit);
+            fail("Expected exception not thrown for "+prefixBit + " bits");
+        } catch(IllegalArgumentException e) {
+            // expected
+        }
+    }
+
+    @Test
     public void testCombine() {
         long key = 0x1234567890abcdefL;
         long val = 0xdeafbeefdeadbeefL;
diff --git a/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/U64Test.java b/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/U64Test.java
index a979fab..b0cca23 100644
--- a/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/U64Test.java
+++ b/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/U64Test.java
@@ -6,6 +6,7 @@
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 import java.math.BigInteger;
 
@@ -78,4 +79,40 @@
                 equalTo(U64.of(key & ~tenMask | (key ^ val) & tenMask)));
     }
 
+    @Test
+    public void testKeyBits() {
+        U64 zeroU = U64.of(0);
+        assertThat(zeroU.prefixBits(0), equalTo(0));
+        assertThat(zeroU.prefixBits(16), equalTo(0));
+        assertThat(zeroU.prefixBits(32), equalTo(0));
+
+        checkInvalidKeyBitSize(zeroU, 33);
+        checkInvalidKeyBitSize(zeroU, 64);
+        assertThat(zeroU.prefixBits(3), equalTo(0));
+
+        U64 positiveU = U64.of(0x1234_5678_1234_5678L);
+        assertThat(positiveU.prefixBits(0), equalTo(0));
+        assertThat(positiveU.prefixBits(16), equalTo(0x1234));
+        assertThat(positiveU.prefixBits(32), equalTo(0x12345678));
+        checkInvalidKeyBitSize(positiveU, 33);
+        checkInvalidKeyBitSize(positiveU, 64);
+
+        U64 signedBitU = U64.of(0x8765_4321_8765_4321L);
+        assertThat(signedBitU.prefixBits(0), equalTo(0));
+        assertThat(signedBitU.prefixBits(16), equalTo(0x8765));
+        assertThat(signedBitU.prefixBits(32), equalTo(0x8765_4321));
+        checkInvalidKeyBitSize(signedBitU, 33);
+        checkInvalidKeyBitSize(signedBitU, 64);
+    }
+
+    private void
+            checkInvalidKeyBitSize(U64 u, int prefixBit) {
+        try {
+            u.prefixBits(prefixBit);
+            fail("Expected exception not thrown for "+prefixBit + " bits");
+        } catch(IllegalArgumentException e) {
+            // expected
+        }
+    }
+
 }