@@ -264,6 +264,7 @@ DBImpl::DBImpl(const Options& options, const std::string& dbname)
264
264
bg_cv_(&mutex_),
265
265
mem_rep_factory_(options_.memtable_factory.get()),
266
266
mem_(new MemTable(internal_comparator_, options_)),
267
+ imm_(options_.min_write_buffer_number_to_merge),
267
268
logfile_number_(0 ),
268
269
super_version_(nullptr ),
269
270
super_version_number_(0 ),
@@ -360,7 +361,7 @@ DBImpl::~DBImpl() {
360
361
delete mem_->Unref ();
361
362
}
362
363
363
- imm_.UnrefAll (&to_delete);
364
+ imm_.current ()-> Unref (&to_delete);
364
365
for (MemTable* m: to_delete) {
365
366
delete m;
366
367
}
@@ -508,21 +509,21 @@ bool DBImpl::SuperVersion::Unref() {
508
509
509
510
void DBImpl::SuperVersion::Cleanup () {
510
511
assert (refs.load (std::memory_order_relaxed) == 0 );
511
- imm. UnrefAll (&to_delete);
512
+ imm-> Unref (&to_delete);
512
513
MemTable* m = mem->Unref ();
513
514
if (m != nullptr ) {
514
515
to_delete.push_back (m);
515
516
}
516
517
current->Unref ();
517
518
}
518
519
519
- void DBImpl::SuperVersion::Init (MemTable* new_mem, const MemTableList& new_imm,
520
+ void DBImpl::SuperVersion::Init (MemTable* new_mem, MemTableListVersion* new_imm,
520
521
Version* new_current) {
521
522
mem = new_mem;
522
523
imm = new_imm;
523
524
current = new_current;
524
525
mem->Ref ();
525
- imm. RefAll ();
526
+ imm-> Ref ();
526
527
current->Ref ();
527
528
refs.store (1 , std::memory_order_relaxed);
528
529
}
@@ -1221,7 +1222,7 @@ Status DBImpl::FlushMemTableToOutputFile(bool* madeProgress,
1221
1222
mutex_.AssertHeld ();
1222
1223
assert (imm_.size () != 0 );
1223
1224
1224
- if (!imm_.IsFlushPending (options_. min_write_buffer_number_to_merge )) {
1225
+ if (!imm_.IsFlushPending ()) {
1225
1226
Log (options_.info_log , " FlushMemTableToOutputFile already in progress" );
1226
1227
Status s = Status::IOError (" FlushMemTableToOutputFile already in progress" );
1227
1228
return s;
@@ -1762,8 +1763,7 @@ void DBImpl::MaybeScheduleFlushOrCompaction() {
1762
1763
} else if (shutting_down_.Acquire_Load ()) {
1763
1764
// DB is being deleted; no more background compactions
1764
1765
} else {
1765
- bool is_flush_pending =
1766
- imm_.IsFlushPending (options_.min_write_buffer_number_to_merge );
1766
+ bool is_flush_pending = imm_.IsFlushPending ();
1767
1767
if (is_flush_pending &&
1768
1768
(bg_flush_scheduled_ < options_.max_background_flushes )) {
1769
1769
// memtable flush needed
@@ -1798,8 +1798,7 @@ void DBImpl::BGWorkCompaction(void* db) {
1798
1798
Status DBImpl::BackgroundFlush (bool * madeProgress,
1799
1799
DeletionState& deletion_state) {
1800
1800
Status stat;
1801
- while (stat.ok () &&
1802
- imm_.IsFlushPending (options_.min_write_buffer_number_to_merge )) {
1801
+ while (stat.ok () && imm_.IsFlushPending ()) {
1803
1802
Log (options_.info_log ,
1804
1803
" BackgroundCallFlush doing FlushMemTableToOutputFile, flush slots available %d" ,
1805
1804
options_.max_background_flushes - bg_flush_scheduled_);
@@ -1919,7 +1918,7 @@ Status DBImpl::BackgroundCompaction(bool* madeProgress,
1919
1918
mutex_.AssertHeld ();
1920
1919
1921
1920
// TODO: remove memtable flush from formal compaction
1922
- while (imm_.IsFlushPending (options_. min_write_buffer_number_to_merge )) {
1921
+ while (imm_.IsFlushPending ()) {
1923
1922
Log (options_.info_log ,
1924
1923
" BackgroundCompaction doing FlushMemTableToOutputFile, compaction slots "
1925
1924
" available %d" ,
@@ -2325,7 +2324,7 @@ Status DBImpl::DoCompactionWork(CompactionState* compact,
2325
2324
const uint64_t imm_start = env_->NowMicros ();
2326
2325
LogFlush (options_.info_log );
2327
2326
mutex_.Lock ();
2328
- if (imm_.IsFlushPending (options_. min_write_buffer_number_to_merge )) {
2327
+ if (imm_.IsFlushPending ()) {
2329
2328
FlushMemTableToOutputFile (nullptr , deletion_state);
2330
2329
bg_cv_.SignalAll (); // Wakeup MakeRoomForWrite() if necessary
2331
2330
}
@@ -2658,8 +2657,9 @@ Status DBImpl::DoCompactionWork(CompactionState* compact,
2658
2657
namespace {
2659
2658
struct IterState {
2660
2659
port::Mutex* mu;
2661
- Version* version;
2662
- std::vector<MemTable*> mem; // includes both mem_ and imm_
2660
+ Version* version = nullptr ;
2661
+ MemTable* mem = nullptr ;
2662
+ MemTableListVersion* imm = nullptr ;
2663
2663
DBImpl *db;
2664
2664
};
2665
2665
@@ -2668,15 +2668,16 @@ static void CleanupIteratorState(void* arg1, void* arg2) {
2668
2668
DBImpl::DeletionState deletion_state (state->db ->GetOptions ().
2669
2669
max_write_buffer_number);
2670
2670
state->mu ->Lock ();
2671
- for (unsigned int i = 0 ; i < state->mem .size (); i++) {
2672
- MemTable* m = state->mem [i]->Unref ();
2673
- if (m != nullptr ) {
2674
- deletion_state.memtables_to_free .push_back (m);
2675
- }
2671
+ MemTable* m = state->mem ->Unref ();
2672
+ if (m != nullptr ) {
2673
+ deletion_state.memtables_to_free .push_back (m);
2676
2674
}
2677
2675
if (state->version ) { // not set for memtable-only iterator
2678
2676
state->version ->Unref ();
2679
2677
}
2678
+ if (state->imm ) { // not set for memtable-only iterator
2679
+ state->imm ->Unref (&deletion_state.memtables_to_free );
2680
+ }
2680
2681
// fast path FindObsoleteFiles
2681
2682
state->db ->FindObsoleteFiles (deletion_state, false , true );
2682
2683
state->mu ->Unlock ();
@@ -2690,7 +2691,7 @@ Iterator* DBImpl::NewInternalIterator(const ReadOptions& options,
2690
2691
SequenceNumber* latest_snapshot) {
2691
2692
IterState* cleanup = new IterState;
2692
2693
MemTable* mutable_mem;
2693
- std::vector<MemTable*> immutables ;
2694
+ MemTableListVersion* immutable_mems ;
2694
2695
Version* version;
2695
2696
2696
2697
// Collect together all needed child iterators for mem
@@ -2699,27 +2700,22 @@ Iterator* DBImpl::NewInternalIterator(const ReadOptions& options,
2699
2700
mem_->Ref ();
2700
2701
mutable_mem = mem_;
2701
2702
// Collect together all needed child iterators for imm_
2702
- imm_.GetMemTables (&immutables);
2703
- for (unsigned int i = 0 ; i < immutables.size (); i++) {
2704
- immutables[i]->Ref ();
2705
- }
2703
+ immutable_mems = imm_.current ();
2704
+ immutable_mems->Ref ();
2706
2705
versions_->current ()->Ref ();
2707
2706
version = versions_->current ();
2708
2707
mutex_.Unlock ();
2709
2708
2710
- std::vector<Iterator*> list ;
2711
- list .push_back (mutable_mem->NewIterator (options));
2712
- cleanup->mem . push_back ( mutable_mem) ;
2713
-
2709
+ std::vector<Iterator*> iterator_list ;
2710
+ iterator_list .push_back (mutable_mem->NewIterator (options));
2711
+ cleanup->mem = mutable_mem;
2712
+ cleanup-> imm = immutable_mems;
2714
2713
// Collect all needed child iterators for immutable memtables
2715
- for (MemTable* m : immutables) {
2716
- list.push_back (m->NewIterator (options));
2717
- cleanup->mem .push_back (m);
2718
- }
2714
+ immutable_mems->AddIterators (options, &iterator_list);
2719
2715
// Collect iterators for files in L0 - Ln
2720
- version->AddIterators (options, storage_options_, &list );
2721
- Iterator* internal_iter =
2722
- NewMergingIterator ( &internal_comparator_, &list [0 ], list .size ());
2716
+ version->AddIterators (options, storage_options_, &iterator_list );
2717
+ Iterator* internal_iter = NewMergingIterator (
2718
+ &internal_comparator_, &iterator_list [0 ], iterator_list .size ());
2723
2719
cleanup->version = version;
2724
2720
cleanup->mu = &mutex_;
2725
2721
cleanup->db = this ;
@@ -2738,19 +2734,15 @@ std::pair<Iterator*, Iterator*> DBImpl::GetTailingIteratorPair(
2738
2734
uint64_t * superversion_number) {
2739
2735
2740
2736
MemTable* mutable_mem;
2741
- std::vector<MemTable*> immutables ;
2737
+ MemTableListVersion* immutable_mems ;
2742
2738
Version* version;
2743
2739
2744
- immutables.reserve (options_.max_write_buffer_number );
2745
-
2746
2740
// get all child iterators and bump their refcounts under lock
2747
2741
mutex_.Lock ();
2748
2742
mutable_mem = mem_;
2749
2743
mutable_mem->Ref ();
2750
- imm_.GetMemTables (&immutables);
2751
- for (size_t i = 0 ; i < immutables.size (); ++i) {
2752
- immutables[i]->Ref ();
2753
- }
2744
+ immutable_mems = imm_.current ();
2745
+ immutable_mems->Ref ();
2754
2746
version = versions_->current ();
2755
2747
version->Ref ();
2756
2748
if (superversion_number != nullptr ) {
@@ -2760,7 +2752,7 @@ std::pair<Iterator*, Iterator*> DBImpl::GetTailingIteratorPair(
2760
2752
2761
2753
Iterator* mutable_iter = mutable_mem->NewIterator (options);
2762
2754
IterState* mutable_cleanup = new IterState ();
2763
- mutable_cleanup->mem . push_back ( mutable_mem) ;
2755
+ mutable_cleanup->mem = mutable_mem;
2764
2756
mutable_cleanup->db = this ;
2765
2757
mutable_cleanup->mu = &mutex_;
2766
2758
mutable_iter->RegisterCleanup (CleanupIteratorState, mutable_cleanup, nullptr );
@@ -2772,10 +2764,8 @@ std::pair<Iterator*, Iterator*> DBImpl::GetTailingIteratorPair(
2772
2764
Iterator* immutable_iter;
2773
2765
IterState* immutable_cleanup = new IterState ();
2774
2766
std::vector<Iterator*> list;
2775
- for (MemTable* m : immutables) {
2776
- list.push_back (m->NewIterator (options));
2777
- immutable_cleanup->mem .push_back (m);
2778
- }
2767
+ immutable_mems->AddIterators (options, &list);
2768
+ immutable_cleanup->imm = immutable_mems;
2779
2769
version->AddIterators (options, storage_options_, &list);
2780
2770
immutable_cleanup->version = version;
2781
2771
immutable_cleanup->db = this ;
@@ -2832,7 +2822,7 @@ void DBImpl::InstallSuperVersion(DeletionState& deletion_state) {
2832
2822
DBImpl::SuperVersion* DBImpl::InstallSuperVersion (
2833
2823
SuperVersion* new_superversion) {
2834
2824
mutex_.AssertHeld ();
2835
- new_superversion->Init (mem_, imm_, versions_->current ());
2825
+ new_superversion->Init (mem_, imm_. current () , versions_->current ());
2836
2826
SuperVersion* old_superversion = super_version_;
2837
2827
super_version_ = new_superversion;
2838
2828
++super_version_number_;
@@ -2875,7 +2865,7 @@ Status DBImpl::GetImpl(const ReadOptions& options,
2875
2865
if (get_version->mem ->Get (lkey, value, &s, merge_context, options_)) {
2876
2866
// Done
2877
2867
RecordTick (options_.statistics .get (), MEMTABLE_HIT);
2878
- } else if (get_version->imm . Get (lkey, value, &s, merge_context, options_)) {
2868
+ } else if (get_version->imm -> Get (lkey, value, &s, merge_context, options_)) {
2879
2869
// Done
2880
2870
RecordTick (options_.statistics .get (), MEMTABLE_HIT);
2881
2871
} else {
@@ -2930,10 +2920,10 @@ std::vector<Status> DBImpl::MultiGet(const ReadOptions& options,
2930
2920
}
2931
2921
2932
2922
MemTable* mem = mem_;
2933
- MemTableList imm = imm_;
2923
+ MemTableListVersion* imm = imm_. current () ;
2934
2924
Version* current = versions_->current ();
2935
2925
mem->Ref ();
2936
- imm. RefAll ();
2926
+ imm-> Ref ();
2937
2927
current->Ref ();
2938
2928
2939
2929
// Unlock while reading from files and memtables
@@ -2965,7 +2955,7 @@ std::vector<Status> DBImpl::MultiGet(const ReadOptions& options,
2965
2955
LookupKey lkey (keys[i], snapshot);
2966
2956
if (mem->Get (lkey, value, &s, merge_context, options_)) {
2967
2957
// Done
2968
- } else if (imm. Get (lkey, value, &s, merge_context, options_)) {
2958
+ } else if (imm-> Get (lkey, value, &s, merge_context, options_)) {
2969
2959
// Done
2970
2960
} else {
2971
2961
current->Get (options, lkey, value, &s, &merge_context, &stats, options_);
@@ -2984,7 +2974,7 @@ std::vector<Status> DBImpl::MultiGet(const ReadOptions& options,
2984
2974
MaybeScheduleFlushOrCompaction ();
2985
2975
}
2986
2976
MemTable* m = mem->Unref ();
2987
- imm. UnrefAll (&to_delete);
2977
+ imm-> Unref (&to_delete);
2988
2978
current->Unref ();
2989
2979
mutex_.Unlock ();
2990
2980
0 commit comments