@ -31,35 +31,51 @@
namespace rocksdb {
MemTable : : MemTable ( const InternalKeyComparator & cmp , const Options & options )
MemTableOptions : : MemTableOptions ( const Options & options )
: write_buffer_size ( options . write_buffer_size ) ,
arena_block_size ( options . arena_block_size ) ,
memtable_prefix_bloom_bits ( options . memtable_prefix_bloom_bits ) ,
memtable_prefix_bloom_probes ( options . memtable_prefix_bloom_probes ) ,
memtable_prefix_bloom_huge_page_tlb_size (
options . memtable_prefix_bloom_huge_page_tlb_size ) ,
inplace_update_support ( options . inplace_update_support ) ,
inplace_update_num_locks ( options . inplace_update_num_locks ) ,
inplace_callback ( options . inplace_callback ) ,
max_successive_merges ( options . max_successive_merges ) ,
filter_deletes ( options . filter_deletes ) { }
MemTable : : MemTable ( const InternalKeyComparator & cmp ,
const ImmutableCFOptions & ioptions ,
const MemTableOptions & moptions )
: comparator_ ( cmp ) ,
ioptions_ ( ioptions ) ,
moptions_ ( moptions ) ,
refs_ ( 0 ) ,
kArenaBlockSize ( OptimizeBlockSize ( options . arena_block_size ) ) ,
kWriteBufferSize ( options . write_buffer_size ) ,
arena_ ( options . arena_block_size ) ,
table_ ( options . memtable_factory - > CreateMemTableRep (
comparator_ , & arena_ , options . prefix_extractor . get ( ) ,
options . info_log . get ( ) ) ) ,
kArenaBlockSize ( OptimizeBlockSize ( moptions . arena_block_size ) ) ,
arena_ ( moptions . arena_block_size ) ,
table_ ( ioptions . memtable_factory - > CreateMemTableRep (
comparator_ , & arena_ , ioptions . prefix_extractor ,
ioptions . info_log ) ) ,
num_entries_ ( 0 ) ,
flush_in_progress_ ( false ) ,
flush_completed_ ( false ) ,
file_number_ ( 0 ) ,
first_seqno_ ( 0 ) ,
mem_next_logfile_number_ ( 0 ) ,
locks_ ( options . inplace_update_support ? options . inplace_update_num_locks
: 0 ) ,
prefix_extractor_ ( options . prefix_extractor . get ( ) ) ,
locks_ ( m options. inplace_update_support ? m options. inplace_update_num_locks
: 0 ) ,
prefix_extractor_ ( i options. prefix_extractor ) ,
should_flush_ ( ShouldFlushNow ( ) ) {
// if should_flush_ == true without an entry inserted, something must have
// gone wrong already.
assert ( ! should_flush_ ) ;
if ( prefix_extractor_ & & options . memtable_prefix_bloom_bits > 0 ) {
if ( prefix_extractor_ & & m options. memtable_prefix_bloom_bits > 0 ) {
prefix_bloom_ . reset ( new DynamicBloom (
& arena_ ,
options . memtable_prefix_bloom_bits , options . bloom_locality ,
options . memtable_prefix_bloom_probes , nullptr ,
options . memtable_prefix_bloom_huge_page_tlb_size ,
options . info_log . get ( ) ) ) ;
m options. memtable_prefix_bloom_bits , i options. bloom_locality ,
m options. memtable_prefix_bloom_probes , nullptr ,
m options. memtable_prefix_bloom_huge_page_tlb_size ,
i options. info_log ) ) ;
}
}
@ -97,14 +113,16 @@ bool MemTable::ShouldFlushNow() const {
// if we can still allocate one more block without exceeding the
// over-allocation ratio, then we should not flush.
if ( allocated_memory + kArenaBlockSize <
kWriteBufferSize + kArenaBlockSize * kAllowOverAllocationRatio ) {
moptions_ . write_buffer_size +
kArenaBlockSize * kAllowOverAllocationRatio ) {
return false ;
}
// if user keeps adding entries that exceeds kWriteBufferSize, we need to
// flush earlier even though we still have much available memory left.
if ( allocated_memory >
kWriteBufferSize + kArenaBlockSize * kAllowOverAllocationRatio ) {
// if user keeps adding entries that exceeds moptions.write_buffer_size,
// we need to flush earlier even though we still have much available
// memory left.
if ( allocated_memory > moptions_ . write_buffer_size +
kArenaBlockSize * kAllowOverAllocationRatio ) {
return true ;
}
@ -175,12 +193,12 @@ const char* EncodeKey(std::string* scratch, const Slice& target) {
class MemTableIterator : public Iterator {
public :
MemTableIterator (
const MemTable & mem , const ReadOptions & options , Arena * arena )
const MemTable & mem , const ReadOptions & read_ options, Arena * arena )
: bloom_ ( nullptr ) ,
prefix_extractor_ ( mem . prefix_extractor_ ) ,
valid_ ( false ) ,
arena_mode_ ( arena ! = nullptr ) {
if ( prefix_extractor_ ! = nullptr & & ! options . total_order_seek ) {
if ( prefix_extractor_ ! = nullptr & & ! read_ options. total_order_seek ) {
bloom_ = mem . prefix_bloom_ . get ( ) ;
iter_ = mem . table_ - > GetDynamicPrefixIterator ( arena ) ;
} else {
@ -248,10 +266,10 @@ class MemTableIterator: public Iterator {
void operator = ( const MemTableIterator & ) ;
} ;
Iterator * MemTable : : NewIterator ( const ReadOptions & options , Arena * arena ) {
Iterator * MemTable : : NewIterator ( const ReadOptions & read_ options, Arena * arena ) {
assert ( arena ! = nullptr ) ;
auto mem = arena - > AllocateAligned ( sizeof ( MemTableIterator ) ) ;
return new ( mem ) MemTableIterator ( * this , options , arena ) ;
return new ( mem ) MemTableIterator ( * this , read_ options, arena ) ;
}
port : : RWMutex * MemTable : : GetLock ( const Slice & key ) {
@ -412,7 +430,7 @@ static bool SaveValue(void* arg, const char* entry) {
}
bool MemTable : : Get ( const LookupKey & key , std : : string * value , Status * s ,
MergeContext & merge_context , const Options & options ) {
MergeContext & merge_context ) {
// The sequence number is updated synchronously in version_set.h
if ( IsEmpty ( ) ) {
// Avoiding recording stats for speed.
@ -437,10 +455,10 @@ bool MemTable::Get(const LookupKey& key, std::string* value, Status* s,
saver . status = s ;
saver . mem = this ;
saver . merge_context = & merge_context ;
saver . merge_operator = options . merge_operator . get ( ) ;
saver . logger = options . info_log . get ( ) ;
saver . inplace_update_support = options . inplace_update_support ;
saver . statistics = options . statistics . get ( ) ;
saver . merge_operator = i options_ . merge_operator ;
saver . logger = i options_ . info_log ;
saver . inplace_update_support = m options_ . inplace_update_support ;
saver . statistics = i options_ . statistics ;
table_ - > Get ( key , & saver , SaveValue ) ;
}
@ -512,8 +530,7 @@ void MemTable::Update(SequenceNumber seq,
bool MemTable : : UpdateCallback ( SequenceNumber seq ,
const Slice & key ,
const Slice & delta ,
const Options & options ) {
const Slice & delta ) {
LookupKey lkey ( key , seq ) ;
Slice memkey = lkey . memtable_key ( ) ;
@ -548,8 +565,8 @@ bool MemTable::UpdateCallback(SequenceNumber seq,
std : : string str_value ;
WriteLock wl ( GetLock ( lkey . user_key ( ) ) ) ;
auto status = options . inplace_callback ( prev_buffer , & new_prev_size ,
delta , & str_value ) ;
auto status = m options_ . inplace_callback ( prev_buffer , & new_prev_size ,
delta , & str_value ) ;
if ( status = = UpdateStatus : : UPDATED_INPLACE ) {
// Value already updated by callback.
assert ( new_prev_size < = prev_size ) ;
@ -562,12 +579,12 @@ bool MemTable::UpdateCallback(SequenceNumber seq,
memcpy ( p , prev_buffer , new_prev_size ) ;
}
}
RecordTick ( options . statistics . get ( ) , NUMBER_KEYS_UPDATED ) ;
RecordTick ( i options_ . statistics , NUMBER_KEYS_UPDATED ) ;
should_flush_ = ShouldFlushNow ( ) ;
return true ;
} else if ( status = = UpdateStatus : : UPDATED ) {
Add ( seq , kTypeValue , key , Slice ( str_value ) ) ;
RecordTick ( options . statistics . get ( ) , NUMBER_KEYS_WRITTEN ) ;
RecordTick ( i options_ . statistics , NUMBER_KEYS_WRITTEN ) ;
should_flush_ = ShouldFlushNow ( ) ;
return true ;
} else if ( status = = UpdateStatus : : UPDATE_FAILED ) {