java_gen: implement HashValue protocol
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 f480c47..dd62cd0 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,10 +24,11 @@
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;
-public class U64 implements Writeable, OFValueType<U64> {
+public class U64 implements Writeable, OFValueType<U64>, HashValue<U64> {
private static final long UNSIGNED_MASK = 0x7fffffffffffffffL;
private final static long ZERO_VAL = 0;
public final static U64 ZERO = new U64(ZERO_VAL);
@@ -110,7 +111,7 @@
@Override
public U64 applyMask(U64 mask) {
- return ofRaw(raw & mask.raw);
+ return and(mask);
}
@Override
@@ -128,6 +129,45 @@
sink.putLong(raw);
}
+ @Override
+ public U64 inverse() {
+ return U64.of(~raw);
+ }
+
+ @Override
+ public U64 or(U64 other) {
+ return U64.of(raw | other.raw);
+ }
+
+ @Override
+ public U64 and(U64 other) {
+ return ofRaw(raw & other.raw);
+ }
+ @Override
+ public U64 xor(U64 other) {
+ return U64.of(raw ^ other.raw);
+ }
+
+ /** return the "numBits" highest-order bits of the hash.
+ * @param numBits number of higest-order bits to return [0-32].
+ * @return a numberic value of the 0-32 highest-order bits.
+ */
+ @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);
+ }
+
+ @Override
+ public U64 combineWithValue(U64 value, int keyBits) {
+ return U64.of(HashValueUtils.combineWithValue(this.raw, value.raw, keyBits));
+ }
+
public final static Reader READER = new Reader();
private static class Reader implements OFMessageReader<U64> {
@@ -136,4 +176,6 @@
return U64.ofRaw(bb.readLong());
}
}
+
+
}
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 e45e8a0..a979fab 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
@@ -1,6 +1,11 @@
package org.projectfloodlight.openflow.types;
+import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
import java.math.BigInteger;
@@ -18,9 +23,59 @@
@Test
public void testNegativeRaws() {
- long minus_1 = 0xFFffFFffFFffFFffL;
+ long minus_1 = 0xFFFF_FFFF_FFFF_FFFFL;
assertEquals(minus_1, U64.ofRaw(minus_1).getValue());
- assertEquals(new BigInteger("FFffFFffFFffFFff", 16), U64.ofRaw(minus_1).getBigInteger());
+ assertEquals(new BigInteger("FFFF_FFFF_FFFF_FFFF".replace("_", ""), 16), U64.ofRaw(minus_1).getBigInteger());
assertEquals(new BigInteger("18446744073709551615"), U64.ofRaw(minus_1).getBigInteger());
}
+
+ @Test
+ public void testEqualHashCode() {
+ U64 h1 = U64.of(0xdeafbeefdeadbeefL);
+ U64 h2 = U64.of(0xdeafbeefdeadbeefL);
+ U64 h3 = U64.of(0xeeafbeefdeadbeefL);
+
+ assertTrue(h1.equals(h1));
+ assertTrue(h1.equals(h2));
+ assertFalse(h1.equals(h3));
+ assertTrue(h2.equals(h1));
+
+ assertEquals(h1.hashCode(), h2.hashCode());
+ assertNotEquals(h1.hashCode(), h3.hashCode()); // not technically a requirement, but we'll hopefully be lucky.
+ }
+
+ @Test
+ public void testXor() {
+ U64 hNull = U64.of(0);
+ U64 hDeadBeef = U64.of(0xdeafbeefdeadbeefL);
+ assertThat(hNull.xor(hNull), equalTo(hNull));
+ assertThat(hNull.xor(hDeadBeef), equalTo(hDeadBeef));
+ assertThat(hDeadBeef.xor(hNull), equalTo(hDeadBeef));
+ assertThat(hDeadBeef.xor(hDeadBeef), equalTo(hNull));
+
+
+ U64 h1 = U64.of(1L);
+ U64 h8 = U64.of(0x8000000000000000L);
+ U64 h81 = U64.of(0x8000000000000001L);
+ assertThat(h1.xor(h8), equalTo(h81));
+ }
+
+ @Test
+ public void testCombine() {
+ long key = 0x1234567890abcdefL;
+ long val = 0xdeafbeefdeadbeefL;
+ U64 hkey = U64.of(key);
+ U64 hVal = U64.of(val);
+
+ assertThat(hkey.combineWithValue(hVal, 0), equalTo(hkey.xor(hVal)));
+ assertThat(hkey.combineWithValue(hVal, 64), equalTo(hkey));
+ long mask32 = 0x00000000FFFFFFFFL;
+ assertThat(hkey.combineWithValue(hVal, 32),
+ equalTo(U64.of(key & ~mask32| (key ^ val) & mask32)));
+
+ long tenMask = 0x003FFFFFFFFFFFFFL;
+ assertThat(hkey.combineWithValue(hVal, 10),
+ equalTo(U64.of(key & ~tenMask | (key ^ val) & tenMask)));
+ }
+
}