diff --git hbase-common/src/main/java/org/apache/hadoop/hbase/CellUtil.java hbase-common/src/main/java/org/apache/hadoop/hbase/CellUtil.java index 7a9fe66..b506903 100644 --- hbase-common/src/main/java/org/apache/hadoop/hbase/CellUtil.java +++ hbase-common/src/main/java/org/apache/hadoop/hbase/CellUtil.java @@ -459,12 +459,17 @@ public final class CellUtil { public TagRewriteCell(Cell cell, byte[] tags) { assert cell instanceof ExtendedCell; assert tags != null; - this.cell = cell; this.tags = tags; // tag offset will be treated as 0 and length this.tags.length - if (this.cell instanceof TagRewriteCell) { + if (cell instanceof TagRewriteCell) { // Cleaning the ref so that the byte[] can be GCed - ((TagRewriteCell) this.cell).tags = null; + ((TagRewriteCell) cell).tags = null; + // What this is doing is even if we have N levels of TagRewriteCells, + // the top most originally refer to the bottom most one which might + // in all chance dont have any cells in it. + this.cell = ((TagRewriteCell) cell).cell; + } else { + this.cell = cell; } } diff --git hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java index d0e5f93..961b88a 100644 --- hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java +++ hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java @@ -7538,17 +7538,15 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi tags); } - private Cell reckonAppend(final Cell delta, final Cell currentValue, final long now, - Append mutation) - throws IOException { - // Forward any tags found on the delta. - List tags = TagUtil.carryForwardTags(delta); - long ts = now; - Cell newCell = null; + private static Cell reckonAppend(final Cell delta, final Cell currentValue, + final long now, Append mutation) throws IOException { + Cell newCell; byte [] row = mutation.getRow(); if (currentValue != null) { + // Forward any tags found on the delta. + List tags = TagUtil.carryForwardTags(delta); tags = TagUtil.carryForwardTags(tags, currentValue); - ts = Math.max(now, currentValue.getTimestamp() + 1); + long ts = Math.max(now, currentValue.getTimestamp() + 1); tags = TagUtil.carryForwardTTLTag(tags, mutation.getTTL()); byte[] tagBytes = TagUtil.fromList(tags); // Allocate an empty cell and copy in all parts. @@ -7578,8 +7576,10 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi // Append's KeyValue.Type==Put and ts==HConstants.LATEST_TIMESTAMP CellUtil.updateLatestStamp(delta, now); newCell = delta; - tags = TagUtil.carryForwardTTLTag(tags, mutation.getTTL()); - if (tags != null) { + // The custom TTL should be carried. + if (mutation.getTTL() != Long.MAX_VALUE) { + List tags = TagUtil.carryForwardTags(delta); + tags = TagUtil.carryForwardTTLTag(tags, mutation.getTTL()); newCell = CellUtil.createCell(delta, tags); } } diff --git hbase-server/src/test/java/org/apache/hadoop/hbase/TestTagRewriteCell.java hbase-server/src/test/java/org/apache/hadoop/hbase/TestTagRewriteCell.java index 54ae775..33850df 100644 --- hbase-server/src/test/java/org/apache/hadoop/hbase/TestTagRewriteCell.java +++ hbase-server/src/test/java/org/apache/hadoop/hbase/TestTagRewriteCell.java @@ -16,6 +16,8 @@ */ package org.apache.hadoop.hbase; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import static org.junit.Assert.assertTrue; import org.apache.hadoop.hbase.io.HeapSize; @@ -26,7 +28,6 @@ import org.junit.experimental.categories.Category; @Category(SmallTests.class) public class TestTagRewriteCell { - @Test public void testHeapSize() { Cell originalCell = CellUtil.createCell(Bytes.toBytes("row"), Bytes.toBytes("value")); @@ -36,13 +37,17 @@ public class TestTagRewriteCell { // Get the heapSize before the internal tags array in trCell are nuked long trCellHeapSize = ((HeapSize)trCell).heapSize(); + Cell trCell2 = trCell; // Make another TagRewriteCell with the original TagRewriteCell // This happens on systems with more than one RegionObserver/Coproc loaded (such as // VisibilityController and AccessController) - Cell trCell2 = CellUtil.createCell(trCell, new byte[fakeTagArrayLength]); + // Make N levels of TagRewriteCells for testing the heap size. + for (int i = 0; i != 10; ++i) { + trCell2 = CellUtil.createCell(trCell2, new byte[fakeTagArrayLength]); + } - assertTrue("TagRewriteCell containing a TagRewriteCell's heapsize should be larger than a " + - "single TagRewriteCell's heapsize", trCellHeapSize < ((HeapSize)trCell2).heapSize()); + assertTrue("TagRewriteCell containing many TagRewriteCell's heapsize should be equal with a " + + "single TagRewriteCell's heapsize", trCellHeapSize == ((HeapSize)trCell2).heapSize()); assertTrue("TagRewriteCell should have had nulled out tags array", ((HeapSize)trCell).heapSize() < trCellHeapSize); }