diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFileBlock.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFileBlock.java index 1535fa9..1b63d8a 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFileBlock.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFileBlock.java @@ -300,11 +300,23 @@ public class HFileBlock implements Cacheable { * Copy constructor. Creates a shallow copy of {@code that}'s buffer. */ private HFileBlock(HFileBlock that) { + this(that, false); + } + + /** + * Copy constructor. Creates a shallow/deep copy of {@code that}'s buffer as per the boolean + * param. + */ + private HFileBlock(HFileBlock that,boolean bufCopy) { this.blockType = that.blockType; this.onDiskSizeWithoutHeader = that.onDiskSizeWithoutHeader; this.uncompressedSizeWithoutHeader = that.uncompressedSizeWithoutHeader; this.prevBlockOffset = that.prevBlockOffset; - this.buf = that.buf.duplicate(); + if (bufCopy) { + this.buf = new SingleByteBuff(ByteBuffer.wrap(that.buf.toBytes(0, that.buf.limit()))); + } else { + this.buf = that.buf.duplicate(); + } this.offset = that.offset; this.onDiskDataSizeWithHeader = that.onDiskDataSizeWithHeader; this.fileContext = that.fileContext; @@ -2015,4 +2027,8 @@ public class HFileBlock implements Cacheable { " bytesPerChecksum " + bytesPerChecksum + " onDiskDataSizeWithHeader " + onDiskDataSizeWithHeader; } + + public HFileBlock deepClone() { + return new HFileBlock(this, true); + } } diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/LruBlockCache.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/LruBlockCache.java index 99b67ba..f454549 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/LruBlockCache.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/LruBlockCache.java @@ -479,6 +479,9 @@ public class LruBlockCache implements ResizableBlockCache, HeapSize { // Promote this to L1. if (result != null && caching) { + if (result instanceof HFileBlock && ((HFileBlock) result).usesSharedMemory()) { + result = ((HFileBlock) result).deepClone(); + } cacheBlock(cacheKey, result, /* inMemory = */ false, /* cacheData = */ true); } return result;