You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by li...@apache.org on 2014/03/14 19:09:54 UTC
svn commit: r1577642 - in /hbase/branches/0.89-fb/src:
main/java/org/apache/hadoop/hbase/util/Bytes.java
test/java/org/apache/hadoop/hbase/util/TestBytes.java
Author: liyin
Date: Fri Mar 14 18:09:54 2014
New Revision: 1577642
URL: http://svn.apache.org/r1577642
Log:
[private] Optimize head/tail/padHead/appendToTail in Bytes, add testcases
Author: daviddeng
Summary:
Reduce the number of allocation of array when possible
Add testcases
Test Plan: `TestBytes`
Reviewers: liyintang, manukranthk, fan
Reviewed By: manukranthk
CC: hbase-eng@, andrewcox, gauravm
Differential Revision: https://phabricator.fb.com/D1218974
Task ID: 3839997
Modified:
hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/util/Bytes.java
hbase/branches/0.89-fb/src/test/java/org/apache/hadoop/hbase/util/TestBytes.java
Modified: hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/util/Bytes.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/util/Bytes.java?rev=1577642&r1=1577641&r2=1577642&view=diff
==============================================================================
--- hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/util/Bytes.java (original)
+++ hbase/branches/0.89-fb/src/main/java/org/apache/hadoop/hbase/util/Bytes.java Fri Mar 14 18:09:54 2014
@@ -19,8 +19,16 @@
*/
package org.apache.hadoop.hbase.util;
-import com.facebook.nifty.header.protocol.TFacebookCompactProtocol;
-import com.facebook.swift.codec.ThriftCodec;
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.math.BigInteger;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Iterator;
+
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.hbase.HConstants;
@@ -33,15 +41,8 @@ import org.apache.thrift.protocol.TProto
import org.apache.thrift.transport.TMemoryBuffer;
import org.apache.thrift.transport.TMemoryInputTransport;
-import java.io.DataInput;
-import java.io.DataOutput;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.math.BigInteger;
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.Iterator;
+import com.facebook.nifty.header.protocol.TFacebookCompactProtocol;
+import com.facebook.swift.codec.ThriftCodec;
/**
* Utility class that handles byte arrays, conversions to/from other types,
@@ -1109,13 +1110,22 @@ public class Bytes {
}
/**
- * @param a array
- * @param length amount of bytes to grab
+ * Returns the first elements of an array.
+ *
+ * NOTE the method may return <code>a</code> if possible.
+ *
+ * @param a
+ * a non-null array
+ * @param length
+ * amount of bytes to grab
* @return First <code>length</code> bytes from <code>a</code>
*/
- public static byte [] head(final byte [] a, final int length) {
- if (a.length < length) {
- return null;
+ public static byte[] head(final byte[] a, final int length) {
+ if (length > a.length) {
+ throw new ArrayIndexOutOfBoundsException(length - 1);
+ }
+ if (length == a.length) {
+ return a;
}
byte [] result = new byte[length];
System.arraycopy(a, 0, result, 0, length);
@@ -1123,13 +1133,22 @@ public class Bytes {
}
/**
- * @param a array
- * @param length amount of bytes to snarf
+ * Returns the last elements of an array.
+ *
+ * NOTE the method may return <code>a</code> if possible.
+ *
+ * @param a
+ * a non-null array
+ * @param length
+ * amount of bytes to snarf
* @return Last <code>length</code> bytes from <code>a</code>
*/
- public static byte [] tail(final byte [] a, final int length) {
- if (a.length < length) {
- return null;
+ public static byte[] tail(final byte[] a, final int length) {
+ if (length > a.length) {
+ throw new ArrayIndexOutOfBoundsException(a.length - length);
+ }
+ if (length == a.length) {
+ return a;
}
byte [] result = new byte[length];
System.arraycopy(a, a.length - length, result, 0, length);
@@ -1137,21 +1156,35 @@ public class Bytes {
}
/**
- * @param a array
- * @param length new array size
- * @return Value in <code>a</code> plus <code>length</code> prepended 0 bytes
- */
- public static byte [] padHead(final byte [] a, final int length) {
- byte [] padding = new byte[length];
- for (int i = 0; i < length; i++) {
- padding[i] = 0;
+ * Pads zeros in front of an array.
+ *
+ * NOTE the method may return <code>a</code> if possible.
+ *
+ * @param a
+ * a non-null array
+ * @param length
+ * the number of zeros to be padded in
+ * @return Value in <code>a</code> plus <code>length</code> prepended 0 bytes.
+ * could be the same instance of <code>a</code> if lenght == 0.
+ */
+ public static byte[] padHead(final byte[] a, final int length) {
+ if (length == 0) {
+ return a;
}
- return add(padding,a);
+ byte[] res = new byte[a.length + length];
+ System.arraycopy(a, 0, res, length, a.length);
+ return res;
}
/**
- * @param a array
- * @param length new array size
+ * Appends zeros at the end of <code>a</code>.
+ *
+ * NOTE the method may return <code>a</code> if possible.
+ *
+ * @param a
+ * array
+ * @param length
+ * new array size
* @return Value in <code>a</code> plus <code>length</code> appended 0 bytes
*/
public static byte [] padTail(final byte [] a, final int length) {
@@ -1161,18 +1194,31 @@ public class Bytes {
/**
* Appends length bytes to the end of the array and returns the new array
* Fills byte b in the newly allocated space in the byte[].
- * @param a array
- * @param length new array size
- * @param b byte to write to the tail.
+ *
+ * NOTE the method may return <code>a</code> if possible.
+ *
+ * @param a
+ * array
+ * @param length
+ * new array size
+ * @param b
+ * byte to write to the tail.
* @return Value in <code>a</code> plus <code>length</code> appended 0 bytes
*/
- public static byte [] appendToTail(final byte [] a, final int length, byte b)
- {
- byte [] padding = new byte[length];
- for (int i = 0; i < length; i++) {
- padding[i] = b;
+ public static byte[] appendToTail(final byte[] a, int length, byte b) {
+ if (length == 0) {
+ return a;
+ }
+ int total = a.length + length;
+ byte[] res = new byte[total];
+ System.arraycopy(a, 0, res, 0, a.length);
+
+ if (b != 0) {
+ for (int i = a.length; i < total; i++) {
+ res[i] = b;
+ }
}
- return add(a,padding);
+ return res;
}
/**
Modified: hbase/branches/0.89-fb/src/test/java/org/apache/hadoop/hbase/util/TestBytes.java
URL: http://svn.apache.org/viewvc/hbase/branches/0.89-fb/src/test/java/org/apache/hadoop/hbase/util/TestBytes.java?rev=1577642&r1=1577641&r2=1577642&view=diff
==============================================================================
--- hbase/branches/0.89-fb/src/test/java/org/apache/hadoop/hbase/util/TestBytes.java (original)
+++ hbase/branches/0.89-fb/src/test/java/org/apache/hadoop/hbase/util/TestBytes.java Fri Mar 14 18:09:54 2014
@@ -28,6 +28,8 @@ import java.util.Arrays;
import junit.framework.TestCase;
+import org.junit.Assert;
+
public class TestBytes extends TestCase {
public void testNullHashCode() {
byte [] b = null;
@@ -170,7 +172,7 @@ public class TestBytes extends TestCase
Bytes.BYTES_RAWCOMPARATOR));
}
}
-
+
public void testStartsWith() {
assertTrue(Bytes.startsWith(Bytes.toBytes("hello"), Bytes.toBytes("h")));
assertTrue(Bytes.startsWith(Bytes.toBytes("hello"), Bytes.toBytes("")));
@@ -214,7 +216,7 @@ public class TestBytes extends TestCase
return (Bytes.toLong(testValue) + amount) == incrementResult;
}
-
+
public void testFixedSizeString() throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
@@ -240,4 +242,51 @@ public class TestBytes extends TestCase
assertEquals("", Bytes.readStringFixedSize(dis, 9));
}
+ public void testHead() throws Exception {
+ byte[] a = new byte[] { 1, 2, 3, 4 };
+ Assert.assertArrayEquals("head(a, 0)", Bytes.head(a, 0), new byte[] {});
+ Assert.assertArrayEquals("head(a, 2)", Bytes.head(a, 2),
+ new byte[] { 1, 2 });
+ Assert.assertArrayEquals("head(a, 4)", Bytes.head(a, 4), new byte[] { 1, 2,
+ 3, 4 });
+ try {
+ Bytes.head(a, 5);
+ fail("Should throw exception for head(a, 5)");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Correct
+ }
+ }
+
+ public void testTail() throws Exception {
+ byte[] a = new byte[] { 1, 2, 3, 4 };
+ Assert.assertArrayEquals("tail(a, 0)", Bytes.tail(a, 0), new byte[] {});
+ Assert.assertArrayEquals("tail(a, 2)", Bytes.tail(a, 2),
+ new byte[] { 3, 4 });
+ Assert.assertArrayEquals("tail(a, 4)", Bytes.tail(a, 4), new byte[] { 1, 2,
+ 3, 4 });
+ try {
+ Bytes.tail(a, 5);
+ fail("Should throw exception for tail(a, 5)");
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // Correct
+ }
+ }
+
+ public void testPadHead() throws Exception {
+ byte[] a = new byte[] { 1, 2 };
+ Assert.assertArrayEquals("padHead(a, 0)", Bytes.padHead(a, 0), new byte[] {
+ 1, 2 });
+ Assert.assertArrayEquals("padHead(a, 2)", Bytes.padHead(a, 2), new byte[] {
+ 0, 0, 1, 2 });
+ }
+
+ public void testAppendToTail() throws Exception {
+ byte[] a = new byte[] { 1, 2 };
+ Assert.assertArrayEquals("appendToTail(a, 0, 0)",
+ Bytes.appendToTail(a, 0, (byte) 0), new byte[] { 1, 2 });
+ Assert.assertArrayEquals("appendToTail(a, 2, 0)",
+ Bytes.appendToTail(a, 2, (byte) 0), new byte[] { 1, 2, 0, 0 });
+ Assert.assertArrayEquals("appendToTail(a, 0, 6)",
+ Bytes.appendToTail(a, 2, (byte) 6), new byte[] { 1, 2, 6, 6 });
+ }
}