From b866ff64d9bf88cae6bb0eb388107e57405ebf90 Mon Sep 17 00:00:00 2001 From: Aaron Myers Date: Mon, 27 Jun 2011 03:39:04 +0000 Subject: [PATCH] HADOOP-310. Additional constructor requested in BytesWritable. (Brock Noland via atm) git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1140010 13f79535-47bb-0310-9956-ffa450edef68 --- common/CHANGES.txt | 3 ++ .../org/apache/hadoop/io/BytesWritable.java | 13 +++++- .../apache/hadoop/io/TestBytesWritable.java | 44 ++++++++++++++++++- 3 files changed, 57 insertions(+), 3 deletions(-) diff --git a/common/CHANGES.txt b/common/CHANGES.txt index 5873f58794..eee47e0549 100644 --- a/common/CHANGES.txt +++ b/common/CHANGES.txt @@ -234,6 +234,9 @@ Trunk (unreleased changes) HADOOP-7385. Remove StringUtils.stringifyException(ie) in logger functions. (Bharath Mundlapudi via Tanping Wang). + HADOOP-310. Additional constructor requested in BytesWritable. (Brock + Noland via atm) + OPTIMIZATIONS HADOOP-7333. Performance improvement in PureJavaCrc32. (Eric Caspole diff --git a/common/src/java/org/apache/hadoop/io/BytesWritable.java b/common/src/java/org/apache/hadoop/io/BytesWritable.java index 318d0cfa52..c4edad8953 100644 --- a/common/src/java/org/apache/hadoop/io/BytesWritable.java +++ b/common/src/java/org/apache/hadoop/io/BytesWritable.java @@ -51,8 +51,19 @@ public class BytesWritable extends BinaryComparable * @param bytes This array becomes the backing storage for the object. */ public BytesWritable(byte[] bytes) { + this(bytes, bytes.length); + } + + /** + * Create a BytesWritable using the byte array as the initial value + * and length as the length. Use this constructor if the array is larger + * than the value it represents. + * @param bytes This array becomes the backing storage for the object. + * @param length The number of bytes to use from array. + */ + public BytesWritable(byte[] bytes, int length) { this.bytes = bytes; - this.size = bytes.length; + this.size = length; } /** diff --git a/common/src/test/core/org/apache/hadoop/io/TestBytesWritable.java b/common/src/test/core/org/apache/hadoop/io/TestBytesWritable.java index da4d760e83..014b8682d8 100644 --- a/common/src/test/core/org/apache/hadoop/io/TestBytesWritable.java +++ b/common/src/test/core/org/apache/hadoop/io/TestBytesWritable.java @@ -17,13 +17,17 @@ */ package org.apache.hadoop.io; -import junit.framework.TestCase; +import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + /** * This is the unit test for BytesWritable. */ -public class TestBytesWritable extends TestCase { +public class TestBytesWritable { + @Test public void testSizeChange() throws Exception { byte[] hadoop = "hadoop".getBytes(); BytesWritable buf = new BytesWritable(hadoop); @@ -50,6 +54,7 @@ public void testSizeChange() throws Exception { assertEquals(hadoop[0], buf.getBytes()[0]); } + @Test public void testHash() throws Exception { byte[] owen = "owen".getBytes(); BytesWritable buf = new BytesWritable(owen); @@ -60,6 +65,7 @@ public void testHash() throws Exception { assertEquals(1, buf.hashCode()); } + @Test public void testCompare() throws Exception { byte[][] values = new byte[][]{"abc".getBytes(), "ad".getBytes(), @@ -88,10 +94,44 @@ private void checkToString(byte[] input, String expected) { assertEquals(expected, actual); } + @Test public void testToString() { checkToString(new byte[]{0,1,2,0x10}, "00 01 02 10"); checkToString(new byte[]{-0x80, -0x7f, -0x1, -0x2, 1, 0}, "80 81 ff fe 01 00"); } + /** + * This test was written as result of adding the new zero + * copy constructor and set method to BytesWritable. These + * methods allow users to specify the backing buffer of the + * BytesWritable instance and a length. + */ + @Test + public void testZeroCopy() { + byte[] bytes = "brock".getBytes(); + BytesWritable zeroBuf = new BytesWritable(bytes, bytes.length); // new + BytesWritable copyBuf = new BytesWritable(bytes); // old + // using zero copy constructor shouldn't result in a copy + assertTrue("copy took place, backing array != array passed to constructor", + bytes == zeroBuf.getBytes()); + assertTrue("length of BW should backing byte array", zeroBuf.getLength() == bytes.length); + assertEquals("objects with same backing array should be equal", zeroBuf, copyBuf); + assertEquals("string repr of objects with same backing array should be equal", + zeroBuf.toString(), copyBuf.toString()); + assertTrue("compare order objects with same backing array should be equal", + zeroBuf.compareTo(copyBuf) == 0); + assertTrue("hash of objects with same backing array should be equal", + zeroBuf.hashCode() == copyBuf.hashCode()); + + // ensure expanding buffer is handled correctly + // for buffers created with zero copy api + byte[] buffer = new byte[bytes.length * 5]; + zeroBuf.set(buffer, 0, buffer.length); // expand internal buffer + zeroBuf.set(bytes, 0, bytes.length); // set back to normal contents + assertEquals("buffer created with (array, len) has bad contents", + zeroBuf, copyBuf); + assertTrue("buffer created with (array, len) has bad length", + zeroBuf.getLength() == copyBuf.getLength()); + } }