java_gen: renamed OFChecksum128 to U128 + implement HashValue
This has the same semantics as our other Uxx types.
diff --git a/java_gen/java_type.py b/java_gen/java_type.py
index 452ac58..471f1a8 100644
--- a/java_gen/java_type.py
+++ b/java_gen/java_type.py
@@ -311,6 +311,10 @@
u64 = JType('U64', 'long') \
.op(read='U64.ofRaw(bb.readLong())', write='bb.writeLong($name.getValue())', default="U64.ZERO", pub_type=True) \
.op(read='bb.readLong()', write='bb.writeLong($name)', pub_type=False)
+u128 = JType("U128") \
+ .op(read='U128.read16Bytes(bb)',
+ write='$name.write16Bytes(bb)',
+ default='U128.ZERO')
of_port = JType("OFPort") \
.op(version=1, read="OFPort.read2Bytes(bb)", write="$name.write2Bytes(bb)", default="OFPort.ANY") \
.op(version=ANY, read="OFPort.read4Bytes(bb)", write="$name.write4Bytes(bb)", default="OFPort.ANY")
@@ -491,10 +495,6 @@
.op(version=ANY, read="ClassId.read4Bytes(bb)", write="$name.write4Bytes(bb)", default="ClassId.NONE")
boolean_value = JType('OFBooleanValue', 'OFBooleanValue') \
.op(read='OFBooleanValue.of(bb.readByte() != 0)', write='bb.writeByte($name.getInt())', default="OFBooleanValue.FALSE")
-checksum = JType("OFChecksum128") \
- .op(read='OFChecksum128.read16Bytes(bb)',
- write='$name.write16Bytes(bb)',
- default='OFChecksum128.ZERO')
gen_table_id = JType("GenTableId") \
.op(read='GenTableId.read2Bytes(bb)',
write='$name.write2Bytes(bb)',
@@ -536,7 +536,7 @@
'of_oxm_t': oxm,
'of_meter_features_t': meter_features,
'of_bitmap_128_t': port_bitmap,
- 'of_checksum_128_t': checksum,
+ 'of_checksum_128_t': u128,
'of_bsn_vport_t': bsn_vport,
}
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFChecksum128.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFChecksum128.java
deleted file mode 100644
index 7578dc6..0000000
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/OFChecksum128.java
+++ /dev/null
@@ -1,80 +0,0 @@
-package org.projectfloodlight.openflow.types;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-
-import com.google.common.hash.PrimitiveSink;
-
-public class OFChecksum128 implements OFValueType<OFChecksum128> {
-
- static final int LENGTH = 16;
-
- private final long raw1; // MSBs
- private final long raw2; // LSBs
-
- public static final OFChecksum128 ZERO = new OFChecksum128(0, 0);
-
- private OFChecksum128(long raw1, long raw2) {
- this.raw1 = raw1;
- this.raw2 = raw2;
- }
-
- public static OFChecksum128 of(long raw1, long raw2) {
- if (raw1 == 0 && raw2 == 0)
- return ZERO;
- return new OFChecksum128(raw1, raw2);
- }
-
- @Override
- public int getLength() {
- return LENGTH;
- }
-
- @Override
- public OFChecksum128 applyMask(OFChecksum128 mask) {
- return of(this.raw1 & mask.raw1, this.raw2 & mask.raw2);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (!(obj instanceof OFChecksum128))
- return false;
- OFChecksum128 other = (OFChecksum128)obj;
- return (other.raw1 == this.raw1 && other.raw2 == this.raw2);
- }
-
- @Override
- public int hashCode() {
- return (int)(31 * raw1 + raw2);
- }
-
- public void write16Bytes(ChannelBuffer cb) {
- cb.writeLong(raw1);
- cb.writeLong(raw2);
- }
-
- public static OFChecksum128 read16Bytes(ChannelBuffer cb) {
- long raw1 = cb.readLong();
- long raw2 = cb.readLong();
- return of(raw1, raw2);
- }
-
- @Override
- public String toString() {
- return String.format("0x%016x%016x", raw1, raw2);
- }
-
- @Override
- public int compareTo(OFChecksum128 o) {
- long c = this.raw1 - o.raw1;
- if (c != 0)
- return Long.signum(c);
- return Long.signum(this.raw2 - o.raw2);
- }
-
- @Override
- public void putTo(PrimitiveSink sink) {
- sink.putLong(raw1);
- sink.putLong(raw2);
- }
-
-}
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
new file mode 100644
index 0000000..747e566
--- /dev/null
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/U128.java
@@ -0,0 +1,142 @@
+package org.projectfloodlight.openflow.types;
+
+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> {
+
+ static final int LENGTH = 16;
+
+ private final long raw1; // MSBs
+ private final long raw2; // LSBs
+
+ public static final U128 ZERO = new U128(0, 0);
+
+ private U128(long raw1, long raw2) {
+ this.raw1 = raw1;
+ this.raw2 = raw2;
+ }
+
+ public static U128 of(long raw1, long raw2) {
+ if (raw1 == 0 && raw2 == 0)
+ return ZERO;
+ return new U128(raw1, raw2);
+ }
+
+ @Override
+ public int getLength() {
+ return LENGTH;
+ }
+
+
+ public long getMsb() {
+ return raw1;
+ }
+
+ public long getLsb() {
+ return raw2;
+ }
+
+ @Override
+ public U128 applyMask(U128 mask) {
+ return and(mask);
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + (int) (raw1 ^ (raw1 >>> 32));
+ result = prime * result + (int) (raw2 ^ (raw2 >>> 32));
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ U128 other = (U128) obj;
+ if (raw1 != other.raw1)
+ return false;
+ if (raw2 != other.raw2)
+ return false;
+ return true;
+ }
+
+ public void write16Bytes(ChannelBuffer cb) {
+ cb.writeLong(raw1);
+ cb.writeLong(raw2);
+ }
+
+ public static U128 read16Bytes(ChannelBuffer cb) {
+ long raw1 = cb.readLong();
+ long raw2 = cb.readLong();
+ return of(raw1, raw2);
+ }
+
+ @Override
+ public String toString() {
+ return String.format("0x%016x%016x", raw1, raw2);
+ }
+
+ @Override
+ public int compareTo(U128 o) {
+ long c = this.raw1 - o.raw1;
+ if (c != 0)
+ return Long.signum(c);
+ return Long.signum(this.raw2 - o.raw2);
+ }
+
+ @Override
+ public void putTo(PrimitiveSink sink) {
+ sink.putLong(raw1);
+ sink.putLong(raw2);
+ }
+
+ @Override
+ public U128 inverse() {
+ return U128.of(~raw1, ~raw2);
+ }
+
+ @Override
+ public U128 or(U128 other) {
+ return U128.of(raw1 | other.raw1, raw2 | other.raw2);
+ }
+
+ @Override
+ public U128 and(U128 other) {
+ return U128.of(raw1 & other.raw1, raw2 & other.raw2);
+ }
+
+ @Override
+ public U128 xor(U128 other) {
+ return U128.of(raw1 ^ other.raw1, raw2 ^ other.raw2);
+ }
+
+ @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);
+ }
+
+ @Override
+ public U128 combineWithValue(U128 value, int keyBits) {
+ return U128.of(
+ HashValueUtils.combineWithValue(this.raw1, value.raw1, Math.min(64, keyBits)),
+ HashValueUtils.combineWithValue(this.raw2, value.raw2, Math.max(0,keyBits-64))
+ );
+ }
+}
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
new file mode 100644
index 0000000..2313d7c
--- /dev/null
+++ b/java_gen/pre-written/src/test/java/org/projectfloodlight/openflow/types/U128Test.java
@@ -0,0 +1,105 @@
+package org.projectfloodlight.openflow.types;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.not;
+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 org.junit.Test;
+
+import com.google.common.hash.HashCode;
+import com.google.common.hash.Hasher;
+import com.google.common.hash.Hashing;
+
+public class U128Test {
+ @Test
+ public void testPositiveRaws() {
+ assertThat(U128.of(0, 0).getMsb(), equalTo(0L));
+ assertThat(U128.of(0, 0).getLsb(), equalTo(0L));
+
+ assertThat(U128.of(1, 2).getMsb(), equalTo(1L));
+ assertThat(U128.of(1, 2).getLsb(), equalTo(2L));
+ }
+
+ @Test
+ public void testPutTo() {
+ U128 h = U128.of(0x1234_5678_90ab_cdefL,0xdeafbeefdeadbeefL);
+ U128 hSame = U128.of(0x1234_5678_90ab_cdefL,0xdeafbeefdeadbeefL);
+
+ U128 hBothDiff = U128.of(0x1234_5678_90ab_cdefL,0x1234_5678_90ab_cdefL);
+ U128 hMsbDiff = U128.of(0x0234_5678_90ab_cdefL,0xdeafbeefdeadbeefL);
+ U128 hLsbDiff = U128.of(0x1234_5678_90ab_cdefL,0xdeafbeefdeadbeeeL);
+
+ assertThat(hash(h), equalTo(hash(hSame)));
+ assertThat(hash(h), not(hash(hBothDiff)));
+ assertThat(hash(h), not(hash(hMsbDiff)));
+ assertThat(hash(h), not(hash(hLsbDiff)));
+ }
+
+ private HashCode hash(U128 f) {
+ Hasher hash = Hashing.murmur3_128().newHasher();
+ f.putTo(hash);
+ return hash.hash();
+
+ }
+
+ @Test
+ public void testEqualHashCode() {
+ U128 h1 = U128.of(0xdeafbeefdeadbeefL, 0xdeafbeefdeadbeefL);
+ U128 h2 = U128.of(0xdeafbeefdeadbeefL, 0xdeafbeefdeadbeefL);
+ U128 h3 = U128.of(0xeeafbeefdeadbeefL, 0xdeafbeefdeadbeefL);
+ U128 h3_2 = U128.of(0xdeafbeefdeadbeefL, 0xeeafbeefdeadbeefL);
+
+ assertTrue(h1.equals(h1));
+ assertTrue(h1.equals(h2));
+ assertFalse(h1.equals(h3));
+ assertFalse(h1.equals(h3_2));
+ assertTrue(h2.equals(h1));
+
+ assertEquals(h1.hashCode(), h2.hashCode());
+ assertNotEquals(h1.hashCode(), h3.hashCode()); // not technically a requirement, but we'll hopefully be lucky.
+ assertNotEquals(h1.hashCode(), h3_2.hashCode()); // not technically a requirement, but we'll hopefully be lucky.
+ }
+
+ @Test
+ public void testXor() {
+ U128 hNull = U128.of(0, 0);
+ U128 hDeadBeef = U128.of(0xdeafbeefdeadbeefL, 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));
+
+
+ U128 h1_0 = U128.of(1L, 0);
+ U128 h8_0 = U128.of(0x8000000000000000L, 0);
+ U128 h81_0 = U128.of(0x8000000000000001L, 0);
+ assertThat(h1_0.xor(h8_0), equalTo(h81_0));
+
+ U128 h0_1 = U128.of(0, 1L);
+ U128 h0_8 = U128.of(0, 0x8000000000000000L);
+ U128 h0_81 = U128.of(0, 0x8000000000000001L);
+ assertThat(h0_1.xor(h0_8), equalTo(h0_81));
+ }
+
+ @Test
+ public void testCombine() {
+ long key = 0x1234567890abcdefL;
+ long val = 0xdeafbeefdeadbeefL;
+ U128 hkey = U128.of(key, key*2);
+ U128 hVal = U128.of(val, val/2);
+
+ assertThat(hkey.combineWithValue(hVal, 0), equalTo(hkey.xor(hVal)));
+ assertThat(hkey.combineWithValue(hVal, 64), equalTo(U128.of(hkey.getMsb(), hkey.getLsb() ^ hVal.getLsb())));
+ assertThat(hkey.combineWithValue(hVal, 128), equalTo(hkey));
+
+ long mask8 = 0xFF00_0000_0000_0000L;
+
+ assertThat(hkey.combineWithValue(hVal, 8), equalTo(U128.of(hkey.getMsb() & mask8 | hkey.getMsb() ^ hVal.getMsb() & ~mask8,
+ hkey.getLsb() ^ hVal.getLsb() )));
+ }
+
+}
diff --git a/test_data/of13/bsn_gentable_bucket_stats_reply.data b/test_data/of13/bsn_gentable_bucket_stats_reply.data
index 8e0772f..84a36a6 100644
--- a/test_data/of13/bsn_gentable_bucket_stats_reply.data
+++ b/test_data/of13/bsn_gentable_bucket_stats_reply.data
@@ -22,8 +22,8 @@
builder.setXid(0x12345678)
.setEntries(
ImmutableList.<OFBsnGentableBucketStatsEntry>of(
- factory.bsnGentableBucketStatsEntry(OFChecksum128.of(0x8877665544332211L, 0xFFEEDDCCBBAA9988L)),
- factory.bsnGentableBucketStatsEntry(OFChecksum128.of(0x1234234534564567L, 0x56786789789A89ABL))
+ factory.bsnGentableBucketStatsEntry(U128.of(0x8877665544332211L, 0xFFEEDDCCBBAA9988L)),
+ factory.bsnGentableBucketStatsEntry(U128.of(0x1234234534564567L, 0x56786789789A89ABL))
)
)
-- c
diff --git a/test_data/of13/bsn_gentable_clear_request.data b/test_data/of13/bsn_gentable_clear_request.data
index 847af3c..853d463 100644
--- a/test_data/of13/bsn_gentable_clear_request.data
+++ b/test_data/of13/bsn_gentable_clear_request.data
@@ -16,8 +16,8 @@
checksum_mask=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000)
-- java
builder.setXid(0x12345678)
- .setChecksum(OFChecksum128.of(0xFEDCBA9876543210L, 0xFFEECCBBAA990000L))
- .setChecksumMask(OFChecksum128.of(0xFFFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFF0000L))
+ .setChecksum(U128.of(0xFEDCBA9876543210L, 0xFFEECCBBAA990000L))
+ .setChecksumMask(U128.of(0xFFFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFF0000L))
.setTableId(GenTableId.of(20))
-- c
obj = of_bsn_gentable_clear_request_new(OF_VERSION_1_3);
diff --git a/test_data/of13/bsn_gentable_entry_add.data b/test_data/of13/bsn_gentable_entry_add.data
index 02c2bb4..f813dcd 100644
--- a/test_data/of13/bsn_gentable_entry_add.data
+++ b/test_data/of13/bsn_gentable_entry_add.data
@@ -38,7 +38,7 @@
])
-- java
builder.setXid(0x12345678)
- .setChecksum(OFChecksum128.of(0xFEDCBA9876543210L, 0xFFEECCBBAA998877L))
+ .setChecksum(U128.of(0xFEDCBA9876543210L, 0xFFEECCBBAA998877L))
.setTableId(GenTableId.of(20))
.setKey(
ImmutableList.<OFBsnTlv>of(
diff --git a/test_data/of13/bsn_gentable_entry_desc_stats_reply.data b/test_data/of13/bsn_gentable_entry_desc_stats_reply.data
index 4035f4c..21291ed 100644
--- a/test_data/of13/bsn_gentable_entry_desc_stats_reply.data
+++ b/test_data/of13/bsn_gentable_entry_desc_stats_reply.data
@@ -55,7 +55,7 @@
.setEntries(
ImmutableList.<OFBsnGentableEntryDescStatsEntry>of(
factory.buildBsnGentableEntryDescStatsEntry()
- .setChecksum(OFChecksum128.of(0xFEDCBA9876543210L, 0xFFEECCBBAA998800L))
+ .setChecksum(U128.of(0xFEDCBA9876543210L, 0xFFEECCBBAA998800L))
.setKey(ImmutableList.<OFBsnTlv>of(
factory.bsnTlvs().port(OFPort.of(5))
))
@@ -64,7 +64,7 @@
))
.build(),
factory.buildBsnGentableEntryDescStatsEntry()
- .setChecksum(OFChecksum128.of(0xFEDCBA9876543210L, 0xFFEECCBBAA998801L))
+ .setChecksum(U128.of(0xFEDCBA9876543210L, 0xFFEECCBBAA998801L))
.setKey(ImmutableList.<OFBsnTlv>of(
factory.bsnTlvs().port(OFPort.of(6))
))