Index: src/test/java/org/apache/hadoop/hbase/io/hfile/RandomSeek.java =================================================================== --- src/test/java/org/apache/hadoop/hbase/io/hfile/RandomSeek.java (revision 1198135) +++ src/test/java/org/apache/hadoop/hbase/io/hfile/RandomSeek.java (working copy) @@ -68,7 +68,7 @@ long start = System.currentTimeMillis(); SimpleBlockCache cache = new SimpleBlockCache(); CacheConfig cacheConf = new CacheConfig(cache, true, false, false, false, - false, false, false); + false, false, false, true, false); Reader reader = HFile.createReader(lfs, path, cacheConf); reader.loadFileInfo(); Index: src/main/java/org/apache/hadoop/hbase/regionserver/StoreScanner.java =================================================================== --- src/main/java/org/apache/hadoop/hbase/regionserver/StoreScanner.java (revision 1198135) +++ src/main/java/org/apache/hadoop/hbase/regionserver/StoreScanner.java (working copy) @@ -66,7 +66,8 @@ private StoreScanner(Store store, boolean cacheBlocks, Scan scan, final NavigableSet columns){ this.store = store; - this.cacheBlocks = cacheBlocks; + this.cacheBlocks = cacheBlocks + && (store == null || store.getCacheConfig().shouldCacheDatablocks()); isGet = scan.isGetScan(); int numCol = columns == null ? 0 : columns.size(); explicitColumnQuery = numCol > 0; Index: src/main/java/org/apache/hadoop/hbase/io/hfile/HFileReaderV1.java =================================================================== --- src/main/java/org/apache/hadoop/hbase/io/hfile/HFileReaderV1.java (revision 1198135) +++ src/main/java/org/apache/hadoop/hbase/io/hfile/HFileReaderV1.java (working copy) @@ -30,6 +30,7 @@ import org.apache.hadoop.fs.FSDataInputStream; import org.apache.hadoop.fs.Path; import org.apache.hadoop.hbase.KeyValue; +import org.apache.hadoop.hbase.io.hfile.BlockType.BlockCategory; import org.apache.hadoop.hbase.io.hfile.HFile.FileInfo; import org.apache.hadoop.hbase.io.hfile.HFile.Reader; import org.apache.hadoop.hbase.io.hfile.HFile.Writer; @@ -339,8 +340,12 @@ // Cache the block if (cacheConf.shouldCacheDataOnRead() && cacheBlock) { - cacheConf.getBlockCache().cacheBlock(cacheKey, hfileBlock, - cacheConf.isInMemory()); + cacheConf.getBlockCache().cacheBlock( + cacheKey, + hfileBlock, + cacheConf.isInMemory() + || (cacheConf.shouldCacheIndexBlocksInMemory() && hfileBlock + .getBlockType().getCategory() == BlockCategory.INDEX)); } return buf; Index: src/main/java/org/apache/hadoop/hbase/io/hfile/HFileReaderV2.java =================================================================== --- src/main/java/org/apache/hadoop/hbase/io/hfile/HFileReaderV2.java (revision 1198135) +++ src/main/java/org/apache/hadoop/hbase/io/hfile/HFileReaderV2.java (working copy) @@ -30,6 +30,7 @@ import org.apache.hadoop.fs.FSDataInputStream; import org.apache.hadoop.fs.Path; import org.apache.hadoop.hbase.KeyValue; +import org.apache.hadoop.hbase.io.hfile.BlockType.BlockCategory; import org.apache.hadoop.hbase.io.hfile.HFile.FileInfo; import org.apache.hadoop.hbase.regionserver.HRegion; import org.apache.hadoop.hbase.util.Bytes; @@ -284,8 +285,12 @@ // Cache the block if (cacheBlock) { - cacheConf.getBlockCache().cacheBlock(cacheKey, dataBlock, - cacheConf.isInMemory()); + cacheConf.getBlockCache().cacheBlock( + cacheKey, + dataBlock, + cacheConf.isInMemory() + || (cacheConf.shouldCacheIndexBlocksInMemory() && dataBlock + .getBlockType().getCategory() == BlockCategory.INDEX)); } if (dataBlock.getBlockType() == BlockType.DATA) Index: src/main/java/org/apache/hadoop/hbase/io/hfile/CacheConfig.java =================================================================== --- src/main/java/org/apache/hadoop/hbase/io/hfile/CacheConfig.java (revision 1198135) +++ src/main/java/org/apache/hadoop/hbase/io/hfile/CacheConfig.java (working copy) @@ -74,6 +74,18 @@ public static final String EVICT_BLOCKS_ON_CLOSE_KEY = "hbase.rs.evictblocksonclose"; + /** + * Configuration key to cache data blocks. + */ + public static final String HFILE_BLOCK_CACHE_DATABLOCKS_KEY = + "hfile.block.cache.datablocks"; + + /** + * Configuration key to cache index blocks witn IN_MEMORY priority. + */ + public static final String HFILE_BLOCK_INDEXBLOCKS_IN_MEMORY_KEY = + "hfile.block.cache.indexblocks.inmemory"; + // Defaults public static final boolean DEFAULT_CACHE_DATA_ON_READ = true; @@ -83,6 +95,8 @@ public static final boolean DEFAULT_CACHE_BLOOMS_ON_WRITE = false; public static final boolean DEFAULT_EVICT_ON_CLOSE = false; public static final boolean DEFAULT_COMPRESSED_CACHE = false; + public static final boolean DEFAULT_CACHE_DATABLOCKS = true; + public static final boolean DEFAULT_INDEXBLOCKS_IN_MEMORY = false; /** Local reference to the block cache, null if completely disabled */ private final BlockCache blockCache; @@ -96,6 +110,9 @@ /** Whether blocks should be flagged as in-memory when being cached */ private final boolean inMemory; + /** Whether index blocks should be flagged as in-memory when being cached */ + private final boolean indexBlocksInMemory; + /** Whether data blocks should be cached when new files are written */ private boolean cacheDataOnWrite; @@ -112,6 +129,11 @@ private final boolean cacheCompressed; /** + * Whether data blocks should be cached, if false only index blocks are cached + */ + private final boolean cacheDatablocks; + + /** * Create a cache configuration using the specified configuration object and * family descriptor. * @param conf hbase configuration @@ -126,8 +148,11 @@ conf.getBoolean(CACHE_BLOOM_BLOCKS_ON_WRITE_KEY, DEFAULT_CACHE_BLOOMS_ON_WRITE), conf.getBoolean(EVICT_BLOCKS_ON_CLOSE_KEY, DEFAULT_EVICT_ON_CLOSE), - conf.getBoolean(CACHE_DATA_BLOCKS_COMPRESSED_KEY, DEFAULT_COMPRESSED_CACHE) - ); + conf.getBoolean(CACHE_DATA_BLOCKS_COMPRESSED_KEY, DEFAULT_COMPRESSED_CACHE), + conf.getBoolean(HFILE_BLOCK_CACHE_DATABLOCKS_KEY, DEFAULT_CACHE_DATABLOCKS), + conf.getBoolean(HFILE_BLOCK_INDEXBLOCKS_IN_MEMORY_KEY, + DEFAULT_INDEXBLOCKS_IN_MEMORY) + ); } /** @@ -143,11 +168,15 @@ conf.getBoolean(CACHE_BLOCKS_ON_WRITE_KEY, DEFAULT_CACHE_DATA_ON_WRITE), conf.getBoolean(CACHE_INDEX_BLOCKS_ON_WRITE_KEY, DEFAULT_CACHE_INDEXES_ON_WRITE), - conf.getBoolean(CACHE_BLOOM_BLOCKS_ON_WRITE_KEY, + conf.getBoolean(CACHE_BLOOM_BLOCKS_ON_WRITE_KEY, DEFAULT_CACHE_BLOOMS_ON_WRITE), conf.getBoolean(EVICT_BLOCKS_ON_CLOSE_KEY, DEFAULT_EVICT_ON_CLOSE), conf.getBoolean(CACHE_DATA_BLOCKS_COMPRESSED_KEY, - DEFAULT_COMPRESSED_CACHE) + DEFAULT_COMPRESSED_CACHE), + conf.getBoolean(HFILE_BLOCK_CACHE_DATABLOCKS_KEY, + DEFAULT_CACHE_DATABLOCKS), + conf.getBoolean(HFILE_BLOCK_INDEXBLOCKS_IN_MEMORY_KEY, + DEFAULT_INDEXBLOCKS_IN_MEMORY) ); } @@ -162,12 +191,15 @@ * @param cacheBloomsOnWrite whether blooms should be cached on write * @param evictOnClose whether blocks should be evicted when HFile is closed * @param cacheCompressed whether to store blocks as compressed in the cache + * @param cacheDatablocks whether to cache data blocks + * @param indexBlocksInMemory whether to cache index blocks in-memory */ CacheConfig(final BlockCache blockCache, final boolean cacheDataOnRead, final boolean inMemory, final boolean cacheDataOnWrite, final boolean cacheIndexesOnWrite, final boolean cacheBloomsOnWrite, final boolean evictOnClose, - final boolean cacheCompressed) { + final boolean cacheCompressed, final boolean cacheDatablocks, + final boolean indexBlocksInMemory) { this.blockCache = blockCache; this.cacheDataOnRead = cacheDataOnRead; this.inMemory = inMemory; @@ -176,6 +208,8 @@ this.cacheBloomsOnWrite = cacheBloomsOnWrite; this.evictOnClose = evictOnClose; this.cacheCompressed = cacheCompressed; + this.cacheDatablocks = cacheDatablocks; + this.indexBlocksInMemory = indexBlocksInMemory; } /** @@ -186,7 +220,8 @@ this(cacheConf.blockCache, cacheConf.cacheDataOnRead, cacheConf.inMemory, cacheConf.cacheDataOnWrite, cacheConf.cacheIndexesOnWrite, cacheConf.cacheBloomsOnWrite, cacheConf.evictOnClose, - cacheConf.cacheCompressed); + cacheConf.cacheCompressed, cacheConf.cacheDatablocks, + cacheConf.indexBlocksInMemory); } /** @@ -213,6 +248,21 @@ } /** + * Returns whether data blocks of this HFile should be cached or not. + * @return true if blocks should be cached, false if not + */ + public boolean shouldCacheDatablocks() { + return isBlockCacheEnabled() && cacheDatablocks; + } + + /** + * @return true if index blocks should be flagged as in-memory + */ + public boolean shouldCacheIndexBlocksInMemory() { + return isBlockCacheEnabled() && indexBlocksInMemory; + } + + /** * @return true if blocks in this file should be flagged as in-memory */ public boolean isInMemory() { Index: src/main/java/org/apache/hadoop/hbase/io/hfile/BlockType.java =================================================================== --- src/main/java/org/apache/hadoop/hbase/io/hfile/BlockType.java (revision 1198135) +++ src/main/java/org/apache/hadoop/hbase/io/hfile/BlockType.java (working copy) @@ -108,6 +108,10 @@ return metricCat.toString(); } + public BlockCategory getCategory(){ + return metricCat; + } + public static BlockType parse(byte[] buf, int offset, int length) throws IOException { if (length != MAGIC_LENGTH) {