commit 2fcbaaf8dfea9182808c0978b7dad63646a14a08 Author: Todd Lipcon Date: Mon May 31 23:16:32 2010 -0700 HBASE-2635. Fix several bugs in ImmutableBytesWritable to take offset into account diff --git src/main/java/org/apache/hadoop/hbase/io/ImmutableBytesWritable.java src/main/java/org/apache/hadoop/hbase/io/ImmutableBytesWritable.java index 0a9ec4b..c48390a 100644 --- src/main/java/org/apache/hadoop/hbase/io/ImmutableBytesWritable.java +++ src/main/java/org/apache/hadoop/hbase/io/ImmutableBytesWritable.java @@ -83,7 +83,7 @@ implements WritableComparable { /** * Get the data from the BytesWritable. - * @return The data is only valid between 0 and getSize() - 1. + * @return The data is only valid between offset and offset+length. */ public byte [] get() { if (this.bytes == null) { @@ -112,7 +112,7 @@ implements WritableComparable { } /** - * @return the current size of the buffer. + * @return the number of valid bytes in the buffer */ public int getSize() { if (this.bytes == null) { @@ -123,7 +123,7 @@ implements WritableComparable { } /** - * @return the current length of the buffer. same as getSize() + * @return the number of valid bytes in the buffer */ //Should probably deprecate getSize() so that we keep the same calls for all //byte [] @@ -155,20 +155,24 @@ implements WritableComparable { } // Below methods copied from BytesWritable - @Override public int hashCode() { - return WritableComparator.hashBytes(bytes, this.length); + int hash = 1; + for (int i = offset; i < offset + length; i++) + hash = (31 * hash) + (int)bytes[i]; + return hash; } /** * Define the sort order of the BytesWritable. - * @param right_obj The other bytes writable + * @param that The other bytes writable * @return Positive if left is bigger than right, 0 if they are equal, and * negative if left is smaller than right. */ - public int compareTo(ImmutableBytesWritable right_obj) { - return compareTo(right_obj.get()); + public int compareTo(ImmutableBytesWritable that) { + return WritableComparator.compareBytes( + this.bytes, this.offset, this.length, + that.bytes, that.offset, that.length); } /** @@ -178,8 +182,9 @@ implements WritableComparable { * negative if left is smaller than right. */ public int compareTo(final byte [] that) { - return WritableComparator.compareBytes(this.bytes, 0, this.length, that, - 0, that.length); + return WritableComparator.compareBytes( + this.bytes, this.offset, this.length, + that, 0, that.length); } /** @@ -202,9 +207,9 @@ implements WritableComparable { @Override public String toString() { StringBuilder sb = new StringBuilder(3*this.bytes.length); - for (int idx = 0; idx < this.bytes.length; idx++) { + for (int idx = offset; idx < offset + length; idx++) { // if not the first, put a blank separator in - if (idx != 0) { + if (idx != offset) { sb.append(' '); } String num = Integer.toHexString(bytes[idx]); diff --git src/test/java/org/apache/hadoop/hbase/io/TestImmutableBytesWritable.java src/test/java/org/apache/hadoop/hbase/io/TestImmutableBytesWritable.java index 1e8886b..43fa6dd 100644 --- src/test/java/org/apache/hadoop/hbase/io/TestImmutableBytesWritable.java +++ src/test/java/org/apache/hadoop/hbase/io/TestImmutableBytesWritable.java @@ -28,6 +28,18 @@ import java.io.DataOutputStream; import java.io.IOException; public class TestImmutableBytesWritable extends TestCase { + public void testHash() throws Exception { + assertEquals( + new ImmutableBytesWritable(Bytes.toBytes("xxabc"), 2, 3).hashCode(), + new ImmutableBytesWritable(Bytes.toBytes("abc")).hashCode()); + assertEquals( + new ImmutableBytesWritable(Bytes.toBytes("xxabcd"), 2, 3).hashCode(), + new ImmutableBytesWritable(Bytes.toBytes("abc")).hashCode()); + assertNotSame( + new ImmutableBytesWritable(Bytes.toBytes("xxabc"), 2, 3).hashCode(), + new ImmutableBytesWritable(Bytes.toBytes("xxabc"), 2, 2).hashCode()); + } + public void testComparison() throws Exception { runTests("aa", "b", -1); runTests("aa", "aa", 0); @@ -46,6 +58,22 @@ public class TestImmutableBytesWritable extends TestCase { doComparisonsOnObjects(a, b, signum); doComparisonsOnRaw(a, b, signum); + + // Tests for when the offset is non-zero + a = new ImmutableBytesWritable(Bytes.toBytes("xxx" + aStr), + 3, aStr.length()); + b = new ImmutableBytesWritable(Bytes.toBytes("yy" + bStr), + 2, bStr.length()); + doComparisonsOnObjects(a, b, signum); + doComparisonsOnRaw(a, b, signum); + + // Tests for when offset is nonzero and length doesn't extend to end + a = new ImmutableBytesWritable(Bytes.toBytes("xxx" + aStr + "zzz"), + 3, aStr.length()); + b = new ImmutableBytesWritable(Bytes.toBytes("yy" + bStr + "aaa"), + 2, bStr.length()); + doComparisonsOnObjects(a, b, signum); + doComparisonsOnRaw(a, b, signum); } @@ -93,4 +121,4 @@ public class TestImmutableBytesWritable extends TestCase { "Comparing " + a + " and " + b + " as objects (inverse)", -signum(comparator.compare(b, a)), expectedSignum); } -} \ No newline at end of file +}