@ -178,6 +178,7 @@ class BlockBasedTable::IndexReaderCommon : public BlockBasedTable::IndexReader {
FilePrefetchBuffer * prefetch_buffer ,
FilePrefetchBuffer * prefetch_buffer ,
const ReadOptions & read_options ,
const ReadOptions & read_options ,
GetContext * get_context ,
GetContext * get_context ,
BlockCacheLookupContext * lookup_context ,
CachableEntry < Block > * index_block ) ;
CachableEntry < Block > * index_block ) ;
const BlockBasedTable * table ( ) const { return table_ ; }
const BlockBasedTable * table ( ) const { return table_ ; }
@ -211,6 +212,7 @@ class BlockBasedTable::IndexReaderCommon : public BlockBasedTable::IndexReader {
Status GetOrReadIndexBlock ( const ReadOptions & read_options ,
Status GetOrReadIndexBlock ( const ReadOptions & read_options ,
GetContext * get_context ,
GetContext * get_context ,
BlockCacheLookupContext * lookup_context ,
CachableEntry < Block > * index_block ) const ;
CachableEntry < Block > * index_block ) const ;
size_t ApproximateIndexBlockMemoryUsage ( ) const {
size_t ApproximateIndexBlockMemoryUsage ( ) const {
@ -228,6 +230,7 @@ class BlockBasedTable::IndexReaderCommon : public BlockBasedTable::IndexReader {
Status BlockBasedTable : : IndexReaderCommon : : ReadIndexBlock (
Status BlockBasedTable : : IndexReaderCommon : : ReadIndexBlock (
const BlockBasedTable * table , FilePrefetchBuffer * prefetch_buffer ,
const BlockBasedTable * table , FilePrefetchBuffer * prefetch_buffer ,
const ReadOptions & read_options , GetContext * get_context ,
const ReadOptions & read_options , GetContext * get_context ,
BlockCacheLookupContext * lookup_context ,
CachableEntry < Block > * index_block ) {
CachableEntry < Block > * index_block ) {
PERF_TIMER_GUARD ( read_index_block_nanos ) ;
PERF_TIMER_GUARD ( read_index_block_nanos ) ;
@ -241,13 +244,14 @@ Status BlockBasedTable::IndexReaderCommon::ReadIndexBlock(
const Status s = table - > RetrieveBlock (
const Status s = table - > RetrieveBlock (
prefetch_buffer , read_options , rep - > footer . index_handle ( ) ,
prefetch_buffer , read_options , rep - > footer . index_handle ( ) ,
UncompressionDict : : GetEmptyDict ( ) , index_block , BlockType : : kIndex ,
UncompressionDict : : GetEmptyDict ( ) , index_block , BlockType : : kIndex ,
get_context ) ;
get_context , lookup_context ) ;
return s ;
return s ;
}
}
Status BlockBasedTable : : IndexReaderCommon : : GetOrReadIndexBlock (
Status BlockBasedTable : : IndexReaderCommon : : GetOrReadIndexBlock (
const ReadOptions & read_options , GetContext * get_context ,
const ReadOptions & read_options , GetContext * get_context ,
BlockCacheLookupContext * lookup_context ,
CachableEntry < Block > * index_block ) const {
CachableEntry < Block > * index_block ) const {
assert ( index_block ! = nullptr ) ;
assert ( index_block ! = nullptr ) ;
@ -256,8 +260,8 @@ Status BlockBasedTable::IndexReaderCommon::GetOrReadIndexBlock(
return Status : : OK ( ) ;
return Status : : OK ( ) ;
}
}
return ReadIndexBlock ( table_ , nullptr /* prefetch_buffer */ , read_options ,
return ReadIndexBlock ( table_ , /*prefetch_buffer=*/ nullptr , read_options ,
get_context , index_block ) ;
get_context , lookup_context , index_block ) ;
}
}
// Index that allows binary search lookup in a two-level index structure.
// Index that allows binary search lookup in a two-level index structure.
@ -269,7 +273,8 @@ class PartitionIndexReader : public BlockBasedTable::IndexReaderCommon {
// unmodified.
// unmodified.
static Status Create ( const BlockBasedTable * table ,
static Status Create ( const BlockBasedTable * table ,
FilePrefetchBuffer * prefetch_buffer , bool use_cache ,
FilePrefetchBuffer * prefetch_buffer , bool use_cache ,
bool prefetch , bool pin , IndexReader * * index_reader ) {
bool prefetch , bool pin , IndexReader * * index_reader ,
BlockCacheLookupContext * lookup_context ) {
assert ( table ! = nullptr ) ;
assert ( table ! = nullptr ) ;
assert ( table - > get_rep ( ) ) ;
assert ( table - > get_rep ( ) ) ;
assert ( ! pin | | prefetch ) ;
assert ( ! pin | | prefetch ) ;
@ -277,8 +282,9 @@ class PartitionIndexReader : public BlockBasedTable::IndexReaderCommon {
CachableEntry < Block > index_block ;
CachableEntry < Block > index_block ;
if ( prefetch | | ! use_cache ) {
if ( prefetch | | ! use_cache ) {
const Status s = ReadIndexBlock ( table , prefetch_buffer , ReadOptions ( ) ,
const Status s =
nullptr /* get_context */ , & index_block ) ;
ReadIndexBlock ( table , prefetch_buffer , ReadOptions ( ) ,
/*get_context=*/ nullptr , lookup_context , & index_block ) ;
if ( ! s . ok ( ) ) {
if ( ! s . ok ( ) ) {
return s ;
return s ;
}
}
@ -296,10 +302,11 @@ class PartitionIndexReader : public BlockBasedTable::IndexReaderCommon {
// return a two-level iterator: first level is on the partition index
// return a two-level iterator: first level is on the partition index
InternalIteratorBase < BlockHandle > * NewIterator (
InternalIteratorBase < BlockHandle > * NewIterator (
const ReadOptions & read_options , bool /* disable_prefix_seek */ ,
const ReadOptions & read_options , bool /* disable_prefix_seek */ ,
IndexBlockIter * iter , GetContext * get_context ) override {
IndexBlockIter * iter , GetContext * get_context ,
BlockCacheLookupContext * lookup_context ) override {
CachableEntry < Block > index_block ;
CachableEntry < Block > index_block ;
const Status s =
const Status s = GetOrReadIndexBlock ( read_options , get_context ,
GetOrReadIndexBlock ( read_options , get _context, & index_block ) ;
lookup _context , & index_block ) ;
if ( ! s . ok ( ) ) {
if ( ! s . ok ( ) ) {
if ( iter ! = nullptr ) {
if ( iter ! = nullptr ) {
iter - > Invalidate ( s ) ;
iter - > Invalidate ( s ) ;
@ -352,6 +359,7 @@ class PartitionIndexReader : public BlockBasedTable::IndexReaderCommon {
void CacheDependencies ( bool pin ) override {
void CacheDependencies ( bool pin ) override {
// Before read partitions, prefetch them to avoid lots of IOs
// Before read partitions, prefetch them to avoid lots of IOs
BlockCacheLookupContext lookup_context { BlockCacheLookupCaller : : kPrefetch } ;
auto rep = table ( ) - > rep_ ;
auto rep = table ( ) - > rep_ ;
IndexBlockIter biter ;
IndexBlockIter biter ;
BlockHandle handle ;
BlockHandle handle ;
@ -359,7 +367,7 @@ class PartitionIndexReader : public BlockBasedTable::IndexReaderCommon {
CachableEntry < Block > index_block ;
CachableEntry < Block > index_block ;
Status s = GetOrReadIndexBlock ( ReadOptions ( ) , nullptr /* get_context */ ,
Status s = GetOrReadIndexBlock ( ReadOptions ( ) , nullptr /* get_context */ ,
& index_block ) ;
& lookup_context , & index_block ) ;
if ( ! s . ok ( ) ) {
if ( ! s . ok ( ) ) {
ROCKS_LOG_WARN ( rep - > ioptions . info_log ,
ROCKS_LOG_WARN ( rep - > ioptions . info_log ,
" Error retrieving top-level index block while trying to "
" Error retrieving top-level index block while trying to "
@ -408,7 +416,7 @@ class PartitionIndexReader : public BlockBasedTable::IndexReaderCommon {
// filter blocks
// filter blocks
s = table ( ) - > MaybeReadBlockAndLoadToCache (
s = table ( ) - > MaybeReadBlockAndLoadToCache (
prefetch_buffer . get ( ) , ro , handle , UncompressionDict : : GetEmptyDict ( ) ,
prefetch_buffer . get ( ) , ro , handle , UncompressionDict : : GetEmptyDict ( ) ,
& block , BlockType : : kIndex , nullptr /* get_context */ ) ;
& block , BlockType : : kIndex , /*get_context=*/ nullptr , & lookup_context ) ;
assert ( s . ok ( ) | | block . GetValue ( ) = = nullptr ) ;
assert ( s . ok ( ) | | block . GetValue ( ) = = nullptr ) ;
if ( s . ok ( ) & & block . GetValue ( ) ! = nullptr ) {
if ( s . ok ( ) & & block . GetValue ( ) ! = nullptr ) {
@ -451,7 +459,8 @@ class BinarySearchIndexReader : public BlockBasedTable::IndexReaderCommon {
// unmodified.
// unmodified.
static Status Create ( const BlockBasedTable * table ,
static Status Create ( const BlockBasedTable * table ,
FilePrefetchBuffer * prefetch_buffer , bool use_cache ,
FilePrefetchBuffer * prefetch_buffer , bool use_cache ,
bool prefetch , bool pin , IndexReader * * index_reader ) {
bool prefetch , bool pin , IndexReader * * index_reader ,
BlockCacheLookupContext * lookup_context ) {
assert ( table ! = nullptr ) ;
assert ( table ! = nullptr ) ;
assert ( table - > get_rep ( ) ) ;
assert ( table - > get_rep ( ) ) ;
assert ( ! pin | | prefetch ) ;
assert ( ! pin | | prefetch ) ;
@ -459,8 +468,9 @@ class BinarySearchIndexReader : public BlockBasedTable::IndexReaderCommon {
CachableEntry < Block > index_block ;
CachableEntry < Block > index_block ;
if ( prefetch | | ! use_cache ) {
if ( prefetch | | ! use_cache ) {
const Status s = ReadIndexBlock ( table , prefetch_buffer , ReadOptions ( ) ,
const Status s =
nullptr /* get_context */ , & index_block ) ;
ReadIndexBlock ( table , prefetch_buffer , ReadOptions ( ) ,
/*get_context=*/ nullptr , lookup_context , & index_block ) ;
if ( ! s . ok ( ) ) {
if ( ! s . ok ( ) ) {
return s ;
return s ;
}
}
@ -477,10 +487,11 @@ class BinarySearchIndexReader : public BlockBasedTable::IndexReaderCommon {
InternalIteratorBase < BlockHandle > * NewIterator (
InternalIteratorBase < BlockHandle > * NewIterator (
const ReadOptions & read_options , bool /* disable_prefix_seek */ ,
const ReadOptions & read_options , bool /* disable_prefix_seek */ ,
IndexBlockIter * iter , GetContext * get_context ) override {
IndexBlockIter * iter , GetContext * get_context ,
BlockCacheLookupContext * lookup_context ) override {
CachableEntry < Block > index_block ;
CachableEntry < Block > index_block ;
const Status s =
const Status s = GetOrReadIndexBlock ( read_options , get_context ,
GetOrReadIndexBlock ( read_options , get _context, & index_block ) ;
lookup _context , & index_block ) ;
if ( ! s . ok ( ) ) {
if ( ! s . ok ( ) ) {
if ( iter ! = nullptr ) {
if ( iter ! = nullptr ) {
iter - > Invalidate ( s ) ;
iter - > Invalidate ( s ) ;
@ -526,7 +537,8 @@ class HashIndexReader : public BlockBasedTable::IndexReaderCommon {
static Status Create ( const BlockBasedTable * table ,
static Status Create ( const BlockBasedTable * table ,
FilePrefetchBuffer * prefetch_buffer ,
FilePrefetchBuffer * prefetch_buffer ,
InternalIterator * meta_index_iter , bool use_cache ,
InternalIterator * meta_index_iter , bool use_cache ,
bool prefetch , bool pin , IndexReader * * index_reader ) {
bool prefetch , bool pin , IndexReader * * index_reader ,
BlockCacheLookupContext * lookup_context ) {
assert ( table ! = nullptr ) ;
assert ( table ! = nullptr ) ;
assert ( index_reader ! = nullptr ) ;
assert ( index_reader ! = nullptr ) ;
assert ( ! pin | | prefetch ) ;
assert ( ! pin | | prefetch ) ;
@ -536,8 +548,9 @@ class HashIndexReader : public BlockBasedTable::IndexReaderCommon {
CachableEntry < Block > index_block ;
CachableEntry < Block > index_block ;
if ( prefetch | | ! use_cache ) {
if ( prefetch | | ! use_cache ) {
const Status s = ReadIndexBlock ( table , prefetch_buffer , ReadOptions ( ) ,
const Status s =
nullptr /* get_context */ , & index_block ) ;
ReadIndexBlock ( table , prefetch_buffer , ReadOptions ( ) ,
/*get_context=*/ nullptr , lookup_context , & index_block ) ;
if ( ! s . ok ( ) ) {
if ( ! s . ok ( ) ) {
return s ;
return s ;
}
}
@ -616,10 +629,11 @@ class HashIndexReader : public BlockBasedTable::IndexReaderCommon {
InternalIteratorBase < BlockHandle > * NewIterator (
InternalIteratorBase < BlockHandle > * NewIterator (
const ReadOptions & read_options , bool disable_prefix_seek ,
const ReadOptions & read_options , bool disable_prefix_seek ,
IndexBlockIter * iter , GetContext * get_context ) override {
IndexBlockIter * iter , GetContext * get_context ,
BlockCacheLookupContext * lookup_context ) override {
CachableEntry < Block > index_block ;
CachableEntry < Block > index_block ;
const Status s =
const Status s = GetOrReadIndexBlock ( read_options , get_context ,
GetOrReadIndexBlock ( read_options , get _context, & index_block ) ;
lookup _context , & index_block ) ;
if ( ! s . ok ( ) ) {
if ( ! s . ok ( ) ) {
if ( iter ! = nullptr ) {
if ( iter ! = nullptr ) {
iter - > Invalidate ( s ) ;
iter - > Invalidate ( s ) ;
@ -1055,6 +1069,7 @@ Status BlockBasedTable::Open(const ImmutableCFOptions& ioptions,
// Better not mutate rep_ after the creation. eg. internal_prefix_transform
// Better not mutate rep_ after the creation. eg. internal_prefix_transform
// raw pointer will be used to create HashIndexReader, whose reset may
// raw pointer will be used to create HashIndexReader, whose reset may
// access a dangling pointer.
// access a dangling pointer.
BlockCacheLookupContext lookup_context { BlockCacheLookupCaller : : kPrefetch } ;
Rep * rep = new BlockBasedTable : : Rep ( ioptions , env_options , table_options ,
Rep * rep = new BlockBasedTable : : Rep ( ioptions , env_options , table_options ,
internal_comparator , skip_filters , level ,
internal_comparator , skip_filters , level ,
immortal_table ) ;
immortal_table ) ;
@ -1095,13 +1110,13 @@ Status BlockBasedTable::Open(const ImmutableCFOptions& ioptions,
return s ;
return s ;
}
}
s = new_table - > ReadRangeDelBlock ( prefetch_buffer . get ( ) , meta_iter . get ( ) ,
s = new_table - > ReadRangeDelBlock ( prefetch_buffer . get ( ) , meta_iter . get ( ) ,
internal_comparator ) ;
internal_comparator , & lookup_context ) ;
if ( ! s . ok ( ) ) {
if ( ! s . ok ( ) ) {
return s ;
return s ;
}
}
s = new_table - > PrefetchIndexAndFilterBlocks (
s = new_table - > PrefetchIndexAndFilterBlocks (
prefetch_buffer . get ( ) , meta_iter . get ( ) , new_table . get ( ) , prefetch_all ,
prefetch_buffer . get ( ) , meta_iter . get ( ) , new_table . get ( ) , prefetch_all ,
table_options , level ) ;
table_options , level , & lookup_context ) ;
if ( s . ok ( ) ) {
if ( s . ok ( ) ) {
// Update tail prefetch stats
// Update tail prefetch stats
@ -1304,7 +1319,8 @@ Status BlockBasedTable::ReadPropertiesBlock(
Status BlockBasedTable : : ReadRangeDelBlock (
Status BlockBasedTable : : ReadRangeDelBlock (
FilePrefetchBuffer * prefetch_buffer , InternalIterator * meta_iter ,
FilePrefetchBuffer * prefetch_buffer , InternalIterator * meta_iter ,
const InternalKeyComparator & internal_comparator ) {
const InternalKeyComparator & internal_comparator ,
BlockCacheLookupContext * lookup_context ) {
Status s ;
Status s ;
bool found_range_del_block ;
bool found_range_del_block ;
BlockHandle range_del_handle ;
BlockHandle range_del_handle ;
@ -1317,10 +1333,10 @@ Status BlockBasedTable::ReadRangeDelBlock(
} else if ( found_range_del_block & & ! range_del_handle . IsNull ( ) ) {
} else if ( found_range_del_block & & ! range_del_handle . IsNull ( ) ) {
ReadOptions read_options ;
ReadOptions read_options ;
std : : unique_ptr < InternalIterator > iter ( NewDataBlockIterator < DataBlockIter > (
std : : unique_ptr < InternalIterator > iter ( NewDataBlockIterator < DataBlockIter > (
read_options , range_del_handle , nullptr /* input_iter */ ,
read_options , range_del_handle ,
BlockType : : kRangeDeletion , true /* key_includes_seq */ ,
/*input_iter=*/ nullptr , BlockType : : kRangeDeletion ,
true /* index_key_is_full */ , nullptr /* get_context */ , Status ( ) ,
/*key_includes_seq=*/ true , /*index_key_is_full=*/ true ,
prefetch_buffer ) ) ;
/*get_context=*/ nullptr , lookup_context , Status ( ) , prefetch_buffer ) ) ;
assert ( iter ! = nullptr ) ;
assert ( iter ! = nullptr ) ;
s = iter - > status ( ) ;
s = iter - > status ( ) ;
if ( ! s . ok ( ) ) {
if ( ! s . ok ( ) ) {
@ -1370,7 +1386,8 @@ Status BlockBasedTable::ReadCompressionDictBlock(
Status BlockBasedTable : : PrefetchIndexAndFilterBlocks (
Status BlockBasedTable : : PrefetchIndexAndFilterBlocks (
FilePrefetchBuffer * prefetch_buffer , InternalIterator * meta_iter ,
FilePrefetchBuffer * prefetch_buffer , InternalIterator * meta_iter ,
BlockBasedTable * new_table , bool prefetch_all ,
BlockBasedTable * new_table , bool prefetch_all ,
const BlockBasedTableOptions & table_options , const int level ) {
const BlockBasedTableOptions & table_options , const int level ,
BlockCacheLookupContext * lookup_context ) {
Status s ;
Status s ;
// Find filter handle and filter type
// Find filter handle and filter type
@ -1440,7 +1457,8 @@ Status BlockBasedTable::PrefetchIndexAndFilterBlocks(
IndexReader * index_reader = nullptr ;
IndexReader * index_reader = nullptr ;
if ( s . ok ( ) ) {
if ( s . ok ( ) ) {
s = new_table - > CreateIndexReader ( prefetch_buffer , meta_iter , use_cache ,
s = new_table - > CreateIndexReader ( prefetch_buffer , meta_iter , use_cache ,
prefetch_index , pin_index , & index_reader ) ;
prefetch_index , pin_index , & index_reader ,
lookup_context ) ;
if ( s . ok ( ) ) {
if ( s . ok ( ) ) {
assert ( index_reader ! = nullptr ) ;
assert ( index_reader ! = nullptr ) ;
rep_ - > index_reader . reset ( index_reader ) ;
rep_ - > index_reader . reset ( index_reader ) ;
@ -1467,7 +1485,9 @@ Status BlockBasedTable::PrefetchIndexAndFilterBlocks(
if ( s . ok ( ) & & prefetch_filter ) {
if ( s . ok ( ) & & prefetch_filter ) {
// Hack: Call GetFilter() to implicitly add filter to the block_cache
// Hack: Call GetFilter() to implicitly add filter to the block_cache
auto filter_entry =
auto filter_entry =
new_table - > GetFilter ( rep_ - > table_prefix_extractor . get ( ) ) ;
new_table - > GetFilter ( rep_ - > table_prefix_extractor . get ( ) ,
/*prefetch_buffer=*/ nullptr , /*no_io=*/ false ,
/*get_context=*/ nullptr , lookup_context ) ;
if ( filter_entry . GetValue ( ) ! = nullptr & & prefetch_all ) {
if ( filter_entry . GetValue ( ) ! = nullptr & & prefetch_all ) {
filter_entry . GetValue ( ) - > CacheDependencies (
filter_entry . GetValue ( ) - > CacheDependencies (
pin_all , rep_ - > table_prefix_extractor . get ( ) ) ;
pin_all , rep_ - > table_prefix_extractor . get ( ) ) ;
@ -1653,8 +1673,7 @@ Status BlockBasedTable::GetDataBlockFromCache(
size_t charge = block_holder - > ApproximateMemoryUsage ( ) ;
size_t charge = block_holder - > ApproximateMemoryUsage ( ) ;
Cache : : Handle * cache_handle = nullptr ;
Cache : : Handle * cache_handle = nullptr ;
s = block_cache - > Insert ( block_cache_key , block_holder . get ( ) , charge ,
s = block_cache - > Insert ( block_cache_key , block_holder . get ( ) , charge ,
& DeleteCachedEntry < Block > ,
& DeleteCachedEntry < Block > , & cache_handle ) ;
& cache_handle ) ;
# ifndef NDEBUG
# ifndef NDEBUG
block_cache - > TEST_mark_as_data_block ( block_cache_key , charge ) ;
block_cache - > TEST_mark_as_data_block ( block_cache_key , charge ) ;
# endif // NDEBUG
# endif // NDEBUG
@ -1758,8 +1777,7 @@ Status BlockBasedTable::PutDataBlockToCache(
size_t charge = block_holder - > ApproximateMemoryUsage ( ) ;
size_t charge = block_holder - > ApproximateMemoryUsage ( ) ;
Cache : : Handle * cache_handle = nullptr ;
Cache : : Handle * cache_handle = nullptr ;
s = block_cache - > Insert ( block_cache_key , block_holder . get ( ) , charge ,
s = block_cache - > Insert ( block_cache_key , block_holder . get ( ) , charge ,
& DeleteCachedEntry < Block > ,
& DeleteCachedEntry < Block > , & cache_handle , priority ) ;
& cache_handle , priority ) ;
# ifndef NDEBUG
# ifndef NDEBUG
block_cache - > TEST_mark_as_data_block ( block_cache_key , charge ) ;
block_cache - > TEST_mark_as_data_block ( block_cache_key , charge ) ;
# endif // NDEBUG
# endif // NDEBUG
@ -1849,25 +1867,28 @@ FilterBlockReader* BlockBasedTable::ReadFilter(
CachableEntry < FilterBlockReader > BlockBasedTable : : GetFilter (
CachableEntry < FilterBlockReader > BlockBasedTable : : GetFilter (
const SliceTransform * prefix_extractor , FilePrefetchBuffer * prefetch_buffer ,
const SliceTransform * prefix_extractor , FilePrefetchBuffer * prefetch_buffer ,
bool no_io , GetContext * get_context ) const {
bool no_io , GetContext * get_context ,
BlockCacheLookupContext * lookup_context ) const {
const BlockHandle & filter_blk_handle = rep_ - > filter_handle ;
const BlockHandle & filter_blk_handle = rep_ - > filter_handle ;
const bool is_a_filter_partition = true ;
const bool is_a_filter_partition = true ;
return GetFilter ( prefetch_buffer , filter_blk_handle , ! is_a_filter_partition ,
return GetFilter ( prefetch_buffer , filter_blk_handle , ! is_a_filter_partition ,
no_io , get_context , prefix_extractor ) ;
no_io , get_context , lookup_context , prefix_extractor ) ;
}
}
CachableEntry < FilterBlockReader > BlockBasedTable : : GetFilter (
CachableEntry < FilterBlockReader > BlockBasedTable : : GetFilter (
FilePrefetchBuffer * prefetch_buffer , const BlockHandle & filter_blk_handle ,
FilePrefetchBuffer * prefetch_buffer , const BlockHandle & filter_blk_handle ,
const bool is_a_filter_partition , bool no_io , GetContext * get_context ,
const bool is_a_filter_partition , bool no_io , GetContext * get_context ,
BlockCacheLookupContext * /*lookup_context*/ ,
const SliceTransform * prefix_extractor ) const {
const SliceTransform * prefix_extractor ) const {
// TODO(haoyu): Trace filter block access here.
// If cache_index_and_filter_blocks is false, filter should be pre-populated.
// If cache_index_and_filter_blocks is false, filter should be pre-populated.
// We will return rep_->filter anyway. rep_->filter can be nullptr if filter
// We will return rep_->filter anyway. rep_->filter can be nullptr if filter
// read fails at Open() time. We don't want to reload again since it will
// read fails at Open() time. We don't want to reload again since it will
// most probably fail again.
// most probably fail again.
if ( ! is_a_filter_partition & &
if ( ! is_a_filter_partition & &
! rep_ - > table_options . cache_index_and_filter_blocks ) {
! rep_ - > table_options . cache_index_and_filter_blocks ) {
return { rep_ - > filter . get ( ) , nullptr /* cache */ ,
return { rep_ - > filter . get ( ) , /*cache=*/ nullptr , /*cache_handle=*/ nullptr ,
nullptr /* cache_handle */ , false /* own_value */ } ;
/*own_value=*/ false } ;
}
}
Cache * block_cache = rep_ - > table_options . block_cache . get ( ) ;
Cache * block_cache = rep_ - > table_options . block_cache . get ( ) ;
@ -1877,8 +1898,8 @@ CachableEntry<FilterBlockReader> BlockBasedTable::GetFilter(
}
}
if ( ! is_a_filter_partition & & rep_ - > filter_entry . IsCached ( ) ) {
if ( ! is_a_filter_partition & & rep_ - > filter_entry . IsCached ( ) ) {
return { rep_ - > filter_entry . GetValue ( ) , nullptr /* cache */ ,
return { rep_ - > filter_entry . GetValue ( ) , /*cache=*/ nullptr ,
nullptr /* cache_handle */ , false /* own_value */ } ;
/*cache_handle=*/ nullptr , /*own_value=*/ false } ;
}
}
PERF_TIMER_GUARD ( read_filter_block_nanos ) ;
PERF_TIMER_GUARD ( read_filter_block_nanos ) ;
@ -1920,12 +1941,13 @@ CachableEntry<FilterBlockReader> BlockBasedTable::GetFilter(
}
}
return { filter , cache_handle ? block_cache : nullptr , cache_handle ,
return { filter , cache_handle ? block_cache : nullptr , cache_handle ,
false /* own_value */ } ;
/*own_value=*/ false } ;
}
}
CachableEntry < UncompressionDict > BlockBasedTable : : GetUncompressionDict (
CachableEntry < UncompressionDict > BlockBasedTable : : GetUncompressionDict (
FilePrefetchBuffer * prefetch_buffer , bool no_io ,
FilePrefetchBuffer * prefetch_buffer , bool no_io , GetContext * get_context ,
GetContext * get_context ) const {
BlockCacheLookupContext * /*lookup_context*/ ) const {
// TODO(haoyu): Trace the access on the uncompression dictionary here.
if ( ! rep_ - > table_options . cache_index_and_filter_blocks ) {
if ( ! rep_ - > table_options . cache_index_and_filter_blocks ) {
// block cache is either disabled or not used for meta-blocks. In either
// block cache is either disabled or not used for meta-blocks. In either
// case, BlockBasedTableReader is the owner of the uncompression dictionary.
// case, BlockBasedTableReader is the owner of the uncompression dictionary.
@ -1987,14 +2009,16 @@ CachableEntry<UncompressionDict> BlockBasedTable::GetUncompressionDict(
// differs from the one in mutable_cf_options and index type is HashBasedIndex
// differs from the one in mutable_cf_options and index type is HashBasedIndex
InternalIteratorBase < BlockHandle > * BlockBasedTable : : NewIndexIterator (
InternalIteratorBase < BlockHandle > * BlockBasedTable : : NewIndexIterator (
const ReadOptions & read_options , bool disable_prefix_seek ,
const ReadOptions & read_options , bool disable_prefix_seek ,
IndexBlockIter * input_iter , GetContext * get_context ) const {
IndexBlockIter * input_iter , GetContext * get_context ,
BlockCacheLookupContext * lookup_context ) const {
assert ( rep_ ! = nullptr ) ;
assert ( rep_ ! = nullptr ) ;
assert ( rep_ - > index_reader ! = nullptr ) ;
assert ( rep_ - > index_reader ! = nullptr ) ;
// We don't return pinned data from index blocks, so no need
// We don't return pinned data from index blocks, so no need
// to set `block_contents_pinned`.
// to set `block_contents_pinned`.
return rep_ - > index_reader - > NewIterator ( read_options , disable_prefix_seek ,
return rep_ - > index_reader - > NewIterator ( read_options , disable_prefix_seek ,
input_iter , get_context ) ;
input_iter , get_context ,
lookup_context ) ;
}
}
// Convert an index iterator value (i.e., an encoded BlockHandle)
// Convert an index iterator value (i.e., an encoded BlockHandle)
@ -2005,7 +2029,7 @@ template <typename TBlockIter>
TBlockIter * BlockBasedTable : : NewDataBlockIterator (
TBlockIter * BlockBasedTable : : NewDataBlockIterator (
const ReadOptions & ro , const BlockHandle & handle , TBlockIter * input_iter ,
const ReadOptions & ro , const BlockHandle & handle , TBlockIter * input_iter ,
BlockType block_type , bool key_includes_seq , bool index_key_is_full ,
BlockType block_type , bool key_includes_seq , bool index_key_is_full ,
GetContext * get_context , Status s ,
GetContext * get_context , BlockCacheLookupContext * lookup_context , Status s ,
FilePrefetchBuffer * prefetch_buffer ) const {
FilePrefetchBuffer * prefetch_buffer ) const {
PERF_TIMER_GUARD ( new_table_block_iter_nanos ) ;
PERF_TIMER_GUARD ( new_table_block_iter_nanos ) ;
@ -2017,7 +2041,7 @@ TBlockIter* BlockBasedTable::NewDataBlockIterator(
const bool no_io = ( ro . read_tier = = kBlockCacheTier ) ;
const bool no_io = ( ro . read_tier = = kBlockCacheTier ) ;
auto uncompression_dict_storage =
auto uncompression_dict_storage =
GetUncompressionDict ( prefetch_buffer , no_io , get_context ) ;
GetUncompressionDict ( prefetch_buffer , no_io , get_context , lookup_context ) ;
const UncompressionDict & uncompression_dict =
const UncompressionDict & uncompression_dict =
uncompression_dict_storage . GetValue ( ) = = nullptr
uncompression_dict_storage . GetValue ( ) = = nullptr
? UncompressionDict : : GetEmptyDict ( )
? UncompressionDict : : GetEmptyDict ( )
@ -2025,7 +2049,7 @@ TBlockIter* BlockBasedTable::NewDataBlockIterator(
CachableEntry < Block > block ;
CachableEntry < Block > block ;
s = RetrieveBlock ( prefetch_buffer , ro , handle , uncompression_dict , & block ,
s = RetrieveBlock ( prefetch_buffer , ro , handle , uncompression_dict , & block ,
block_type , get_context ) ;
block_type , get_context , lookup_context ) ;
if ( ! s . ok ( ) ) {
if ( ! s . ok ( ) ) {
assert ( block . IsEmpty ( ) ) ;
assert ( block . IsEmpty ( ) ) ;
@ -2093,7 +2117,9 @@ Status BlockBasedTable::MaybeReadBlockAndLoadToCache(
FilePrefetchBuffer * prefetch_buffer , const ReadOptions & ro ,
FilePrefetchBuffer * prefetch_buffer , const ReadOptions & ro ,
const BlockHandle & handle , const UncompressionDict & uncompression_dict ,
const BlockHandle & handle , const UncompressionDict & uncompression_dict ,
CachableEntry < Block > * block_entry , BlockType block_type ,
CachableEntry < Block > * block_entry , BlockType block_type ,
GetContext * get_context ) const {
GetContext * get_context ,
BlockCacheLookupContext * /*lookup_context*/ ) const {
// TODO(haoyu): Trace data/index/range deletion block access here.
assert ( block_entry ! = nullptr ) ;
assert ( block_entry ! = nullptr ) ;
const bool no_io = ( ro . read_tier = = kBlockCacheTier ) ;
const bool no_io = ( ro . read_tier = = kBlockCacheTier ) ;
Cache * block_cache = rep_ - > table_options . block_cache . get ( ) ;
Cache * block_cache = rep_ - > table_options . block_cache . get ( ) ;
@ -2169,7 +2195,7 @@ Status BlockBasedTable::RetrieveBlock(
FilePrefetchBuffer * prefetch_buffer , const ReadOptions & ro ,
FilePrefetchBuffer * prefetch_buffer , const ReadOptions & ro ,
const BlockHandle & handle , const UncompressionDict & uncompression_dict ,
const BlockHandle & handle , const UncompressionDict & uncompression_dict ,
CachableEntry < Block > * block_entry , BlockType block_type ,
CachableEntry < Block > * block_entry , BlockType block_type ,
GetContext * get_context ) const {
GetContext * get_context , BlockCacheLookupContext * lookup_context ) const {
assert ( block_entry ) ;
assert ( block_entry ) ;
assert ( block_entry - > IsEmpty ( ) ) ;
assert ( block_entry - > IsEmpty ( ) ) ;
@ -2180,7 +2206,7 @@ Status BlockBasedTable::RetrieveBlock(
block_type ! = BlockType : : kIndex ) ) {
block_type ! = BlockType : : kIndex ) ) {
s = MaybeReadBlockAndLoadToCache ( prefetch_buffer , ro , handle ,
s = MaybeReadBlockAndLoadToCache ( prefetch_buffer , ro , handle ,
uncompression_dict , block_entry ,
uncompression_dict , block_entry ,
block_type , get_context ) ;
block_type , get_context , lookup_context ) ;
if ( ! s . ok ( ) ) {
if ( ! s . ok ( ) ) {
return s ;
return s ;
@ -2271,7 +2297,8 @@ BlockBasedTable::PartitionedIndexIteratorState::NewSecondaryIterator(
bool BlockBasedTable : : PrefixMayMatch (
bool BlockBasedTable : : PrefixMayMatch (
const Slice & internal_key , const ReadOptions & read_options ,
const Slice & internal_key , const ReadOptions & read_options ,
const SliceTransform * options_prefix_extractor ,
const SliceTransform * options_prefix_extractor ,
const bool need_upper_bound_check ) const {
const bool need_upper_bound_check ,
BlockCacheLookupContext * lookup_context ) const {
if ( ! rep_ - > filter_policy ) {
if ( ! rep_ - > filter_policy ) {
return true ;
return true ;
}
}
@ -2295,7 +2322,9 @@ bool BlockBasedTable::PrefixMayMatch(
Status s ;
Status s ;
// First, try check with full filter
// First, try check with full filter
auto filter_entry = GetFilter ( prefix_extractor ) ;
auto filter_entry =
GetFilter ( prefix_extractor , /*prefetch_buffer=*/ nullptr , /*no_io=*/ false ,
/*get_context=*/ nullptr , lookup_context ) ;
FilterBlockReader * filter = filter_entry . GetValue ( ) ;
FilterBlockReader * filter = filter_entry . GetValue ( ) ;
bool filter_checked = true ;
bool filter_checked = true ;
if ( filter ! = nullptr ) {
if ( filter ! = nullptr ) {
@ -2304,7 +2333,7 @@ bool BlockBasedTable::PrefixMayMatch(
may_match = filter - > RangeMayExist (
may_match = filter - > RangeMayExist (
read_options . iterate_upper_bound , user_key , prefix_extractor ,
read_options . iterate_upper_bound , user_key , prefix_extractor ,
rep_ - > internal_comparator . user_comparator ( ) , const_ikey_ptr ,
rep_ - > internal_comparator . user_comparator ( ) , const_ikey_ptr ,
& filter_checked , need_upper_bound_check ) ;
& filter_checked , need_upper_bound_check , lookup_context ) ;
} else {
} else {
// if prefix_extractor changed for block based filter, skip filter
// if prefix_extractor changed for block based filter, skip filter
if ( need_upper_bound_check ) {
if ( need_upper_bound_check ) {
@ -2323,9 +2352,10 @@ bool BlockBasedTable::PrefixMayMatch(
// Then, try find it within each block
// Then, try find it within each block
// we already know prefix_extractor and prefix_extractor_name must match
// we already know prefix_extractor and prefix_extractor_name must match
// because `CheckPrefixMayMatch` first checks `check_filter_ == true`
// because `CheckPrefixMayMatch` first checks `check_filter_ == true`
std : : unique_ptr < InternalIteratorBase < BlockHandle > > iiter (
std : : unique_ptr < InternalIteratorBase < BlockHandle > > iiter ( NewIndexIterator (
NewIndexIterator ( no_io_read_options ,
no_io_read_options ,
/* need_upper_bound_check */ false ) ) ;
/*need_upper_bound_check=*/ false , /*input_iter=*/ nullptr ,
/*need_upper_bound_check=*/ nullptr , lookup_context ) ) ;
iiter - > Seek ( internal_prefix ) ;
iiter - > Seek ( internal_prefix ) ;
if ( ! iiter - > Valid ( ) ) {
if ( ! iiter - > Valid ( ) ) {
@ -2357,8 +2387,9 @@ bool BlockBasedTable::PrefixMayMatch(
// possibly contain the key. Thus, the corresponding data block
// possibly contain the key. Thus, the corresponding data block
// is the only on could potentially contain the prefix.
// is the only on could potentially contain the prefix.
BlockHandle handle = iiter - > value ( ) ;
BlockHandle handle = iiter - > value ( ) ;
may_match =
may_match = filter - > PrefixMayMatch (
filter - > PrefixMayMatch ( prefix , prefix_extractor , handle . offset ( ) ) ;
prefix , prefix_extractor , handle . offset ( ) , /*no_io=*/ false ,
/*const_key_ptr=*/ nullptr , lookup_context ) ;
}
}
}
}
}
}
@ -2588,7 +2619,7 @@ void BlockBasedTableIterator<TBlockIter, TValue>::InitDataBlock() {
table_ - > NewDataBlockIterator < TBlockIter > (
table_ - > NewDataBlockIterator < TBlockIter > (
read_options_ , data_block_handle , & block_iter_ , block_type_ ,
read_options_ , data_block_handle , & block_iter_ , block_type_ ,
key_includes_seq_ , index_key_is_full_ ,
key_includes_seq_ , index_key_is_full_ ,
/* get_context */ nullptr , s , prefetch_buffer_ . get ( ) ) ;
/*get_context=*/ nullptr , & lookup_context_ , s , prefetch_buffer_ . get ( ) ) ;
block_iter_points_to_real_block_ = true ;
block_iter_points_to_real_block_ = true ;
if ( read_options_ . iterate_upper_bound ! = nullptr ) {
if ( read_options_ . iterate_upper_bound ! = nullptr ) {
data_block_within_upper_bound_ =
data_block_within_upper_bound_ =
@ -2682,6 +2713,9 @@ void BlockBasedTableIterator<TBlockIter, TValue>::CheckOutOfBound() {
InternalIterator * BlockBasedTable : : NewIterator (
InternalIterator * BlockBasedTable : : NewIterator (
const ReadOptions & read_options , const SliceTransform * prefix_extractor ,
const ReadOptions & read_options , const SliceTransform * prefix_extractor ,
Arena * arena , bool skip_filters , bool for_compaction ) {
Arena * arena , bool skip_filters , bool for_compaction ) {
BlockCacheLookupContext lookup_context {
for_compaction ? BlockCacheLookupCaller : : kCompaction
: BlockCacheLookupCaller : : kUserIterator } ;
bool need_upper_bound_check =
bool need_upper_bound_check =
PrefixExtractorChanged ( rep_ - > table_properties . get ( ) , prefix_extractor ) ;
PrefixExtractorChanged ( rep_ - > table_properties . get ( ) , prefix_extractor ) ;
if ( arena = = nullptr ) {
if ( arena = = nullptr ) {
@ -2690,7 +2724,8 @@ InternalIterator* BlockBasedTable::NewIterator(
NewIndexIterator (
NewIndexIterator (
read_options ,
read_options ,
need_upper_bound_check & &
need_upper_bound_check & &
rep_ - > index_type = = BlockBasedTableOptions : : kHashSearch ) ,
rep_ - > index_type = = BlockBasedTableOptions : : kHashSearch ,
/*input_iter=*/ nullptr , /*get_context=*/ nullptr , & lookup_context ) ,
! skip_filters & & ! read_options . total_order_seek & &
! skip_filters & & ! read_options . total_order_seek & &
prefix_extractor ! = nullptr ,
prefix_extractor ! = nullptr ,
need_upper_bound_check , prefix_extractor , BlockType : : kData ,
need_upper_bound_check , prefix_extractor , BlockType : : kData ,
@ -2700,7 +2735,9 @@ InternalIterator* BlockBasedTable::NewIterator(
arena - > AllocateAligned ( sizeof ( BlockBasedTableIterator < DataBlockIter > ) ) ;
arena - > AllocateAligned ( sizeof ( BlockBasedTableIterator < DataBlockIter > ) ) ;
return new ( mem ) BlockBasedTableIterator < DataBlockIter > (
return new ( mem ) BlockBasedTableIterator < DataBlockIter > (
this , read_options , rep_ - > internal_comparator ,
this , read_options , rep_ - > internal_comparator ,
NewIndexIterator ( read_options , need_upper_bound_check ) ,
NewIndexIterator ( read_options , need_upper_bound_check ,
/*input_iter=*/ nullptr , /*get_context=*/ nullptr ,
& lookup_context ) ,
! skip_filters & & ! read_options . total_order_seek & &
! skip_filters & & ! read_options . total_order_seek & &
prefix_extractor ! = nullptr ,
prefix_extractor ! = nullptr ,
need_upper_bound_check , prefix_extractor , BlockType : : kData ,
need_upper_bound_check , prefix_extractor , BlockType : : kData ,
@ -2724,7 +2761,8 @@ FragmentedRangeTombstoneIterator* BlockBasedTable::NewRangeTombstoneIterator(
bool BlockBasedTable : : FullFilterKeyMayMatch (
bool BlockBasedTable : : FullFilterKeyMayMatch (
const ReadOptions & read_options , FilterBlockReader * filter ,
const ReadOptions & read_options , FilterBlockReader * filter ,
const Slice & internal_key , const bool no_io ,
const Slice & internal_key , const bool no_io ,
const SliceTransform * prefix_extractor ) const {
const SliceTransform * prefix_extractor ,
BlockCacheLookupContext * lookup_context ) const {
if ( filter = = nullptr | | filter - > IsBlockBased ( ) ) {
if ( filter = = nullptr | | filter - > IsBlockBased ( ) ) {
return true ;
return true ;
}
}
@ -2735,15 +2773,16 @@ bool BlockBasedTable::FullFilterKeyMayMatch(
size_t ts_sz =
size_t ts_sz =
rep_ - > internal_comparator . user_comparator ( ) - > timestamp_size ( ) ;
rep_ - > internal_comparator . user_comparator ( ) - > timestamp_size ( ) ;
Slice user_key_without_ts = StripTimestampFromUserKey ( user_key , ts_sz ) ;
Slice user_key_without_ts = StripTimestampFromUserKey ( user_key , ts_sz ) ;
may_match = filter - > KeyMayMatch ( user_key_without_ts , prefix_extractor ,
may_match =
kNotValid , no_io , const_ikey_ptr ) ;
filter - > KeyMayMatch ( user_key_without_ts , prefix_extractor , kNotValid ,
no_io , const_ikey_ptr , lookup_context ) ;
} else if ( ! read_options . total_order_seek & & prefix_extractor & &
} else if ( ! read_options . total_order_seek & & prefix_extractor & &
rep_ - > table_properties - > prefix_extractor_name . compare (
rep_ - > table_properties - > prefix_extractor_name . compare (
prefix_extractor - > Name ( ) ) = = 0 & &
prefix_extractor - > Name ( ) ) = = 0 & &
prefix_extractor - > InDomain ( user_key ) & &
prefix_extractor - > InDomain ( user_key ) & &
! filter - > PrefixMayMatch ( prefix_extractor - > Transform ( user_key ) ,
! filter - > PrefixMayMatch ( prefix_extractor - > Transform ( user_key ) ,
prefix_extractor , kNotValid , false ,
prefix_extractor , kNotValid , false ,
const_ikey_ptr ) ) {
const_ikey_ptr , lookup_context ) ) {
may_match = false ;
may_match = false ;
}
}
if ( may_match ) {
if ( may_match ) {
@ -2756,12 +2795,14 @@ bool BlockBasedTable::FullFilterKeyMayMatch(
void BlockBasedTable : : FullFilterKeysMayMatch (
void BlockBasedTable : : FullFilterKeysMayMatch (
const ReadOptions & read_options , FilterBlockReader * filter ,
const ReadOptions & read_options , FilterBlockReader * filter ,
MultiGetRange * range , const bool no_io ,
MultiGetRange * range , const bool no_io ,
const SliceTransform * prefix_extractor ) const {
const SliceTransform * prefix_extractor ,
BlockCacheLookupContext * lookup_context ) const {
if ( filter = = nullptr | | filter - > IsBlockBased ( ) ) {
if ( filter = = nullptr | | filter - > IsBlockBased ( ) ) {
return ;
return ;
}
}
if ( filter - > whole_key_filtering ( ) ) {
if ( filter - > whole_key_filtering ( ) ) {
filter - > KeysMayMatch ( range , prefix_extractor , kNotValid , no_io ) ;
filter - > KeysMayMatch ( range , prefix_extractor , kNotValid , no_io ,
lookup_context ) ;
} else if ( ! read_options . total_order_seek & & prefix_extractor & &
} else if ( ! read_options . total_order_seek & & prefix_extractor & &
rep_ - > table_properties - > prefix_extractor_name . compare (
rep_ - > table_properties - > prefix_extractor_name . compare (
prefix_extractor - > Name ( ) ) = = 0 ) {
prefix_extractor - > Name ( ) ) = = 0 ) {
@ -2772,7 +2813,8 @@ void BlockBasedTable::FullFilterKeysMayMatch(
range - > SkipKey ( iter ) ;
range - > SkipKey ( iter ) ;
}
}
}
}
filter - > PrefixesMayMatch ( range , prefix_extractor , kNotValid , false ) ;
filter - > PrefixesMayMatch ( range , prefix_extractor , kNotValid , false ,
lookup_context ) ;
}
}
}
}
@ -2786,18 +2828,19 @@ Status BlockBasedTable::Get(const ReadOptions& read_options, const Slice& key,
CachableEntry < FilterBlockReader > filter_entry ;
CachableEntry < FilterBlockReader > filter_entry ;
bool may_match ;
bool may_match ;
FilterBlockReader * filter = nullptr ;
FilterBlockReader * filter = nullptr ;
BlockCacheLookupContext lookup_context { BlockCacheLookupCaller : : kUserGet } ;
{
{
if ( ! skip_filters ) {
if ( ! skip_filters ) {
filter_entry =
filter_entry = GetFilter ( prefix_extractor , /*prefetch_buffer=*/ nullptr ,
GetFilter ( prefix_extractor , /*prefetch_buffer*/ nullpt r,
read_options . read_tier = = kBlockCacheTie r ,
read_options . read_tier = = kBlockCacheTier , get _context) ;
get_context , & lookup _context ) ;
}
}
filter = filter_entry . GetValue ( ) ;
filter = filter_entry . GetValue ( ) ;
// First check the full filter
// First check the full filter
// If full filter not useful, Then go into each block
// If full filter not useful, Then go into each block
may_match = FullFilterKeyMayMatch ( read_options , filter , key , no_io ,
may_match = FullFilterKeyMayMatch ( read_options , filter , key , no_io ,
prefix_extractor ) ;
prefix_extractor , & lookup_context ) ;
}
}
if ( ! may_match ) {
if ( ! may_match ) {
RecordTick ( rep_ - > ioptions . statistics , BLOOM_FILTER_USEFUL ) ;
RecordTick ( rep_ - > ioptions . statistics , BLOOM_FILTER_USEFUL ) ;
@ -2811,8 +2854,9 @@ Status BlockBasedTable::Get(const ReadOptions& read_options, const Slice& key,
need_upper_bound_check = PrefixExtractorChanged (
need_upper_bound_check = PrefixExtractorChanged (
rep_ - > table_properties . get ( ) , prefix_extractor ) ;
rep_ - > table_properties . get ( ) , prefix_extractor ) ;
}
}
auto iiter = NewIndexIterator ( read_options , need_upper_bound_check ,
auto iiter =
& iiter_on_stack , get_context ) ;
NewIndexIterator ( read_options , need_upper_bound_check , & iiter_on_stack ,
get_context , & lookup_context ) ;
std : : unique_ptr < InternalIteratorBase < BlockHandle > > iiter_unique_ptr ;
std : : unique_ptr < InternalIteratorBase < BlockHandle > > iiter_unique_ptr ;
if ( iiter ! = & iiter_on_stack ) {
if ( iiter ! = & iiter_on_stack ) {
iiter_unique_ptr . reset ( iiter ) ;
iiter_unique_ptr . reset ( iiter ) ;
@ -2828,7 +2872,8 @@ Status BlockBasedTable::Get(const ReadOptions& read_options, const Slice& key,
bool not_exist_in_filter =
bool not_exist_in_filter =
filter ! = nullptr & & filter - > IsBlockBased ( ) = = true & &
filter ! = nullptr & & filter - > IsBlockBased ( ) = = true & &
! filter - > KeyMayMatch ( ExtractUserKeyAndStripTimestamp ( key , ts_sz ) ,
! filter - > KeyMayMatch ( ExtractUserKeyAndStripTimestamp ( key , ts_sz ) ,
prefix_extractor , handle . offset ( ) , no_io ) ;
prefix_extractor , handle . offset ( ) , no_io ,
/*const_ikey_ptr=*/ nullptr , & lookup_context ) ;
if ( not_exist_in_filter ) {
if ( not_exist_in_filter ) {
// Not found
// Not found
@ -2841,8 +2886,9 @@ Status BlockBasedTable::Get(const ReadOptions& read_options, const Slice& key,
DataBlockIter biter ;
DataBlockIter biter ;
NewDataBlockIterator < DataBlockIter > (
NewDataBlockIterator < DataBlockIter > (
read_options , iiter - > value ( ) , & biter , BlockType : : kData ,
read_options , iiter - > value ( ) , & biter , BlockType : : kData ,
true /* key_includes_seq */ , true /* index_key_is_full */ ,
/*key_includes_seq=*/ true ,
get_context ) ;
/*index_key_is_full=*/ true , get_context , & lookup_context ,
/*s=*/ Status ( ) , /*prefetch_buffer*/ nullptr ) ;
if ( read_options . read_tier = = kBlockCacheTier & &
if ( read_options . read_tier = = kBlockCacheTier & &
biter . status ( ) . IsIncomplete ( ) ) {
biter . status ( ) . IsIncomplete ( ) ) {
@ -2907,6 +2953,7 @@ void BlockBasedTable::MultiGet(const ReadOptions& read_options,
const MultiGetRange * mget_range ,
const MultiGetRange * mget_range ,
const SliceTransform * prefix_extractor ,
const SliceTransform * prefix_extractor ,
bool skip_filters ) {
bool skip_filters ) {
BlockCacheLookupContext lookup_context { BlockCacheLookupCaller : : kUserMGet } ;
const bool no_io = read_options . read_tier = = kBlockCacheTier ;
const bool no_io = read_options . read_tier = = kBlockCacheTier ;
CachableEntry < FilterBlockReader > filter_entry ;
CachableEntry < FilterBlockReader > filter_entry ;
FilterBlockReader * filter = nullptr ;
FilterBlockReader * filter = nullptr ;
@ -2915,16 +2962,16 @@ void BlockBasedTable::MultiGet(const ReadOptions& read_options,
{
{
if ( ! skip_filters ) {
if ( ! skip_filters ) {
// TODO: Figure out where the stats should go
// TODO: Figure out where the stats should go
filter_entry = GetFilter ( prefix_extractor , /*prefetch_buffer*/ nullptr ,
filter_entry = GetFilter ( prefix_extractor , /*prefetch_buffer= */ nullptr ,
read_options . read_tier = = kBlockCacheTier ,
read_options . read_tier = = kBlockCacheTier ,
nullptr /*get_context*/ ) ;
/*get_context=*/ nullptr , & lookup_context ) ;
}
}
filter = filter_entry . GetValue ( ) ;
filter = filter_entry . GetValue ( ) ;
// First check the full filter
// First check the full filter
// If full filter not useful, Then go into each block
// If full filter not useful, Then go into each block
FullFilterKeysMayMatch ( read_options , filter , & sst_file_range , no_io ,
FullFilterKeysMayMatch ( read_options , filter , & sst_file_range , no_io ,
prefix_extractor ) ;
prefix_extractor , & lookup_context ) ;
}
}
if ( skip_filters | | ! sst_file_range . empty ( ) ) {
if ( skip_filters | | ! sst_file_range . empty ( ) ) {
IndexBlockIter iiter_on_stack ;
IndexBlockIter iiter_on_stack ;
@ -2937,7 +2984,7 @@ void BlockBasedTable::MultiGet(const ReadOptions& read_options,
}
}
auto iiter =
auto iiter =
NewIndexIterator ( read_options , need_upper_bound_check , & iiter_on_stack ,
NewIndexIterator ( read_options , need_upper_bound_check , & iiter_on_stack ,
sst_file_range . begin ( ) - > get_context ) ;
sst_file_range . begin ( ) - > get_context , & lookup_context ) ;
std : : unique_ptr < InternalIteratorBase < BlockHandle > > iiter_unique_ptr ;
std : : unique_ptr < InternalIteratorBase < BlockHandle > > iiter_unique_ptr ;
if ( iiter ! = & iiter_on_stack ) {
if ( iiter ! = & iiter_on_stack ) {
iiter_unique_ptr . reset ( iiter ) ;
iiter_unique_ptr . reset ( iiter ) ;
@ -2958,11 +3005,12 @@ void BlockBasedTable::MultiGet(const ReadOptions& read_options,
offset = iiter - > value ( ) . offset ( ) ;
offset = iiter - > value ( ) . offset ( ) ;
biter . Invalidate ( Status : : OK ( ) ) ;
biter . Invalidate ( Status : : OK ( ) ) ;
NewDataBlockIterator < DataBlockIter > (
NewDataBlockIterator < DataBlockIter > (
read_options , iiter - > value ( ) , & biter , BlockType : : kData , false ,
read_options , iiter - > value ( ) , & biter , BlockType : : kData ,
true /* key_includes_seq */ , get_context ) ;
/*key_includes_seq=*/ false ,
/*index_key_is_full=*/ true , get_context , & lookup_context ,
Status ( ) , nullptr ) ;
reusing_block = false ;
reusing_block = false ;
}
}
if ( read_options . read_tier = = kBlockCacheTier & &
if ( read_options . read_tier = = kBlockCacheTier & &
biter . status ( ) . IsIncomplete ( ) ) {
biter . status ( ) . IsIncomplete ( ) ) {
// couldn't get block from block_cache
// couldn't get block from block_cache
@ -3040,9 +3088,11 @@ Status BlockBasedTable::Prefetch(const Slice* const begin,
if ( begin & & end & & comparator . Compare ( * begin , * end ) > 0 ) {
if ( begin & & end & & comparator . Compare ( * begin , * end ) > 0 ) {
return Status : : InvalidArgument ( * begin , * end ) ;
return Status : : InvalidArgument ( * begin , * end ) ;
}
}
BlockCacheLookupContext lookup_context { BlockCacheLookupCaller : : kPrefetch } ;
IndexBlockIter iiter_on_stack ;
IndexBlockIter iiter_on_stack ;
auto iiter = NewIndexIterator ( ReadOptions ( ) , false , & iiter_on_stack ) ;
auto iiter = NewIndexIterator ( ReadOptions ( ) , /*need_upper_bound_check=*/ false ,
& iiter_on_stack , /*get_context=*/ nullptr ,
& lookup_context ) ;
std : : unique_ptr < InternalIteratorBase < BlockHandle > > iiter_unique_ptr ;
std : : unique_ptr < InternalIteratorBase < BlockHandle > > iiter_unique_ptr ;
if ( iiter ! = & iiter_on_stack ) {
if ( iiter ! = & iiter_on_stack ) {
iiter_unique_ptr =
iiter_unique_ptr =
@ -3077,7 +3127,12 @@ Status BlockBasedTable::Prefetch(const Slice* const begin,
// Load the block specified by the block_handle into the block cache
// Load the block specified by the block_handle into the block cache
DataBlockIter biter ;
DataBlockIter biter ;
NewDataBlockIterator < DataBlockIter > ( ReadOptions ( ) , block_handle , & biter ) ;
NewDataBlockIterator < DataBlockIter > (
ReadOptions ( ) , block_handle , & biter , /*type=*/ BlockType : : kData ,
/*key_includes_seq=*/ true , /*index_key_is_full=*/ true ,
/*get_context=*/ nullptr , & lookup_context , Status ( ) ,
/*prefetch_buffer=*/ nullptr ) ;
if ( ! biter . status ( ) . ok ( ) ) {
if ( ! biter . status ( ) . ok ( ) ) {
// there was an unexpected error while pre-fetching
// there was an unexpected error while pre-fetching
@ -3089,6 +3144,8 @@ Status BlockBasedTable::Prefetch(const Slice* const begin,
}
}
Status BlockBasedTable : : VerifyChecksum ( ) {
Status BlockBasedTable : : VerifyChecksum ( ) {
// TODO(haoyu): This function is called by external sst ingestion and the
// verify checksum public API. We don't log its block cache accesses for now.
Status s ;
Status s ;
// Check Meta blocks
// Check Meta blocks
std : : unique_ptr < Block > meta ;
std : : unique_ptr < Block > meta ;
@ -3104,8 +3161,9 @@ Status BlockBasedTable::VerifyChecksum() {
}
}
// Check Data blocks
// Check Data blocks
IndexBlockIter iiter_on_stack ;
IndexBlockIter iiter_on_stack ;
InternalIteratorBase < BlockHandle > * iiter =
InternalIteratorBase < BlockHandle > * iiter = NewIndexIterator (
NewIndexIterator ( ReadOptions ( ) , false , & iiter_on_stack ) ;
ReadOptions ( ) , /*need_upper_bound_check=*/ false , & iiter_on_stack ,
/*get_context=*/ nullptr , /*lookup_contex=*/ nullptr ) ;
std : : unique_ptr < InternalIteratorBase < BlockHandle > > iiter_unique_ptr ;
std : : unique_ptr < InternalIteratorBase < BlockHandle > > iiter_unique_ptr ;
if ( iiter ! = & iiter_on_stack ) {
if ( iiter ! = & iiter_on_stack ) {
iiter_unique_ptr =
iiter_unique_ptr =
@ -3199,8 +3257,9 @@ bool BlockBasedTable::TEST_BlockInCache(const BlockHandle& handle) const {
bool BlockBasedTable : : TEST_KeyInCache ( const ReadOptions & options ,
bool BlockBasedTable : : TEST_KeyInCache ( const ReadOptions & options ,
const Slice & key ) {
const Slice & key ) {
std : : unique_ptr < InternalIteratorBase < BlockHandle > > iiter (
std : : unique_ptr < InternalIteratorBase < BlockHandle > > iiter ( NewIndexIterator (
NewIndexIterator ( options ) ) ;
options , /*need_upper_bound_check=*/ false , /*input_iter=*/ nullptr ,
/*get_context=*/ nullptr , /*lookup_contex=*/ nullptr ) ) ;
iiter - > Seek ( key ) ;
iiter - > Seek ( key ) ;
assert ( iiter - > Valid ( ) ) ;
assert ( iiter - > Valid ( ) ) ;
@ -3234,7 +3293,8 @@ BlockBasedTableOptions::IndexType BlockBasedTable::UpdateIndexType() {
Status BlockBasedTable : : CreateIndexReader (
Status BlockBasedTable : : CreateIndexReader (
FilePrefetchBuffer * prefetch_buffer ,
FilePrefetchBuffer * prefetch_buffer ,
InternalIterator * preloaded_meta_index_iter , bool use_cache , bool prefetch ,
InternalIterator * preloaded_meta_index_iter , bool use_cache , bool prefetch ,
bool pin , IndexReader * * index_reader ) {
bool pin , IndexReader * * index_reader ,
BlockCacheLookupContext * lookup_context ) {
auto index_type_on_file = rep_ - > index_type ;
auto index_type_on_file = rep_ - > index_type ;
// kHashSearch requires non-empty prefix_extractor but bypass checking
// kHashSearch requires non-empty prefix_extractor but bypass checking
@ -3246,11 +3306,13 @@ Status BlockBasedTable::CreateIndexReader(
switch ( index_type_on_file ) {
switch ( index_type_on_file ) {
case BlockBasedTableOptions : : kTwoLevelIndexSearch : {
case BlockBasedTableOptions : : kTwoLevelIndexSearch : {
return PartitionIndexReader : : Create ( this , prefetch_buffer , use_cache ,
return PartitionIndexReader : : Create ( this , prefetch_buffer , use_cache ,
prefetch , pin , index_reader ) ;
prefetch , pin , index_reader ,
lookup_context ) ;
}
}
case BlockBasedTableOptions : : kBinarySearch : {
case BlockBasedTableOptions : : kBinarySearch : {
return BinarySearchIndexReader : : Create ( this , prefetch_buffer , use_cache ,
return BinarySearchIndexReader : : Create ( this , prefetch_buffer , use_cache ,
prefetch , pin , index_reader ) ;
prefetch , pin , index_reader ,
lookup_context ) ;
}
}
case BlockBasedTableOptions : : kHashSearch : {
case BlockBasedTableOptions : : kHashSearch : {
std : : unique_ptr < Block > meta_guard ;
std : : unique_ptr < Block > meta_guard ;
@ -3264,14 +3326,16 @@ Status BlockBasedTable::CreateIndexReader(
ROCKS_LOG_WARN ( rep_ - > ioptions . info_log ,
ROCKS_LOG_WARN ( rep_ - > ioptions . info_log ,
" Unable to read the metaindex block. "
" Unable to read the metaindex block. "
" Fall back to binary search index. " ) ;
" Fall back to binary search index. " ) ;
return BinarySearchIndexReader : : Create (
return BinarySearchIndexReader : : Create ( this , prefetch_buffer ,
this , prefetch_buffer , use_cache , prefetch , pin , index_reader ) ;
use_cache , prefetch , pin ,
index_reader , lookup_context ) ;
}
}
meta_index_iter = meta_iter_guard . get ( ) ;
meta_index_iter = meta_iter_guard . get ( ) ;
}
}
return HashIndexReader : : Create ( this , prefetch_buffer , meta_index_iter ,
return HashIndexReader : : Create ( this , prefetch_buffer , meta_index_iter ,
use_cache , prefetch , pin , index_reader ) ;
use_cache , prefetch , pin , index_reader ,
lookup_context ) ;
}
}
default : {
default : {
std : : string error_message =
std : : string error_message =
@ -3281,9 +3345,15 @@ Status BlockBasedTable::CreateIndexReader(
}
}
}
}
uint64_t BlockBasedTable : : ApproximateOffsetOf ( const Slice & key ) {
uint64_t BlockBasedTable : : ApproximateOffsetOf ( const Slice & key ,
bool for_compaction ) {
BlockCacheLookupContext context (
for_compaction ? BlockCacheLookupCaller : : kCompaction
: BlockCacheLookupCaller : : kUserApproximateSize ) ;
std : : unique_ptr < InternalIteratorBase < BlockHandle > > index_iter (
std : : unique_ptr < InternalIteratorBase < BlockHandle > > index_iter (
NewIndexIterator ( ReadOptions ( ) ) ) ;
NewIndexIterator ( ReadOptions ( ) , /*need_upper_bound_check=*/ false ,
/*input_iter=*/ nullptr , /*get_context=*/ nullptr ,
/*lookup_contex=*/ & context ) ) ;
index_iter - > Seek ( key ) ;
index_iter - > Seek ( key ) ;
uint64_t result ;
uint64_t result ;
@ -3319,7 +3389,9 @@ bool BlockBasedTable::TEST_IndexBlockInCache() const {
Status BlockBasedTable : : GetKVPairsFromDataBlocks (
Status BlockBasedTable : : GetKVPairsFromDataBlocks (
std : : vector < KVPairBlock > * kv_pair_blocks ) {
std : : vector < KVPairBlock > * kv_pair_blocks ) {
std : : unique_ptr < InternalIteratorBase < BlockHandle > > blockhandles_iter (
std : : unique_ptr < InternalIteratorBase < BlockHandle > > blockhandles_iter (
NewIndexIterator ( ReadOptions ( ) ) ) ;
NewIndexIterator ( ReadOptions ( ) , /*need_upper_bound_check=*/ false ,
/*input_iter=*/ nullptr , /*get_context=*/ nullptr ,
/*lookup_contex=*/ nullptr ) ) ;
Status s = blockhandles_iter - > status ( ) ;
Status s = blockhandles_iter - > status ( ) ;
if ( ! s . ok ( ) ) {
if ( ! s . ok ( ) ) {
@ -3337,7 +3409,11 @@ Status BlockBasedTable::GetKVPairsFromDataBlocks(
std : : unique_ptr < InternalIterator > datablock_iter ;
std : : unique_ptr < InternalIterator > datablock_iter ;
datablock_iter . reset ( NewDataBlockIterator < DataBlockIter > (
datablock_iter . reset ( NewDataBlockIterator < DataBlockIter > (
ReadOptions ( ) , blockhandles_iter - > value ( ) ) ) ;
ReadOptions ( ) , blockhandles_iter - > value ( ) , /*input_iter=*/ nullptr ,
/*type=*/ BlockType : : kData ,
/*key_includes_seq=*/ true , /*index_key_is_full=*/ true ,
/*get_context=*/ nullptr , /*lookup_context=*/ nullptr , Status ( ) ,
/*prefetch_buffer=*/ nullptr ) ) ;
s = datablock_iter - > status ( ) ;
s = datablock_iter - > status ( ) ;
if ( ! s . ok ( ) ) {
if ( ! s . ok ( ) ) {
@ -3545,7 +3621,9 @@ Status BlockBasedTable::DumpIndexBlock(WritableFile* out_file) {
" Index Details: \n "
" Index Details: \n "
" -------------------------------------- \n " ) ;
" -------------------------------------- \n " ) ;
std : : unique_ptr < InternalIteratorBase < BlockHandle > > blockhandles_iter (
std : : unique_ptr < InternalIteratorBase < BlockHandle > > blockhandles_iter (
NewIndexIterator ( ReadOptions ( ) ) ) ;
NewIndexIterator ( ReadOptions ( ) , /*need_upper_bound_check=*/ false ,
/*input_iter=*/ nullptr , /*get_context=*/ nullptr ,
/*lookup_contex=*/ nullptr ) ) ;
Status s = blockhandles_iter - > status ( ) ;
Status s = blockhandles_iter - > status ( ) ;
if ( ! s . ok ( ) ) {
if ( ! s . ok ( ) ) {
out_file - > Append ( " Can not read Index Block \n \n " ) ;
out_file - > Append ( " Can not read Index Block \n \n " ) ;
@ -3594,7 +3672,9 @@ Status BlockBasedTable::DumpIndexBlock(WritableFile* out_file) {
Status BlockBasedTable : : DumpDataBlocks ( WritableFile * out_file ) {
Status BlockBasedTable : : DumpDataBlocks ( WritableFile * out_file ) {
std : : unique_ptr < InternalIteratorBase < BlockHandle > > blockhandles_iter (
std : : unique_ptr < InternalIteratorBase < BlockHandle > > blockhandles_iter (
NewIndexIterator ( ReadOptions ( ) ) ) ;
NewIndexIterator ( ReadOptions ( ) , /*need_upper_bound_check=*/ false ,
/*input_iter=*/ nullptr , /*get_context=*/ nullptr ,
/*lookup_contex=*/ nullptr ) ) ;
Status s = blockhandles_iter - > status ( ) ;
Status s = blockhandles_iter - > status ( ) ;
if ( ! s . ok ( ) ) {
if ( ! s . ok ( ) ) {
out_file - > Append ( " Can not read Index Block \n \n " ) ;
out_file - > Append ( " Can not read Index Block \n \n " ) ;
@ -3628,7 +3708,11 @@ Status BlockBasedTable::DumpDataBlocks(WritableFile* out_file) {
std : : unique_ptr < InternalIterator > datablock_iter ;
std : : unique_ptr < InternalIterator > datablock_iter ;
datablock_iter . reset ( NewDataBlockIterator < DataBlockIter > (
datablock_iter . reset ( NewDataBlockIterator < DataBlockIter > (
ReadOptions ( ) , blockhandles_iter - > value ( ) ) ) ;
ReadOptions ( ) , blockhandles_iter - > value ( ) , /*input_iter=*/ nullptr ,
/*type=*/ BlockType : : kData ,
/*key_includes_seq=*/ true , /*index_key_is_full=*/ true ,
/*get_context=*/ nullptr , /*lookup_context=*/ nullptr , Status ( ) ,
/*prefetch_buffer=*/ nullptr ) ) ;
s = datablock_iter - > status ( ) ;
s = datablock_iter - > status ( ) ;
if ( ! s . ok ( ) ) {
if ( ! s . ok ( ) ) {