java/HashValue: add+subtract, remove combineWithValue
Added arithmetic add and subtract operations to HashValue types. Also
removed the obsolete combineWithValue operation that had weird/broken
semantics.
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/HashValue.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/HashValue.java
index 1dd55d5..a656dab 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/HashValue.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/HashValue.java
@@ -17,6 +17,23 @@
*/
int prefixBits(int numBits);
+ /** perform an arithmetic addition of this value and other. Wraps around on
+ * overflow of the defined word size.
+ *
+ * @param other
+ * @return this + other
+ */
+ H add(H other);
+
+ /**
+ * arithmetically substract the given 'other' value from this value.
+ * around on overflow.
+ *
+ * @param other
+ * @return this - other
+ */
+ H subtract(H other);
+
/** @return the bitwise inverse of this value */
H inverse();
@@ -28,27 +45,4 @@
/** xor this value with another value value of the same type */
H xor(H other);
-
- /** calculate a combined hash value of this hash value (the <b>Key</b>) and the hash value
- * specified as a parameter (the <b>Value</b>).
- * <p>
- * The value is constructed as follows:
- * <ul>
- * <li>the first keyBits bits are taken only from the Key
- * <li>the other bits are taken from key xor value.
- * </ul>
- * The overall result looks like this:
- * <pre>
- * MSB LSB
- * +---------+--------------+
- * | key | key ^ value |
- * +---------+--------------+
- * |-keyBits-|
- * </pre>
- *
- * @param value - hash value to be compared with this value (the key)
- * @param keyBits number of prefix bits that are just taken from key
- * @return the combined value.
- */
- H combineWithValue(H value, int keyBits);
}
\ No newline at end of file
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 35ef846..ba7d88a 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
@@ -123,15 +123,29 @@
}
@Override
+ public U128 add(U128 other) {
+ long newRaw2 = this.raw2 + other.raw2;
+ long newRaw1 = this.raw1 + other.raw1;
+ if (UnsignedLongs.compare(newRaw2, this.raw2) < 0 ||
+ UnsignedLongs.compare(newRaw2, other.raw2) < 0) {
+ // raw2 overflow
+ newRaw1+=1;
+ }
+ return U128.of(newRaw1, newRaw2);
+ }
+
+ @Override
+ public U128 subtract(U128 other) {
+ long newRaw2 = this.raw2 - other.raw2;
+ long newRaw1 = this.raw1 - other.raw1;
+ if (UnsignedLongs.compare(this.raw2, other.raw2) < 0) {
+ newRaw1 -= 1;
+ }
+ return U128.of(newRaw1, newRaw2);
+ }
+ @Override
public int prefixBits(int numBits) {
return HashValueUtils.prefixBits(this.raw1, numBits);
}
- @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/main/java/org/projectfloodlight/openflow/types/U64.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/U64.java
index 1353b42..dcd812d 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
@@ -151,6 +151,16 @@
return U64.of(raw ^ other.raw);
}
+ @Override
+ public U64 add(U64 other) {
+ return U64.of(this.raw + other.raw);
+ }
+
+ @Override
+ public U64 subtract(U64 other) {
+ return U64.of(this.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.
@@ -160,11 +170,6 @@
return HashValueUtils.prefixBits(raw, numBits);
}
- @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> {
@@ -174,5 +179,4 @@
}
}
-
}
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 18f524e..5393db9 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
@@ -9,6 +9,8 @@
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import java.text.MessageFormat;
+
import org.hamcrest.Matchers;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
@@ -141,6 +143,66 @@
}
}
+ public static class Triple {
+ U128 a, b, c;
+
+ public Triple(U128 a, U128 b, U128 c) {
+ this.a = a;
+ this.b = b;
+ this.c = c;
+ }
+
+ public static Triple of(U128 a, U128 b, U128 c) {
+ return new Triple(a, b, c);
+ }
+
+ public String msg(String string) {
+ return MessageFormat.format(string, a,b,c);
+ }
+ }
+
+ @Test
+ public void testAddSubtract() {
+ U128 u0_0 = U128.of(0, 0);
+ U128 u0_1 = U128.of(0, 1);
+ U128 u1_0 = U128.of(1, 0);
+ U128 u1_1 = U128.of(1, 1);
+
+ U128 u0_2 = U128.of(0, 2);
+ U128 u2_0 = U128.of(2, 0);
+
+ U128 u0_f = U128.of(0, -1L);
+ U128 uf_0 = U128.of(-1L, 0);
+
+ Triple[] triples = new Triple[] {
+ Triple.of(u0_0, u0_0, u0_0),
+ Triple.of(u0_0, u0_1, u0_1),
+ Triple.of(u0_0, u1_0, u1_0),
+ Triple.of(u0_1, u1_0, u1_1),
+
+ Triple.of(u0_1, u0_1, u0_2),
+ Triple.of(u1_0, u1_0, u2_0),
+
+ Triple.of(u0_1, u0_f, u1_0),
+
+ Triple.of(u0_1, u0_f, u1_0),
+ Triple.of(u0_f, u0_f, U128.of(1, 0xffff_ffff_ffff_fffeL)),
+ Triple.of(uf_0, u0_f, U128.of(-1, -1)),
+ Triple.of(uf_0, u1_0, U128.ZERO),
+
+ Triple.of(U128.of(0x1234_5678_9abc_def1L, 0x1234_5678_9abc_def1L),
+ U128.of(0xedcb_a987_6543_210eL, 0xedcb_a987_6543_210fL),
+ U128.ZERO)
+ };
+
+ for(Triple t: triples) {
+ assertThat(t.msg("{0} + {1} = {2}"), t.a.add(t.b), equalTo(t.c));
+ assertThat(t.msg("{1} + {0} = {2}"), t.b.add(t.a), equalTo(t.c));
+
+ assertThat(t.msg("{2} - {0} = {1}"), t.c.subtract(t.a), equalTo(t.b));
+ assertThat(t.msg("{2} - {1} = {0}"), t.c.subtract(t.b), equalTo(t.a));
+ }
+ }
@Test
public void testCompare() {
@@ -180,21 +242,4 @@
}
}
- @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/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 b0cca23..7bd1c46 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
@@ -9,6 +9,7 @@
import static org.junit.Assert.fail;
import java.math.BigInteger;
+import java.text.MessageFormat;
import org.junit.Test;
@@ -24,10 +25,10 @@
@Test
public void testNegativeRaws() {
- long minus_1 = 0xFFFF_FFFF_FFFF_FFFFL;
- assertEquals(minus_1, U64.ofRaw(minus_1).getValue());
- assertEquals(new BigInteger("FFFF_FFFF_FFFF_FFFF".replace("_", ""), 16), U64.ofRaw(minus_1).getBigInteger());
- assertEquals(new BigInteger("18446744073709551615"), U64.ofRaw(minus_1).getBigInteger());
+ long minu1 = 0xFFFF_FFFF_FFFF_FFFFL;
+ assertEquals(minu1, U64.ofRaw(minu1).getValue());
+ assertEquals(new BigInteger("FFFF_FFFF_FFFF_FFFF".replace("_", ""), 16), U64.ofRaw(minu1).getBigInteger());
+ assertEquals(new BigInteger("18446744073709551615"), U64.ofRaw(minu1).getBigInteger());
}
@Test
@@ -62,24 +63,6 @@
}
@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)));
- }
-
- @Test
public void testKeyBits() {
U64 zeroU = U64.of(0);
assertThat(zeroU.prefixBits(0), equalTo(0));
@@ -105,6 +88,62 @@
checkInvalidKeyBitSize(signedBitU, 64);
}
+ public static class Triple {
+ U64 a, b, c;
+
+ public Triple(U64 a, U64 b, U64 c) {
+ this.a = a;
+ this.b = b;
+ this.c = c;
+ }
+
+ public static Triple of(U64 a, U64 b, U64 c) {
+ return new Triple(a, b, c);
+ }
+
+ public String msg(String string) {
+ return MessageFormat.format(string, a,b,c);
+ }
+ }
+
+ @Test
+ public void testAddSubtract() {
+ U64 u0 = U64.of(0);
+ U64 u1 = U64.of(1);
+
+ U64 u2 = U64.of(2);
+ U64 u7f = U64.of(0x7fff_ffff_ffff_ffffL);
+ U64 u8 = U64.of(0x8000_0000_0000_0000L);
+
+ U64 uf = U64.of(-1L);
+
+ Triple[] triples = new Triple[] {
+ Triple.of(u0, u0, u0),
+ Triple.of(u0, u1, u1),
+
+ Triple.of(u1, u1, u2),
+
+ Triple.of(u1, uf, u0),
+
+ Triple.of(uf, uf, U64.of(0xffff_ffff_ffff_fffeL)),
+ Triple.of(u0, uf, uf),
+
+ Triple.of(u7f, u1, u8),
+
+ Triple.of(U64.of(0x1234_5678_9abc_def1L),
+ U64.of(0xedcb_a987_6543_210fL),
+ U64.ZERO)
+ };
+
+ for(Triple t: triples) {
+ assertThat(t.msg("{0} + {1} = {2}"), t.a.add(t.b), equalTo(t.c));
+ assertThat(t.msg("{1} + {0} = {2}"), t.b.add(t.a), equalTo(t.c));
+
+ assertThat(t.msg("{2} - {0} = {1}"), t.c.subtract(t.a), equalTo(t.b));
+ assertThat(t.msg("{2} - {1} = {0}"), t.c.subtract(t.b), equalTo(t.a));
+ }
+ }
+
private void
checkInvalidKeyBitSize(U64 u, int prefixBit) {
try {