Skip to content

Commit 1423e7c

Browse files
committed
Merge branch 'master' into columnfamilies
Conflicts: db/version_set.cc db/version_set_reduce_num_levels.cc util/ldb_cmd.cc
2 parents 28d1a0c + b13bdfa commit 1423e7c

20 files changed

+385
-310
lines changed

Makefile

+3-2
Original file line numberDiff line numberDiff line change
@@ -136,13 +136,12 @@ endif # PLATFORM_SHARED_EXT
136136
all: $(LIBRARY) $(PROGRAMS)
137137

138138
.PHONY: blackbox_crash_test check clean coverage crash_test ldb_tests \
139-
release tags valgrind_check whitebox_crash_test format
139+
release tags valgrind_check whitebox_crash_test format shared_lib
140140

141141
# Will also generate shared libraries.
142142
release:
143143
$(MAKE) clean
144144
OPT=-DNDEBUG $(MAKE) all -j32
145-
OPT=-DNDEBUG $(MAKE) $(SHARED) -j32
146145

147146
coverage:
148147
$(MAKE) clean
@@ -202,6 +201,8 @@ tags:
202201
format:
203202
build_tools/format-diff.sh
204203

204+
shared_lib: $(SHARED)
205+
205206
# ---------------------------------------------------------------------------
206207
# Unit tests and tools
207208
# ---------------------------------------------------------------------------

db/compaction_picker.cc

+20-12
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,21 @@ uint64_t TotalFileSize(const std::vector<FileMetaData*>& files) {
2222
return sum;
2323
}
2424

25+
// Multiple two operands. If they overflow, return op1.
26+
uint64_t MultiplyCheckOverflow(uint64_t op1, int op2) {
27+
if (op1 == 0) {
28+
return 0;
29+
}
30+
if (op2 <= 0) {
31+
return op1;
32+
}
33+
uint64_t casted_op2 = (uint64_t) op2;
34+
if (std::numeric_limits<uint64_t>::max() / op1 < casted_op2) {
35+
return op1;
36+
}
37+
return op1 * casted_op2;
38+
}
39+
2540
} // anonymous namespace
2641

2742
CompactionPicker::CompactionPicker(const Options* options,
@@ -30,15 +45,7 @@ CompactionPicker::CompactionPicker(const Options* options,
3045
options_(options),
3146
num_levels_(options->num_levels),
3247
icmp_(icmp) {
33-
Init();
34-
}
35-
36-
void CompactionPicker::ReduceNumberOfLevels(int new_levels) {
37-
num_levels_ = new_levels;
38-
Init();
39-
}
4048

41-
void CompactionPicker::Init() {
4249
max_file_size_.reset(new uint64_t[NumberLevels()]);
4350
level_max_bytes_.reset(new uint64_t[NumberLevels()]);
4451
int target_file_size_multiplier = options_->target_file_size_multiplier;
@@ -48,10 +55,11 @@ void CompactionPicker::Init() {
4855
max_file_size_[i] = ULLONG_MAX;
4956
level_max_bytes_[i] = options_->max_bytes_for_level_base;
5057
} else if (i > 1) {
51-
max_file_size_[i] = max_file_size_[i - 1] * target_file_size_multiplier;
52-
level_max_bytes_[i] =
53-
level_max_bytes_[i - 1] * max_bytes_multiplier *
54-
options_->max_bytes_for_level_multiplier_additional[i - 1];
58+
max_file_size_[i] = MultiplyCheckOverflow(max_file_size_[i - 1],
59+
target_file_size_multiplier);
60+
level_max_bytes_[i] = MultiplyCheckOverflow(
61+
MultiplyCheckOverflow(level_max_bytes_[i - 1], max_bytes_multiplier),
62+
options_->max_bytes_for_level_multiplier_additional[i - 1]);
5563
} else {
5664
max_file_size_[i] = options_->target_file_size_base;
5765
level_max_bytes_[i] = options_->max_bytes_for_level_base;

db/compaction_picker.h

-5
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,6 @@ class CompactionPicker {
2727
CompactionPicker(const Options* options, const InternalKeyComparator* icmp);
2828
virtual ~CompactionPicker();
2929

30-
// See VersionSet::ReduceNumberOfLevels()
31-
void ReduceNumberOfLevels(int new_levels);
32-
3330
// Pick level and inputs for a new compaction.
3431
// Returns nullptr if there is no compaction to be done.
3532
// Otherwise returns a pointer to a heap-allocated object that
@@ -120,8 +117,6 @@ class CompactionPicker {
120117

121118
const Options* const options_;
122119
private:
123-
void Init();
124-
125120
int num_levels_;
126121

127122
const InternalKeyComparator* const icmp_;

db/db_impl.cc

+42-52
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,7 @@ DBImpl::DBImpl(const Options& options, const std::string& dbname)
267267
bg_cv_(&mutex_),
268268
mem_rep_factory_(options_.memtable_factory.get()),
269269
mem_(new MemTable(internal_comparator_, options_)),
270+
imm_(options_.min_write_buffer_number_to_merge),
270271
logfile_number_(0),
271272
super_version_(nullptr),
272273
super_version_number_(0),
@@ -363,7 +364,7 @@ DBImpl::~DBImpl() {
363364
delete mem_->Unref();
364365
}
365366

366-
imm_.UnrefAll(&to_delete);
367+
imm_.current()->Unref(&to_delete);
367368
for (MemTable* m: to_delete) {
368369
delete m;
369370
}
@@ -511,21 +512,21 @@ bool DBImpl::SuperVersion::Unref() {
511512

512513
void DBImpl::SuperVersion::Cleanup() {
513514
assert(refs.load(std::memory_order_relaxed) == 0);
514-
imm.UnrefAll(&to_delete);
515+
imm->Unref(&to_delete);
515516
MemTable* m = mem->Unref();
516517
if (m != nullptr) {
517518
to_delete.push_back(m);
518519
}
519520
current->Unref();
520521
}
521522

522-
void DBImpl::SuperVersion::Init(MemTable* new_mem, const MemTableList& new_imm,
523+
void DBImpl::SuperVersion::Init(MemTable* new_mem, MemTableListVersion* new_imm,
523524
Version* new_current) {
524525
mem = new_mem;
525526
imm = new_imm;
526527
current = new_current;
527528
mem->Ref();
528-
imm.RefAll();
529+
imm->Ref();
529530
current->Ref();
530531
refs.store(1, std::memory_order_relaxed);
531532
}
@@ -1226,7 +1227,7 @@ Status DBImpl::FlushMemTableToOutputFile(bool* madeProgress,
12261227
mutex_.AssertHeld();
12271228
assert(imm_.size() != 0);
12281229

1229-
if (!imm_.IsFlushPending(options_.min_write_buffer_number_to_merge)) {
1230+
if (!imm_.IsFlushPending()) {
12301231
Log(options_.info_log, "FlushMemTableToOutputFile already in progress");
12311232
Status s = Status::IOError("FlushMemTableToOutputFile already in progress");
12321233
return s;
@@ -1767,8 +1768,7 @@ void DBImpl::MaybeScheduleFlushOrCompaction() {
17671768
} else if (shutting_down_.Acquire_Load()) {
17681769
// DB is being deleted; no more background compactions
17691770
} else {
1770-
bool is_flush_pending =
1771-
imm_.IsFlushPending(options_.min_write_buffer_number_to_merge);
1771+
bool is_flush_pending = imm_.IsFlushPending();
17721772
if (is_flush_pending &&
17731773
(bg_flush_scheduled_ < options_.max_background_flushes)) {
17741774
// memtable flush needed
@@ -1803,8 +1803,7 @@ void DBImpl::BGWorkCompaction(void* db) {
18031803
Status DBImpl::BackgroundFlush(bool* madeProgress,
18041804
DeletionState& deletion_state) {
18051805
Status stat;
1806-
while (stat.ok() &&
1807-
imm_.IsFlushPending(options_.min_write_buffer_number_to_merge)) {
1806+
while (stat.ok() && imm_.IsFlushPending()) {
18081807
Log(options_.info_log,
18091808
"BackgroundCallFlush doing FlushMemTableToOutputFile, flush slots available %d",
18101809
options_.max_background_flushes - bg_flush_scheduled_);
@@ -1924,7 +1923,7 @@ Status DBImpl::BackgroundCompaction(bool* madeProgress,
19241923
mutex_.AssertHeld();
19251924

19261925
// TODO: remove memtable flush from formal compaction
1927-
while (imm_.IsFlushPending(options_.min_write_buffer_number_to_merge)) {
1926+
while (imm_.IsFlushPending()) {
19281927
Log(options_.info_log,
19291928
"BackgroundCompaction doing FlushMemTableToOutputFile, compaction slots "
19301929
"available %d",
@@ -2330,7 +2329,7 @@ Status DBImpl::DoCompactionWork(CompactionState* compact,
23302329
const uint64_t imm_start = env_->NowMicros();
23312330
LogFlush(options_.info_log);
23322331
mutex_.Lock();
2333-
if (imm_.IsFlushPending(options_.min_write_buffer_number_to_merge)) {
2332+
if (imm_.IsFlushPending()) {
23342333
FlushMemTableToOutputFile(nullptr, deletion_state);
23352334
bg_cv_.SignalAll(); // Wakeup MakeRoomForWrite() if necessary
23362335
}
@@ -2663,8 +2662,9 @@ Status DBImpl::DoCompactionWork(CompactionState* compact,
26632662
namespace {
26642663
struct IterState {
26652664
port::Mutex* mu;
2666-
Version* version;
2667-
std::vector<MemTable*> mem; // includes both mem_ and imm_
2665+
Version* version = nullptr;
2666+
MemTable* mem = nullptr;
2667+
MemTableListVersion* imm = nullptr;
26682668
DBImpl *db;
26692669
};
26702670

@@ -2673,15 +2673,16 @@ static void CleanupIteratorState(void* arg1, void* arg2) {
26732673
DBImpl::DeletionState deletion_state(state->db->GetOptions().
26742674
max_write_buffer_number);
26752675
state->mu->Lock();
2676-
for (unsigned int i = 0; i < state->mem.size(); i++) {
2677-
MemTable* m = state->mem[i]->Unref();
2678-
if (m != nullptr) {
2679-
deletion_state.memtables_to_free.push_back(m);
2680-
}
2676+
MemTable* m = state->mem->Unref();
2677+
if (m != nullptr) {
2678+
deletion_state.memtables_to_free.push_back(m);
26812679
}
26822680
if (state->version) { // not set for memtable-only iterator
26832681
state->version->Unref();
26842682
}
2683+
if (state->imm) { // not set for memtable-only iterator
2684+
state->imm->Unref(&deletion_state.memtables_to_free);
2685+
}
26852686
// fast path FindObsoleteFiles
26862687
state->db->FindObsoleteFiles(deletion_state, false, true);
26872688
state->mu->Unlock();
@@ -2695,7 +2696,7 @@ Iterator* DBImpl::NewInternalIterator(const ReadOptions& options,
26952696
SequenceNumber* latest_snapshot) {
26962697
IterState* cleanup = new IterState;
26972698
MemTable* mutable_mem;
2698-
std::vector<MemTable*> immutables;
2699+
MemTableListVersion* immutable_mems;
26992700
Version* version;
27002701

27012702
// Collect together all needed child iterators for mem
@@ -2704,27 +2705,22 @@ Iterator* DBImpl::NewInternalIterator(const ReadOptions& options,
27042705
mem_->Ref();
27052706
mutable_mem = mem_;
27062707
// Collect together all needed child iterators for imm_
2707-
imm_.GetMemTables(&immutables);
2708-
for (unsigned int i = 0; i < immutables.size(); i++) {
2709-
immutables[i]->Ref();
2710-
}
2708+
immutable_mems = imm_.current();
2709+
immutable_mems->Ref();
27112710
versions_->current()->Ref();
27122711
version = versions_->current();
27132712
mutex_.Unlock();
27142713

2715-
std::vector<Iterator*> list;
2716-
list.push_back(mutable_mem->NewIterator(options));
2717-
cleanup->mem.push_back(mutable_mem);
2718-
2714+
std::vector<Iterator*> iterator_list;
2715+
iterator_list.push_back(mutable_mem->NewIterator(options));
2716+
cleanup->mem = mutable_mem;
2717+
cleanup->imm = immutable_mems;
27192718
// Collect all needed child iterators for immutable memtables
2720-
for (MemTable* m : immutables) {
2721-
list.push_back(m->NewIterator(options));
2722-
cleanup->mem.push_back(m);
2723-
}
2719+
immutable_mems->AddIterators(options, &iterator_list);
27242720
// Collect iterators for files in L0 - Ln
2725-
version->AddIterators(options, storage_options_, &list);
2726-
Iterator* internal_iter =
2727-
NewMergingIterator(&internal_comparator_, &list[0], list.size());
2721+
version->AddIterators(options, storage_options_, &iterator_list);
2722+
Iterator* internal_iter = NewMergingIterator(
2723+
&internal_comparator_, &iterator_list[0], iterator_list.size());
27282724
cleanup->version = version;
27292725
cleanup->mu = &mutex_;
27302726
cleanup->db = this;
@@ -2743,19 +2739,15 @@ std::pair<Iterator*, Iterator*> DBImpl::GetTailingIteratorPair(
27432739
uint64_t* superversion_number) {
27442740

27452741
MemTable* mutable_mem;
2746-
std::vector<MemTable*> immutables;
2742+
MemTableListVersion* immutable_mems;
27472743
Version* version;
27482744

2749-
immutables.reserve(options_.max_write_buffer_number);
2750-
27512745
// get all child iterators and bump their refcounts under lock
27522746
mutex_.Lock();
27532747
mutable_mem = mem_;
27542748
mutable_mem->Ref();
2755-
imm_.GetMemTables(&immutables);
2756-
for (size_t i = 0; i < immutables.size(); ++i) {
2757-
immutables[i]->Ref();
2758-
}
2749+
immutable_mems = imm_.current();
2750+
immutable_mems->Ref();
27592751
version = versions_->current();
27602752
version->Ref();
27612753
if (superversion_number != nullptr) {
@@ -2765,7 +2757,7 @@ std::pair<Iterator*, Iterator*> DBImpl::GetTailingIteratorPair(
27652757

27662758
Iterator* mutable_iter = mutable_mem->NewIterator(options);
27672759
IterState* mutable_cleanup = new IterState();
2768-
mutable_cleanup->mem.push_back(mutable_mem);
2760+
mutable_cleanup->mem = mutable_mem;
27692761
mutable_cleanup->db = this;
27702762
mutable_cleanup->mu = &mutex_;
27712763
mutable_iter->RegisterCleanup(CleanupIteratorState, mutable_cleanup, nullptr);
@@ -2777,10 +2769,8 @@ std::pair<Iterator*, Iterator*> DBImpl::GetTailingIteratorPair(
27772769
Iterator* immutable_iter;
27782770
IterState* immutable_cleanup = new IterState();
27792771
std::vector<Iterator*> list;
2780-
for (MemTable* m : immutables) {
2781-
list.push_back(m->NewIterator(options));
2782-
immutable_cleanup->mem.push_back(m);
2783-
}
2772+
immutable_mems->AddIterators(options, &list);
2773+
immutable_cleanup->imm = immutable_mems;
27842774
version->AddIterators(options, storage_options_, &list);
27852775
immutable_cleanup->version = version;
27862776
immutable_cleanup->db = this;
@@ -2837,7 +2827,7 @@ void DBImpl::InstallSuperVersion(DeletionState& deletion_state) {
28372827
DBImpl::SuperVersion* DBImpl::InstallSuperVersion(
28382828
SuperVersion* new_superversion) {
28392829
mutex_.AssertHeld();
2840-
new_superversion->Init(mem_, imm_, versions_->current());
2830+
new_superversion->Init(mem_, imm_.current(), versions_->current());
28412831
SuperVersion* old_superversion = super_version_;
28422832
super_version_ = new_superversion;
28432833
++super_version_number_;
@@ -2880,7 +2870,7 @@ Status DBImpl::GetImpl(const ReadOptions& options,
28802870
if (get_version->mem->Get(lkey, value, &s, merge_context, options_)) {
28812871
// Done
28822872
RecordTick(options_.statistics.get(), MEMTABLE_HIT);
2883-
} else if (get_version->imm.Get(lkey, value, &s, merge_context, options_)) {
2873+
} else if (get_version->imm->Get(lkey, value, &s, merge_context, options_)) {
28842874
// Done
28852875
RecordTick(options_.statistics.get(), MEMTABLE_HIT);
28862876
} else {
@@ -2936,10 +2926,10 @@ std::vector<Status> DBImpl::MultiGet(
29362926
}
29372927

29382928
MemTable* mem = mem_;
2939-
MemTableList imm = imm_;
2929+
MemTableListVersion* imm = imm_.current();
29402930
Version* current = versions_->current();
29412931
mem->Ref();
2942-
imm.RefAll();
2932+
imm->Ref();
29432933
current->Ref();
29442934

29452935
// Unlock while reading from files and memtables
@@ -2971,7 +2961,7 @@ std::vector<Status> DBImpl::MultiGet(
29712961
LookupKey lkey(keys[i], snapshot);
29722962
if (mem->Get(lkey, value, &s, merge_context, options_)) {
29732963
// Done
2974-
} else if (imm.Get(lkey, value, &s, merge_context, options_)) {
2964+
} else if (imm->Get(lkey, value, &s, merge_context, options_)) {
29752965
// Done
29762966
} else {
29772967
current->Get(options, lkey, value, &s, &merge_context, &stats, options_);
@@ -2990,7 +2980,7 @@ std::vector<Status> DBImpl::MultiGet(
29902980
MaybeScheduleFlushOrCompaction();
29912981
}
29922982
MemTable* m = mem->Unref();
2993-
imm.UnrefAll(&to_delete);
2983+
imm->Unref(&to_delete);
29942984
current->Unref();
29952985
mutex_.Unlock();
29962986

db/db_impl.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -177,10 +177,10 @@ class DBImpl : public DB {
177177
// holds references to memtable, all immutable memtables and version
178178
struct SuperVersion {
179179
MemTable* mem;
180-
MemTableList imm;
180+
MemTableListVersion* imm;
181181
Version* current;
182182
std::atomic<uint32_t> refs;
183-
// We need to_delete because during Cleanup(), imm.UnrefAll() returns
183+
// We need to_delete because during Cleanup(), imm->Unref() returns
184184
// all memtables that we need to free through this vector. We then
185185
// delete all those memtables outside of mutex, during destruction
186186
std::vector<MemTable*> to_delete;
@@ -198,7 +198,7 @@ class DBImpl : public DB {
198198
// that needs to be deleted in to_delete vector. Unrefing those
199199
// objects needs to be done in the mutex
200200
void Cleanup();
201-
void Init(MemTable* new_mem, const MemTableList& new_imm,
201+
void Init(MemTable* new_mem, MemTableListVersion* new_imm,
202202
Version* new_current);
203203
};
204204

0 commit comments

Comments
 (0)