diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java index 7364162..a21fd3c 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java @@ -7534,12 +7534,15 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi for (int i = 0; i < deltas.size(); i++) { Cell delta = deltas.get(i); Cell currentValue = null; + boolean firstWrite = false; if (currentValuesIndex < currentValues.size() && CellUtil.matchingQualifier(currentValues.get(currentValuesIndex), delta)) { currentValue = currentValues.get(currentValuesIndex); if (i < (deltas.size() - 1) && !CellUtil.matchingQualifier(delta, deltas.get(i + 1))) { currentValuesIndex++; } + } else { + firstWrite = true; } // Switch on whether this an increment or an append building the new Cell to apply. Cell newCell = null; @@ -7568,7 +7571,7 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi coprocessorHost.postMutationBeforeWAL(mutationType, mutation, currentValue, newCell); } // If apply, we need to update memstore/WAL with new value; add it toApply. - if (apply) { + if (apply || firstWrite) { toApply.add(newCell); } // Add to results to get returned to the Client. If null, cilent does not want results. diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestIncrementsFromClientSide.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestIncrementsFromClientSide.java index 1c51177..0ea61ec 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestIncrementsFromClientSide.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestIncrementsFromClientSide.java @@ -19,6 +19,7 @@ package org.apache.hadoop.hbase.client; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -346,6 +347,49 @@ public class TestIncrementsFromClientSide { } @Test + public void testIncrementIncrZeroAtFirst() throws Exception { + LOG.info("Starting " + this.name.getMethodName()); + final TableName TABLENAME = + TableName.valueOf(filterStringSoTableNameSafe(this.name.getMethodName())); + Table ht = TEST_UTIL.createTable(TABLENAME, FAMILY); + + byte[] col1 = Bytes.toBytes("col1"); + byte[] col2 = Bytes.toBytes("col2"); + byte[] col3 = Bytes.toBytes("col3"); + + // Now increment zero at first time incr + Increment inc = new Increment(ROW); + inc.addColumn(FAMILY, col1, 0); + ht.increment(inc); + + // Verify expected results + Get get = new Get(ROW); + Result r = ht.get(get); + Cell [] kvs = r.rawCells(); + assertEquals(1, kvs.length); + assertNotNull(kvs[0]); + assertIncrementKey(kvs[0], ROW, FAMILY, col1, 0); + + // Now try multiple columns by different amounts + inc = new Increment(ROW); + inc.addColumn(FAMILY, col1, 1); + inc.addColumn(FAMILY, col2, 0); + inc.addColumn(FAMILY, col3, 2); + ht.increment(inc); + // Verify + get = new Get(ROW); + r = ht.get(get); + kvs = r.rawCells(); + assertEquals(3, kvs.length); + assertNotNull(kvs[0]); + assertNotNull(kvs[1]); + assertNotNull(kvs[2]); + assertIncrementKey(kvs[0], ROW, FAMILY, col1, 1); + assertIncrementKey(kvs[1], ROW, FAMILY, col2, 0); + assertIncrementKey(kvs[2], ROW, FAMILY, col3, 2); + } + + @Test public void testIncrement() throws Exception { LOG.info("Starting " + this.name.getMethodName()); final TableName TABLENAME = diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/wal/TestDurability.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/wal/TestDurability.java index e6fbf36..f80d66b 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/wal/TestDurability.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/wal/TestDurability.java @@ -177,24 +177,32 @@ public class TestDurability { final WAL wal = wals.getWAL(tableName, null); HRegion region = createHRegion(tableName, "increment", wal, Durability.USE_DEFAULT); - // col1: amount = 1, 1 write back to WAL + // col1: amount = 0, 1 write back to WAL Increment inc1 = new Increment(row1); - inc1.addColumn(FAMILY, col1, 1); + inc1.addColumn(FAMILY, col1, 0); Result res = region.increment(inc1); assertEquals(1, res.size()); - assertEquals(1, Bytes.toLong(res.getValue(FAMILY, col1))); + assertEquals(0, Bytes.toLong(res.getValue(FAMILY, col1))); verifyWALCount(wals, wal, 1); + // col1: amount = 1, 1 write back to WAL + inc1 = new Increment(row1); + inc1.addColumn(FAMILY, col1, 1); + res = region.increment(inc1); + assertEquals(1, res.size()); + assertEquals(1, Bytes.toLong(res.getValue(FAMILY, col1))); + verifyWALCount(wals, wal, 2); + // col1: amount = 0, 0 write back to WAL inc1 = new Increment(row1); inc1.addColumn(FAMILY, col1, 0); res = region.increment(inc1); assertEquals(1, res.size()); assertEquals(1, Bytes.toLong(res.getValue(FAMILY, col1))); - verifyWALCount(wals, wal, 1); + verifyWALCount(wals, wal, 2); // col1: amount = 0, col2: amount = 0, col3: amount = 0 - // 0 write back to WAL + // 1 write back to WAL inc1 = new Increment(row1); inc1.addColumn(FAMILY, col1, 0); inc1.addColumn(FAMILY, col2, 0); @@ -204,7 +212,7 @@ public class TestDurability { assertEquals(1, Bytes.toLong(res.getValue(FAMILY, col1))); assertEquals(0, Bytes.toLong(res.getValue(FAMILY, col2))); assertEquals(0, Bytes.toLong(res.getValue(FAMILY, col3))); - verifyWALCount(wals, wal, 1); + verifyWALCount(wals, wal, 3); // col1: amount = 5, col2: amount = 4, col3: amount = 3 // 1 write back to WAL @@ -217,7 +225,7 @@ public class TestDurability { assertEquals(6, Bytes.toLong(res.getValue(FAMILY, col1))); assertEquals(4, Bytes.toLong(res.getValue(FAMILY, col2))); assertEquals(3, Bytes.toLong(res.getValue(FAMILY, col3))); - verifyWALCount(wals, wal, 2); + verifyWALCount(wals, wal, 4); } /*