HBASE-17318 Increment does not add new column if the increment amount is zero at first time writing (Guangxu Cheng)

This commit is contained in:
tedyu 2016-12-15 07:06:37 -08:00
parent f9750f2122
commit 401e83cee3
3 changed files with 63 additions and 8 deletions

View File

@ -7508,12 +7508,15 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi
for (int i = 0; i < deltas.size(); i++) { for (int i = 0; i < deltas.size(); i++) {
Cell delta = deltas.get(i); Cell delta = deltas.get(i);
Cell currentValue = null; Cell currentValue = null;
boolean firstWrite = false;
if (currentValuesIndex < currentValues.size() && if (currentValuesIndex < currentValues.size() &&
CellUtil.matchingQualifier(currentValues.get(currentValuesIndex), delta)) { CellUtil.matchingQualifier(currentValues.get(currentValuesIndex), delta)) {
currentValue = currentValues.get(currentValuesIndex); currentValue = currentValues.get(currentValuesIndex);
if (i < (deltas.size() - 1) && !CellUtil.matchingQualifier(delta, deltas.get(i + 1))) { if (i < (deltas.size() - 1) && !CellUtil.matchingQualifier(delta, deltas.get(i + 1))) {
currentValuesIndex++; currentValuesIndex++;
} }
} else {
firstWrite = true;
} }
// Switch on whether this an increment or an append building the new Cell to apply. // Switch on whether this an increment or an append building the new Cell to apply.
Cell newCell = null; Cell newCell = null;
@ -7542,7 +7545,7 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi
coprocessorHost.postMutationBeforeWAL(mutationType, mutation, currentValue, newCell); coprocessorHost.postMutationBeforeWAL(mutationType, mutation, currentValue, newCell);
} }
// If apply, we need to update memstore/WAL with new value; add it toApply. // If apply, we need to update memstore/WAL with new value; add it toApply.
if (apply) { if (apply || firstWrite) {
toApply.add(newCell); toApply.add(newCell);
} }
// Add to results to get returned to the Client. If null, cilent does not want results. // Add to results to get returned to the Client. If null, cilent does not want results.

View File

@ -19,6 +19,7 @@
package org.apache.hadoop.hbase.client; package org.apache.hadoop.hbase.client;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
@ -345,6 +346,49 @@ public class TestIncrementsFromClientSide {
ht.close(); ht.close();
} }
@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 @Test
public void testIncrement() throws Exception { public void testIncrement() throws Exception {
LOG.info("Starting " + this.name.getMethodName()); LOG.info("Starting " + this.name.getMethodName());

View File

@ -177,24 +177,32 @@ public class TestDurability {
final WAL wal = wals.getWAL(tableName, null); final WAL wal = wals.getWAL(tableName, null);
HRegion region = createHRegion(tableName, "increment", wal, Durability.USE_DEFAULT); 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); Increment inc1 = new Increment(row1);
inc1.addColumn(FAMILY, col1, 1); inc1.addColumn(FAMILY, col1, 0);
Result res = region.increment(inc1); Result res = region.increment(inc1);
assertEquals(1, res.size()); assertEquals(1, res.size());
assertEquals(1, Bytes.toLong(res.getValue(FAMILY, col1))); assertEquals(0, Bytes.toLong(res.getValue(FAMILY, col1)));
verifyWALCount(wals, wal, 1); 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 // col1: amount = 0, 0 write back to WAL
inc1 = new Increment(row1); inc1 = new Increment(row1);
inc1.addColumn(FAMILY, col1, 0); inc1.addColumn(FAMILY, col1, 0);
res = region.increment(inc1); res = region.increment(inc1);
assertEquals(1, res.size()); assertEquals(1, res.size());
assertEquals(1, Bytes.toLong(res.getValue(FAMILY, col1))); 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 // col1: amount = 0, col2: amount = 0, col3: amount = 0
// 0 write back to WAL // 1 write back to WAL
inc1 = new Increment(row1); inc1 = new Increment(row1);
inc1.addColumn(FAMILY, col1, 0); inc1.addColumn(FAMILY, col1, 0);
inc1.addColumn(FAMILY, col2, 0); inc1.addColumn(FAMILY, col2, 0);
@ -204,7 +212,7 @@ public class TestDurability {
assertEquals(1, Bytes.toLong(res.getValue(FAMILY, col1))); assertEquals(1, Bytes.toLong(res.getValue(FAMILY, col1)));
assertEquals(0, Bytes.toLong(res.getValue(FAMILY, col2))); assertEquals(0, Bytes.toLong(res.getValue(FAMILY, col2)));
assertEquals(0, Bytes.toLong(res.getValue(FAMILY, col3))); 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 // col1: amount = 5, col2: amount = 4, col3: amount = 3
// 1 write back to WAL // 1 write back to WAL
@ -217,7 +225,7 @@ public class TestDurability {
assertEquals(6, Bytes.toLong(res.getValue(FAMILY, col1))); assertEquals(6, Bytes.toLong(res.getValue(FAMILY, col1)));
assertEquals(4, Bytes.toLong(res.getValue(FAMILY, col2))); assertEquals(4, Bytes.toLong(res.getValue(FAMILY, col2)));
assertEquals(3, Bytes.toLong(res.getValue(FAMILY, col3))); assertEquals(3, Bytes.toLong(res.getValue(FAMILY, col3)));
verifyWALCount(wals, wal, 2); verifyWALCount(wals, wal, 4);
} }
/* /*