@ -72,6 +72,57 @@ BlockBasedTable::~BlockBasedTable() {
std : : atomic < uint64_t > BlockBasedTable : : next_cache_key_id_ ( 0 ) ;
std : : atomic < uint64_t > BlockBasedTable : : next_cache_key_id_ ( 0 ) ;
template < typename TBlocklike >
class BlocklikeTraits ;
template < >
class BlocklikeTraits < BlockContents > {
public :
static BlockContents * Create ( BlockContents & & contents ,
SequenceNumber /* global_seqno */ ,
size_t /* read_amp_bytes_per_bit */ ,
Statistics * /* statistics */ ,
bool /* using_zstd */ ) {
return new BlockContents ( std : : move ( contents ) ) ;
}
static uint32_t GetNumRestarts ( const BlockContents & /* contents */ ) {
return 0 ;
}
} ;
template < >
class BlocklikeTraits < Block > {
public :
static Block * Create ( BlockContents & & contents , SequenceNumber global_seqno ,
size_t read_amp_bytes_per_bit , Statistics * statistics ,
bool /* using_zstd */ ) {
return new Block ( std : : move ( contents ) , global_seqno , read_amp_bytes_per_bit ,
statistics ) ;
}
static uint32_t GetNumRestarts ( const Block & block ) {
return block . NumRestarts ( ) ;
}
} ;
template < >
class BlocklikeTraits < UncompressionDict > {
public :
static UncompressionDict * Create ( BlockContents & & contents ,
SequenceNumber /* global_seqno */ ,
size_t /* read_amp_bytes_per_bit */ ,
Statistics * /* statistics */ ,
bool using_zstd ) {
return new UncompressionDict ( contents . data , std : : move ( contents . allocation ) ,
using_zstd ) ;
}
static uint32_t GetNumRestarts ( const UncompressionDict & /* dict */ ) {
return 0 ;
}
} ;
namespace {
namespace {
// Read the block identified by "handle" from "file".
// Read the block identified by "handle" from "file".
// The only relevant option is options.verify_checksums for now.
// The only relevant option is options.verify_checksums for now.
@ -79,15 +130,16 @@ namespace {
// On success fill *result and return OK - caller owns *result
// On success fill *result and return OK - caller owns *result
// @param uncompression_dict Data for presetting the compression library's
// @param uncompression_dict Data for presetting the compression library's
// dictionary.
// dictionary.
template < typename TBlocklike >
Status ReadBlockFromFile (
Status ReadBlockFromFile (
RandomAccessFileReader * file , FilePrefetchBuffer * prefetch_buffer ,
RandomAccessFileReader * file , FilePrefetchBuffer * prefetch_buffer ,
const Footer & footer , const ReadOptions & options , const BlockHandle & handle ,
const Footer & footer , const ReadOptions & options , const BlockHandle & handle ,
std : : unique_ptr < Block > * result , const ImmutableCFOptions & ioptions ,
std : : unique_ptr < T Blocklike > * result , const ImmutableCFOptions & ioptions ,
bool do_uncompress , bool maybe_compressed , BlockType block_type ,
bool do_uncompress , bool maybe_compressed , BlockType block_type ,
const UncompressionDict & uncompression_dict ,
const UncompressionDict & uncompression_dict ,
const PersistentCacheOptions & cache_options , SequenceNumber global_seqno ,
const PersistentCacheOptions & cache_options , SequenceNumber global_seqno ,
size_t read_amp_bytes_per_bit , MemoryAllocator * memory_allocator ,
size_t read_amp_bytes_per_bit , MemoryAllocator * memory_allocator ,
bool for_compaction = false ) {
bool for_compaction , bool using_zstd ) {
assert ( result ) ;
assert ( result ) ;
BlockContents contents ;
BlockContents contents ;
@ -97,34 +149,9 @@ Status ReadBlockFromFile(
cache_options , memory_allocator , nullptr , for_compaction ) ;
cache_options , memory_allocator , nullptr , for_compaction ) ;
Status s = block_fetcher . ReadBlockContents ( ) ;
Status s = block_fetcher . ReadBlockContents ( ) ;
if ( s . ok ( ) ) {
if ( s . ok ( ) ) {
result - > reset ( new Block ( std : : move ( contents ) , global_seqno ,
result - > reset ( BlocklikeTraits < TBlocklike > : : Create (
read_amp_bytes_per_bit , ioptions . statistics ) ) ;
std : : move ( contents ) , global_seqno , read_amp_bytes_per_bit ,
}
ioptions . statistics , using_zstd ) ) ;
return s ;
}
Status ReadBlockFromFile (
RandomAccessFileReader * file , FilePrefetchBuffer * prefetch_buffer ,
const Footer & footer , const ReadOptions & options , const BlockHandle & handle ,
std : : unique_ptr < BlockContents > * result , const ImmutableCFOptions & ioptions ,
bool do_uncompress , bool maybe_compressed , BlockType block_type ,
const UncompressionDict & uncompression_dict ,
const PersistentCacheOptions & cache_options ,
SequenceNumber /* global_seqno */ , size_t /* read_amp_bytes_per_bit */ ,
MemoryAllocator * memory_allocator , bool for_compaction = false ) {
assert ( result ) ;
result - > reset ( new BlockContents ) ;
BlockFetcher block_fetcher (
file , prefetch_buffer , footer , options , handle , result - > get ( ) , ioptions ,
do_uncompress , maybe_compressed , block_type , uncompression_dict ,
cache_options , memory_allocator , nullptr , for_compaction ) ;
const Status s = block_fetcher . ReadBlockContents ( ) ;
if ( ! s . ok ( ) ) {
result - > reset ( ) ;
}
}
return s ;
return s ;
@ -1599,7 +1626,8 @@ Status BlockBasedTable::ReadMetaBlock(FilePrefetchBuffer* prefetch_buffer,
true /* decompress */ , true /*maybe_compressed*/ , BlockType : : kMetaIndex ,
true /* decompress */ , true /*maybe_compressed*/ , BlockType : : kMetaIndex ,
UncompressionDict : : GetEmptyDict ( ) , rep_ - > persistent_cache_options ,
UncompressionDict : : GetEmptyDict ( ) , rep_ - > persistent_cache_options ,
kDisableGlobalSequenceNumber , 0 /* read_amp_bytes_per_bit */ ,
kDisableGlobalSequenceNumber , 0 /* read_amp_bytes_per_bit */ ,
GetMemoryAllocator ( rep_ - > table_options ) ) ;
GetMemoryAllocator ( rep_ - > table_options ) , false /* for_compaction */ ,
rep_ - > blocks_definitely_zstd_compressed ) ;
if ( ! s . ok ( ) ) {
if ( ! s . ok ( ) ) {
ROCKS_LOG_ERROR ( rep_ - > ioptions . info_log ,
ROCKS_LOG_ERROR ( rep_ - > ioptions . info_log ,
@ -1616,38 +1644,6 @@ Status BlockBasedTable::ReadMetaBlock(FilePrefetchBuffer* prefetch_buffer,
return Status : : OK ( ) ;
return Status : : OK ( ) ;
}
}
template < typename TBlocklike >
class BlocklikeTraits ;
template < >
class BlocklikeTraits < BlockContents > {
public :
static BlockContents * Create ( BlockContents & & contents ,
SequenceNumber /* global_seqno */ ,
size_t /* read_amp_bytes_per_bit */ ,
Statistics * /* statistics */ ) {
return new BlockContents ( std : : move ( contents ) ) ;
}
static uint32_t GetNumRestarts ( const BlockContents & /* contents */ ) {
return 0 ;
}
} ;
template < >
class BlocklikeTraits < Block > {
public :
static Block * Create ( BlockContents & & contents , SequenceNumber global_seqno ,
size_t read_amp_bytes_per_bit , Statistics * statistics ) {
return new Block ( std : : move ( contents ) , global_seqno , read_amp_bytes_per_bit ,
statistics ) ;
}
static uint32_t GetNumRestarts ( const Block & block ) {
return block . NumRestarts ( ) ;
}
} ;
template < typename TBlocklike >
template < typename TBlocklike >
Status BlockBasedTable : : GetDataBlockFromCache (
Status BlockBasedTable : : GetDataBlockFromCache (
const Slice & block_cache_key , const Slice & compressed_block_cache_key ,
const Slice & block_cache_key , const Slice & compressed_block_cache_key ,
@ -1719,7 +1715,8 @@ Status BlockBasedTable::GetDataBlockFromCache(
std : : unique_ptr < TBlocklike > block_holder (
std : : unique_ptr < TBlocklike > block_holder (
BlocklikeTraits < TBlocklike > : : Create (
BlocklikeTraits < TBlocklike > : : Create (
std : : move ( contents ) , rep_ - > get_global_seqno ( block_type ) ,
std : : move ( contents ) , rep_ - > get_global_seqno ( block_type ) ,
read_amp_bytes_per_bit , statistics ) ) ; // uncompressed block
read_amp_bytes_per_bit , statistics ,
rep_ - > blocks_definitely_zstd_compressed ) ) ; // uncompressed block
if ( block_cache ! = nullptr & & block_holder - > own_bytes ( ) & &
if ( block_cache ! = nullptr & & block_holder - > own_bytes ( ) & &
read_options . fill_cache ) {
read_options . fill_cache ) {
@ -1790,11 +1787,11 @@ Status BlockBasedTable::PutDataBlockToCache(
block_holder . reset ( BlocklikeTraits < TBlocklike > : : Create (
block_holder . reset ( BlocklikeTraits < TBlocklike > : : Create (
std : : move ( uncompressed_block_contents ) , seq_no , read_amp_bytes_per_bit ,
std : : move ( uncompressed_block_contents ) , seq_no , read_amp_bytes_per_bit ,
statistics ) ) ;
statistics , rep_ - > blocks_definitely_zstd_compressed ) ) ;
} else {
} else {
block_holder . reset ( BlocklikeTraits < TBlocklike > : : Create (
block_holder . reset ( BlocklikeTraits < TBlocklike > : : Create (
std : : move ( * raw_block_contents ) , seq_no , read_amp_bytes_per_bit ,
std : : move ( * raw_block_contents ) , seq_no , read_amp_bytes_per_bit ,
statistics ) ) ;
statistics , rep_ - > blocks_definitely_zstd_compressed ) ) ;
}
}
// Insert compressed block into compressed block cache.
// Insert compressed block into compressed block cache.
@ -1912,7 +1909,7 @@ TBlockIter* BlockBasedTable::NewDataBlockIterator(
return iter ;
return iter ;
}
}
UncompressionDict uncompression_dict ;
CachableEntry < UncompressionDict > uncompression_dict ;
if ( rep_ - > uncompression_dict_reader ) {
if ( rep_ - > uncompression_dict_reader ) {
const bool no_io = ( ro . read_tier = = kBlockCacheTier ) ;
const bool no_io = ( ro . read_tier = = kBlockCacheTier ) ;
s = rep_ - > uncompression_dict_reader - > GetOrReadUncompressionDictionary (
s = rep_ - > uncompression_dict_reader - > GetOrReadUncompressionDictionary (
@ -1924,9 +1921,13 @@ TBlockIter* BlockBasedTable::NewDataBlockIterator(
}
}
}
}
const UncompressionDict & dict = uncompression_dict . GetValue ( )
? * uncompression_dict . GetValue ( )
: UncompressionDict : : GetEmptyDict ( ) ;
CachableEntry < Block > block ;
CachableEntry < Block > block ;
s = RetrieveBlock ( prefetch_buffer , ro , handle , uncompression_dict , & block ,
s = RetrieveBlock ( prefetch_buffer , ro , handle , dict , & block , block_type ,
block_type , get_context , lookup_context , for_compaction ,
get_context , lookup_context , for_compaction ,
/* use_cache */ true ) ;
/* use_cache */ true ) ;
if ( ! s . ok ( ) ) {
if ( ! s . ok ( ) ) {
@ -2255,15 +2256,11 @@ Status BlockBasedTable::MaybeReadBlockAndLoadToCache(
// handles - A vector of block handles. Some of them me be NULL handles
// handles - A vector of block handles. Some of them me be NULL handles
// scratch - An optional contiguous buffer to read compressed blocks into
// scratch - An optional contiguous buffer to read compressed blocks into
void BlockBasedTable : : RetrieveMultipleBlocks (
void BlockBasedTable : : RetrieveMultipleBlocks (
const ReadOptions & options ,
const ReadOptions & options , const MultiGetRange * batch ,
const MultiGetRange * batch ,
const autovector < BlockHandle , MultiGetContext : : MAX_BATCH_SIZE > * handles ,
const autovector < BlockHandle , MultiGetContext : : MAX_BATCH_SIZE > * handles ,
autovector < Status , MultiGetContext : : MAX_BATCH_SIZE > * statuses ,
autovector < Status , MultiGetContext : : MAX_BATCH_SIZE > * statuses ,
autovector <
autovector < CachableEntry < Block > , MultiGetContext : : MAX_BATCH_SIZE > * results ,
CachableEntry < Block > , MultiGetContext : : MAX_BATCH_SIZE > * results ,
char * scratch , const UncompressionDict & uncompression_dict ) const {
char * scratch ,
const UncompressionDict & uncompression_dict ) const {
RandomAccessFileReader * file = rep_ - > file . get ( ) ;
RandomAccessFileReader * file = rep_ - > file . get ( ) ;
const Footer & footer = rep_ - > footer ;
const Footer & footer = rep_ - > footer ;
const ImmutableCFOptions & ioptions = rep_ - > ioptions ;
const ImmutableCFOptions & ioptions = rep_ - > ioptions ;
@ -2459,7 +2456,8 @@ Status BlockBasedTable::RetrieveBlock(
block_type = = BlockType : : kData
block_type = = BlockType : : kData
? rep_ - > table_options . read_amp_bytes_per_bit
? rep_ - > table_options . read_amp_bytes_per_bit
: 0 ,
: 0 ,
GetMemoryAllocator ( rep_ - > table_options ) , for_compaction ) ;
GetMemoryAllocator ( rep_ - > table_options ) , for_compaction ,
rep_ - > blocks_definitely_zstd_compressed ) ;
}
}
if ( ! s . ok ( ) ) {
if ( ! s . ok ( ) ) {
@ -2488,6 +2486,13 @@ template Status BlockBasedTable::RetrieveBlock<Block>(
GetContext * get_context , BlockCacheLookupContext * lookup_context ,
GetContext * get_context , BlockCacheLookupContext * lookup_context ,
bool for_compaction , bool use_cache ) const ;
bool for_compaction , bool use_cache ) const ;
template Status BlockBasedTable : : RetrieveBlock < UncompressionDict > (
FilePrefetchBuffer * prefetch_buffer , const ReadOptions & ro ,
const BlockHandle & handle , const UncompressionDict & uncompression_dict ,
CachableEntry < UncompressionDict > * block_entry , BlockType block_type ,
GetContext * get_context , BlockCacheLookupContext * lookup_context ,
bool for_compaction , bool use_cache ) const ;
BlockBasedTable : : PartitionedIndexIteratorState : : PartitionedIndexIteratorState (
BlockBasedTable : : PartitionedIndexIteratorState : : PartitionedIndexIteratorState (
const BlockBasedTable * table ,
const BlockBasedTable * table ,
std : : unordered_map < uint64_t , CachableEntry < Block > > * block_map )
std : : unordered_map < uint64_t , CachableEntry < Block > > * block_map )
@ -3369,7 +3374,7 @@ void BlockBasedTable::MultiGet(const ReadOptions& read_options,
MultiGetRange data_block_range ( sst_file_range , sst_file_range . begin ( ) ,
MultiGetRange data_block_range ( sst_file_range , sst_file_range . begin ( ) ,
sst_file_range . end ( ) ) ;
sst_file_range . end ( ) ) ;
UncompressionDict uncompression_dict ;
CachableEntry < UncompressionDict > uncompression_dict ;
Status uncompression_dict_status ;
Status uncompression_dict_status ;
if ( rep_ - > uncompression_dict_reader ) {
if ( rep_ - > uncompression_dict_reader ) {
uncompression_dict_status =
uncompression_dict_status =
@ -3379,6 +3384,10 @@ void BlockBasedTable::MultiGet(const ReadOptions& read_options,
& uncompression_dict ) ;
& uncompression_dict ) ;
}
}
const UncompressionDict & dict = uncompression_dict . GetValue ( )
? * uncompression_dict . GetValue ( )
: UncompressionDict : : GetEmptyDict ( ) ;
size_t total_len = 0 ;
size_t total_len = 0 ;
ReadOptions ro = read_options ;
ReadOptions ro = read_options ;
ro . read_tier = kBlockCacheTier ;
ro . read_tier = kBlockCacheTier ;
@ -3427,10 +3436,10 @@ void BlockBasedTable::MultiGet(const ReadOptions& read_options,
BlockHandle handle = v . handle ;
BlockHandle handle = v . handle ;
BlockCacheLookupContext lookup_data_block_context (
BlockCacheLookupContext lookup_data_block_context (
TableReaderCaller : : kUserMultiGet ) ;
TableReaderCaller : : kUserMultiGet ) ;
Status s = RetrieveBlock ( nullptr , ro , handle , uncompression_dict ,
Status s = RetrieveBlock (
& ( results . back ( ) ) , BlockType : : kData ,
nullptr , ro , handle , dict , & ( results . back ( ) ) , BlockType : : kData ,
miter - > get_context , & lookup_data_block_context ,
miter - > get_context , & lookup_data_block_context ,
/* for_compaction */ false , /* use_cache */ true ) ;
/* for_compaction */ false , /* use_cache */ true ) ;
if ( s . IsIncomplete ( ) ) {
if ( s . IsIncomplete ( ) ) {
s = Status : : OK ( ) ;
s = Status : : OK ( ) ;
}
}
@ -3464,9 +3473,8 @@ void BlockBasedTable::MultiGet(const ReadOptions& read_options,
block_buf . reset ( scratch ) ;
block_buf . reset ( scratch ) ;
}
}
}
}
RetrieveMultipleBlocks ( read_options ,
RetrieveMultipleBlocks ( read_options , & data_block_range , & block_handles ,
& data_block_range , & block_handles , & statuses , & results ,
& statuses , & results , scratch , dict ) ;
scratch , uncompression_dict ) ;
}
}
}
}
@ -4117,7 +4125,7 @@ Status BlockBasedTable::DumpTable(WritableFile* out_file) {
// Output compression dictionary
// Output compression dictionary
if ( rep_ - > uncompression_dict_reader ) {
if ( rep_ - > uncompression_dict_reader ) {
UncompressionDict uncompression_dict ;
CachableEntry < UncompressionDict > uncompression_dict ;
s = rep_ - > uncompression_dict_reader - > GetOrReadUncompressionDictionary (
s = rep_ - > uncompression_dict_reader - > GetOrReadUncompressionDictionary (
nullptr /* prefetch_buffer */ , false /* no_io */ ,
nullptr /* prefetch_buffer */ , false /* no_io */ ,
nullptr /* get_context */ , nullptr /* lookup_context */ ,
nullptr /* get_context */ , nullptr /* lookup_context */ ,
@ -4126,7 +4134,9 @@ Status BlockBasedTable::DumpTable(WritableFile* out_file) {
return s ;
return s ;
}
}
const Slice & raw_dict = uncompression_dict . GetRawDict ( ) ;
assert ( uncompression_dict . GetValue ( ) ) ;
const Slice & raw_dict = uncompression_dict . GetValue ( ) - > GetRawDict ( ) ;
out_file - > Append (
out_file - > Append (
" Compression Dictionary: \n "
" Compression Dictionary: \n "
" -------------------------------------- \n " ) ;
" -------------------------------------- \n " ) ;