Index: hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFileBlock.java =================================================================== --- hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFileBlock.java £¨ÐÞ¶©°æ 1574807£© +++ hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFileBlock.java £¨¹¤×÷¿½±´£© @@ -25,6 +25,7 @@ import java.io.IOException; import java.io.InputStream; import java.nio.ByteBuffer; +import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; @@ -1260,6 +1261,7 @@ private HFileBlockDefaultDecodingContext defaultDecodingCtx; + private AtomicReference prefetchedHeaderGlobal = new AtomicReference(); private ThreadLocal prefetchedHeaderForThread = new ThreadLocal() { @Override @@ -1278,6 +1280,7 @@ new HFileBlockDefaultDecodingContext(fileContext); encodedBlockDecodingCtx = new HFileBlockDefaultDecodingContext(fileContext); + prefetchedHeaderGlobal.set(new PrefetchedHeader()); } /** @@ -1408,9 +1411,15 @@ // read this block's header as part of the previous read's look-ahead. // And we also want to skip reading the header again if it has already // been read. - PrefetchedHeader prefetchedHeader = prefetchedHeaderForThread.get(); - ByteBuffer headerBuf = prefetchedHeader.offset == offset ? - prefetchedHeader.buf : null; + PrefetchedHeader prefetchedHeaderGlobalRef = prefetchedHeaderGlobal.get(); + ByteBuffer headerBuf = prefetchedHeaderGlobalRef.offset == offset ? + prefetchedHeaderGlobalRef.buf : null; + PrefetchedHeader prefetchedHeaderThisThread = prefetchedHeaderGlobalRef; + if (headerBuf == null) { + prefetchedHeaderThisThread = prefetchedHeaderForThread.get(); + headerBuf = prefetchedHeaderThisThread.offset == offset ? + prefetchedHeaderThisThread.buf : null; + } int nextBlockOnDiskSize = 0; // Allocate enough space to fit the next block's header too. @@ -1455,9 +1464,9 @@ + ", preReadHeaderSize=" + hdrSize + ", header.length=" - + prefetchedHeader.header.length + + prefetchedHeaderThisThread.header.length + ", header bytes: " - + Bytes.toStringBinary(prefetchedHeader.header, 0, + + Bytes.toStringBinary(prefetchedHeaderThisThread.header, 0, hdrSize), ex); } // if the caller specifies a onDiskSizeWithHeader, validate it. @@ -1543,9 +1552,14 @@ // Set prefetched header if (b.nextBlockOnDiskSizeWithHeader > 0) { - prefetchedHeader.offset = offset + b.getOnDiskSizeWithHeader(); + PrefetchedHeader nextBlockHeader = new PrefetchedHeader(); + nextBlockHeader.offset = offset + b.getOnDiskSizeWithHeader(); System.arraycopy(onDiskBlock, onDiskSizeWithHeader, - prefetchedHeader.header, 0, hdrSize); + nextBlockHeader.header, 0, hdrSize); + prefetchedHeaderGlobal.set(nextBlockHeader); + prefetchedHeaderForThread.get().offset = offset + b.getOnDiskSizeWithHeader(); + System.arraycopy(onDiskBlock, onDiskSizeWithHeader, + prefetchedHeaderForThread.get().header, 0, hdrSize); } b.offset = offset;