You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by st...@apache.org on 2009/05/03 01:36:41 UTC
svn commit: r770991 - in /hadoop/hbase/trunk: ./
src/java/org/apache/hadoop/hbase/regionserver/
src/java/org/apache/hadoop/hbase/util/
src/test/org/apache/hadoop/hbase/regionserver/
src/test/org/apache/hadoop/hbase/util/
Author: stack
Date: Sat May 2 22:39:32 2009
New Revision: 770991
URL: http://svn.apache.org/viewvc?rev=770991&view=rev
Log:
HBASE-1347 HTable.incrementColumnValue does not take negative 'amount'
Modified:
hadoop/hbase/trunk/CHANGES.txt
hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/HRegion.java
hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/util/Bytes.java
hadoop/hbase/trunk/src/test/org/apache/hadoop/hbase/regionserver/TestAtomicIncrement.java
hadoop/hbase/trunk/src/test/org/apache/hadoop/hbase/util/TestBytes.java
Modified: hadoop/hbase/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/hadoop/hbase/trunk/CHANGES.txt?rev=770991&r1=770990&r2=770991&view=diff
==============================================================================
--- hadoop/hbase/trunk/CHANGES.txt (original)
+++ hadoop/hbase/trunk/CHANGES.txt Sat May 2 22:39:32 2009
@@ -99,6 +99,8 @@
(Evgeny Ryabitskiy via Stack)
HBASE-1322 hbase-1234 broke TestAtomicIncrement; fix and reenable
(Evgeny Ryabitskiy and Ryan Rawson via Stack)
+ HBASE-1347 HTable.incrementColumnValue does not take negative 'amount'
+ (Evgeny Ryabitskiy via Stack)
IMPROVEMENTS
HBASE-1089 Add count of regions on filesystem to master UI; add percentage
Modified: hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/HRegion.java
URL: http://svn.apache.org/viewvc/hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/HRegion.java?rev=770991&r1=770990&r2=770991&view=diff
==============================================================================
--- hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/HRegion.java (original)
+++ hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/regionserver/HRegion.java Sat May 2 22:39:32 2009
@@ -2701,7 +2701,8 @@
"/"+ Bytes.toString(column));
value = Bytes.toBytes(amount);
} else {
- value = incrementBytes(value, amount);
+ if (amount == 0) return Bytes.toLong(value);
+ value = Bytes.incrementBytes(value, amount);
}
BatchUpdate b = new BatchUpdate(row, ts);
@@ -2713,34 +2714,4 @@
releaseRowLock(lid);
}
}
-
- private byte [] incrementBytes(byte[] value, long amount) throws IOException {
- // Hopefully this doesn't happen too often.
- if (value.length < Bytes.SIZEOF_LONG) {
- byte [] newvalue = new byte[Bytes.SIZEOF_LONG];
- System.arraycopy(value, 0, newvalue, newvalue.length - value.length,
- value.length);
- value = newvalue;
- } else if (value.length > Bytes.SIZEOF_LONG) {
- throw new DoNotRetryIOException("Increment Bytes - value too big: " +
- value.length);
- }
- return binaryIncrement(value, amount);
- }
-
- private byte [] binaryIncrement(byte [] value, long amount) {
- for(int i=0;i<value.length;i++) {
- int cur = (int)(amount >> (8 * i)) % 256;
- int val = value[value.length-i-1] & 0xff;
- int total = cur + val;
- if(total > 255) {
- amount += ((long)256 << (8 * i));
- total %= 256;
- }
- value[value.length-i-1] = (byte)total;
- amount = (amount >> (8 * (i + 1))) << (8 * (i + 1));
- if(amount == 0) return value;
- }
- return value;
- }
-}
\ No newline at end of file
+}
Modified: hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/util/Bytes.java
URL: http://svn.apache.org/viewvc/hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/util/Bytes.java?rev=770991&r1=770990&r2=770991&view=diff
==============================================================================
--- hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/util/Bytes.java (original)
+++ hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/util/Bytes.java Sat May 2 22:39:32 2009
@@ -27,6 +27,7 @@
import java.util.Comparator;
import java.math.BigInteger;
+import org.apache.hadoop.hbase.DoNotRetryIOException;
import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
import org.apache.hadoop.io.RawComparator;
@@ -909,5 +910,90 @@
return mid;
}
return - (low+1);
- }
-}
\ No newline at end of file
+ }
+
+ /**
+ * Bytewise binary increment/deincrement of long contained in byte array
+ * on given amount.
+ *
+ * @param value - array of bytes containing long (length <= SIZEOF_LONG)
+ * @param amount value will be incremented on (deincremented if negative)
+ * @return array of bytes containing incremented long (length == SIZEOF_LONG)
+ * @throws IOException - if value.length > SIZEOF_LONG
+ */
+ public static byte [] incrementBytes(byte[] value, long amount)
+ throws IOException {
+ byte[] val = value;
+ if (val.length < SIZEOF_LONG) {
+ // Hopefully this doesn't happen too often.
+ byte [] newvalue;
+ if (val[0] < 0) {
+ byte [] negativeValue = {-1, -1, -1, -1, -1, -1, -1, -1};
+ newvalue = negativeValue;
+ } else {
+ newvalue = new byte[SIZEOF_LONG];
+ }
+ System.arraycopy(val, 0, newvalue, newvalue.length - val.length,
+ val.length);
+ val = newvalue;
+ } else if (val.length > SIZEOF_LONG) {
+ throw new DoNotRetryIOException("Increment Bytes - value too big: " +
+ val.length);
+ }
+ if(amount == 0) return val;
+ if(val[0] < 0){
+ return binaryIncrementNeg(val, amount);
+ }
+ return binaryIncrementPos(val, amount);
+ }
+
+ /* increment/deincrement for positive value */
+ private static byte [] binaryIncrementPos(byte [] value, long amount) {
+ long amo = amount;
+ int sign = 1;
+ if (amount < 0) {
+ amo = -amount;
+ sign = -1;
+ }
+ for(int i=0;i<value.length;i++) {
+ int cur = ((int)amo % 256) * sign;
+ amo = (amo >> 8);
+ int val = value[value.length-i-1] & 0x0ff;
+ int total = val + cur;
+ if(total > 255) {
+ amo += sign;
+ total %= 256;
+ } else if (total < 0) {
+ amo -= sign;
+ }
+ value[value.length-i-1] = (byte)total;
+ if (amo == 0) return value;
+ }
+ return value;
+ }
+
+ /* increment/deincrement for negative value */
+ private static byte [] binaryIncrementNeg(byte [] value, long amount) {
+ long amo = amount;
+ int sign = 1;
+ if (amount < 0) {
+ amo = -amount;
+ sign = -1;
+ }
+ for(int i=0;i<value.length;i++) {
+ int cur = ((int)amo % 256) * sign;
+ amo = (amo >> 8);
+ int val = ((~value[value.length-i-1]) & 0x0ff) + 1;
+ int total = cur - val;
+ if(total >= 0) {
+ amo += sign;
+ } else if (total < -256) {
+ amo -= sign;
+ total %= 256;
+ }
+ value[value.length-i-1] = (byte)total;
+ if (amo == 0) return value;
+ }
+ return value;
+ }
+}
Modified: hadoop/hbase/trunk/src/test/org/apache/hadoop/hbase/regionserver/TestAtomicIncrement.java
URL: http://svn.apache.org/viewvc/hadoop/hbase/trunk/src/test/org/apache/hadoop/hbase/regionserver/TestAtomicIncrement.java?rev=770991&r1=770990&r2=770991&view=diff
==============================================================================
--- hadoop/hbase/trunk/src/test/org/apache/hadoop/hbase/regionserver/TestAtomicIncrement.java (original)
+++ hadoop/hbase/trunk/src/test/org/apache/hadoop/hbase/regionserver/TestAtomicIncrement.java Sat May 2 22:39:32 2009
@@ -88,6 +88,9 @@
assertEquals(3L, table.incrementColumnValue(row, column, 1));
assertEquals(-2L, table.incrementColumnValue(row, column, -5));
+ assertEquals(-502L, table.incrementColumnValue(row, column, -500));
+ assertEquals(1500L, table.incrementColumnValue(row, column, 2002));
+ assertEquals(1501L, table.incrementColumnValue(row, column, 1));
row = Bytes.toBytes("foo3");
byte[] value2 = {1,2,3,4,5,6,7,8,9};
Modified: hadoop/hbase/trunk/src/test/org/apache/hadoop/hbase/util/TestBytes.java
URL: http://svn.apache.org/viewvc/hadoop/hbase/trunk/src/test/org/apache/hadoop/hbase/util/TestBytes.java?rev=770991&r1=770990&r2=770991&view=diff
==============================================================================
--- hadoop/hbase/trunk/src/test/org/apache/hadoop/hbase/util/TestBytes.java (original)
+++ hadoop/hbase/trunk/src/test/org/apache/hadoop/hbase/util/TestBytes.java Sat May 2 22:39:32 2009
@@ -19,6 +19,7 @@
*/
package org.apache.hadoop.hbase.util;
+import java.io.IOException;
import java.util.Arrays;
import junit.framework.TestCase;
@@ -113,4 +114,40 @@
assertEquals(5, Bytes.binarySearch(arr, key3, 1, 1,
Bytes.BYTES_RAWCOMPARATOR));
}
-}
\ No newline at end of file
+
+ public void testIncrementBytes() throws IOException {
+
+ assertTrue(checkTestIncrementBytes(10, 1));
+ assertTrue(checkTestIncrementBytes(12, 123435445));
+ assertTrue(checkTestIncrementBytes(124634654, 1));
+ assertTrue(checkTestIncrementBytes(10005460, 5005645));
+ assertTrue(checkTestIncrementBytes(1, -1));
+ assertTrue(checkTestIncrementBytes(10, -1));
+ assertTrue(checkTestIncrementBytes(10, -5));
+ assertTrue(checkTestIncrementBytes(1005435000, -5));
+ assertTrue(checkTestIncrementBytes(10, -43657655));
+ assertTrue(checkTestIncrementBytes(-1, 1));
+ assertTrue(checkTestIncrementBytes(-26, 5034520));
+ assertTrue(checkTestIncrementBytes(-10657200, 5));
+ assertTrue(checkTestIncrementBytes(-12343250, 45376475));
+ assertTrue(checkTestIncrementBytes(-10, -5));
+ assertTrue(checkTestIncrementBytes(-12343250, -5));
+ assertTrue(checkTestIncrementBytes(-12, -34565445));
+ assertTrue(checkTestIncrementBytes(-1546543452, -34565445));
+ }
+
+ private static boolean checkTestIncrementBytes(long val, long amount)
+ throws IOException {
+ byte[] value = Bytes.toBytes(val);
+ byte [] testValue = {-1, -1, -1, -1, -1, -1, -1, -1};
+ if (value[0] > 0) {
+ testValue = new byte[Bytes.SIZEOF_LONG];
+ }
+ System.arraycopy(value, 0, testValue, testValue.length - value.length,
+ value.length);
+
+ long incrementResult = Bytes.toLong(Bytes.incrementBytes(value, amount));
+
+ return (Bytes.toLong(testValue) + amount) == incrementResult;
+ }
+}