Skip to content

Commit 28d1a0c

Browse files
committed
Merge branch 'master' into columnfamilies
Conflicts: db/db_impl.cc db/db_impl.h db/db_impl_readonly.h db/db_test.cc include/rocksdb/db.h include/utilities/stackable_db.h
2 parents 09489d3 + aba2acb commit 28d1a0c

20 files changed

+5342
-82
lines changed

.arcconfig

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
{
2-
"project_id" : "leveldb",
2+
"project_id" : "rocksdb",
33
"conduit_uri" : "https://reviews.facebook.net/",
4-
"copyright_holder" : "",
4+
"copyright_holder" : "Facebook",
55
"load" : [
6-
"linters/src/"
6+
"linters"
77
],
88
"lint.engine" : "FacebookFbcodeLintEngine",
9-
"lint.engine.single.linter" : "FbcodeCppLinter"
9+
"lint.engine.single.linter" : "FbcodeCppLinter",
10+
"lint.cpplint.prefix" : "linters"
1011
}

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,4 @@ util/build_version.cc
2020
build_tools/VALGRIND_LOGS/
2121
coverage/COVERAGE_REPORT
2222
.gdbhistory
23+
.phutil_module_cache

db/db_impl.cc

+123-27
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <stdint.h>
1818
#include <string>
1919
#include <unordered_set>
20+
#include <utility>
2021
#include <vector>
2122

2223
#include "db/builder.h"
@@ -32,6 +33,7 @@
3233
#include "db/prefix_filter_iterator.h"
3334
#include "db/table_cache.h"
3435
#include "db/table_properties_collector.h"
36+
#include "db/tailing_iter.h"
3537
#include "db/transaction_log_impl.h"
3638
#include "db/version_set.h"
3739
#include "db/write_batch_internal.h"
@@ -267,6 +269,7 @@ DBImpl::DBImpl(const Options& options, const std::string& dbname)
267269
mem_(new MemTable(internal_comparator_, options_)),
268270
logfile_number_(0),
269271
super_version_(nullptr),
272+
super_version_number_(0),
270273
tmp_batch_(),
271274
bg_compaction_scheduled_(0),
272275
bg_manual_only_(0),
@@ -1290,10 +1293,15 @@ Status DBImpl::FlushMemTableToOutputFile(bool* madeProgress,
12901293
return s;
12911294
}
12921295

1293-
void DBImpl::CompactRange(const ColumnFamilyHandle& column_family,
1294-
const Slice* begin, const Slice* end,
1295-
bool reduce_level, int target_level) {
1296-
FlushMemTable(FlushOptions());
1296+
Status DBImpl::CompactRange(const ColumnFamilyHandle& column_family,
1297+
const Slice* begin, const Slice* end,
1298+
bool reduce_level, int target_level) {
1299+
Status s = FlushMemTable(FlushOptions());
1300+
if (!s.ok()) {
1301+
LogFlush(options_.info_log);
1302+
return s;
1303+
}
1304+
12971305
int max_level_with_files = 1;
12981306
{
12991307
MutexLock l(&mutex_);
@@ -1309,16 +1317,22 @@ void DBImpl::CompactRange(const ColumnFamilyHandle& column_family,
13091317
// bottom-most level, the output level will be the same as input one
13101318
if (options_.compaction_style == kCompactionStyleUniversal ||
13111319
level == max_level_with_files) {
1312-
RunManualCompaction(level, level, begin, end);
1320+
s = RunManualCompaction(level, level, begin, end);
13131321
} else {
1314-
RunManualCompaction(level, level + 1, begin, end);
1322+
s = RunManualCompaction(level, level + 1, begin, end);
1323+
}
1324+
if (!s.ok()) {
1325+
LogFlush(options_.info_log);
1326+
return s;
13151327
}
13161328
}
13171329

13181330
if (reduce_level) {
1319-
ReFitLevel(max_level_with_files, target_level);
1331+
s = ReFitLevel(max_level_with_files, target_level);
13201332
}
13211333
LogFlush(options_.info_log);
1334+
1335+
return s;
13221336
}
13231337

13241338
// return the same level if it cannot be moved
@@ -1337,7 +1351,7 @@ int DBImpl::FindMinimumEmptyLevelFitting(int level) {
13371351
return minimum_level;
13381352
}
13391353

1340-
void DBImpl::ReFitLevel(int level, int target_level) {
1354+
Status DBImpl::ReFitLevel(int level, int target_level) {
13411355
assert(level < NumberLevels());
13421356

13431357
SuperVersion* superversion_to_free = nullptr;
@@ -1351,7 +1365,7 @@ void DBImpl::ReFitLevel(int level, int target_level) {
13511365
mutex_.Unlock();
13521366
Log(options_.info_log, "ReFitLevel: another thread is refitting");
13531367
delete new_superversion;
1354-
return;
1368+
return Status::NotSupported("another thread is refitting");
13551369
}
13561370
refitting_level_ = true;
13571371

@@ -1372,6 +1386,7 @@ void DBImpl::ReFitLevel(int level, int target_level) {
13721386

13731387
assert(to_level <= level);
13741388

1389+
Status status;
13751390
if (to_level < level) {
13761391
Log(options_.info_log, "Before refitting:\n%s",
13771392
versions_->current()->DebugString().data());
@@ -1385,7 +1400,7 @@ void DBImpl::ReFitLevel(int level, int target_level) {
13851400
Log(options_.info_log, "Apply version edit:\n%s",
13861401
edit.DebugString().data());
13871402

1388-
auto status = versions_->LogAndApply(&edit, &mutex_);
1403+
status = versions_->LogAndApply(&edit, &mutex_);
13891404
superversion_to_free = InstallSuperVersion(new_superversion);
13901405
new_superversion = nullptr;
13911406

@@ -1403,6 +1418,7 @@ void DBImpl::ReFitLevel(int level, int target_level) {
14031418
mutex_.Unlock();
14041419
delete superversion_to_free;
14051420
delete new_superversion;
1421+
return status;
14061422
}
14071423

14081424
int DBImpl::NumberLevels(const ColumnFamilyHandle& column_family) {
@@ -1417,6 +1433,10 @@ int DBImpl::Level0StopWriteTrigger(const ColumnFamilyHandle& column_family) {
14171433
return options_.level0_stop_writes_trigger;
14181434
}
14191435

1436+
uint64_t DBImpl::CurrentVersionNumber() const {
1437+
return super_version_number_.load();
1438+
}
1439+
14201440
Status DBImpl::Flush(const FlushOptions& options,
14211441
const ColumnFamilyHandle& column_family) {
14221442
Status status = FlushMemTable(options);
@@ -1612,10 +1632,10 @@ Status DBImpl::AppendSortedWalsOfType(const std::string& path,
16121632
return status;
16131633
}
16141634

1615-
void DBImpl::RunManualCompaction(int input_level,
1616-
int output_level,
1617-
const Slice* begin,
1618-
const Slice* end) {
1635+
Status DBImpl::RunManualCompaction(int input_level,
1636+
int output_level,
1637+
const Slice* begin,
1638+
const Slice* end) {
16191639
assert(input_level >= 0);
16201640

16211641
InternalKey begin_storage, end_storage;
@@ -1682,15 +1702,16 @@ void DBImpl::RunManualCompaction(int input_level,
16821702
assert(!manual.in_progress);
16831703
assert(bg_manual_only_ > 0);
16841704
--bg_manual_only_;
1705+
return manual.status;
16851706
}
16861707

1687-
void DBImpl::TEST_CompactRange(int level,
1688-
const Slice* begin,
1689-
const Slice* end) {
1708+
Status DBImpl::TEST_CompactRange(int level,
1709+
const Slice* begin,
1710+
const Slice* end) {
16901711
int output_level = (options_.compaction_style == kCompactionStyleUniversal)
16911712
? level
16921713
: level + 1;
1693-
RunManualCompaction(level, output_level, begin, end);
1714+
return RunManualCompaction(level, output_level, begin, end);
16941715
}
16951716

16961717
Status DBImpl::FlushMemTable(const FlushOptions& options) {
@@ -1989,6 +2010,7 @@ Status DBImpl::BackgroundCompaction(bool* madeProgress,
19892010
if (is_manual) {
19902011
ManualCompaction* m = manual_compaction_;
19912012
if (!status.ok()) {
2013+
m->status = status;
19922014
m->done = true;
19932015
}
19942016
// For universal compaction:
@@ -2657,11 +2679,14 @@ static void CleanupIteratorState(void* arg1, void* arg2) {
26572679
deletion_state.memtables_to_free.push_back(m);
26582680
}
26592681
}
2660-
state->version->Unref();
2682+
if (state->version) { // not set for memtable-only iterator
2683+
state->version->Unref();
2684+
}
26612685
// fast path FindObsoleteFiles
26622686
state->db->FindObsoleteFiles(deletion_state, false, true);
26632687
state->mu->Unlock();
26642688
state->db->PurgeObsoleteFiles(deletion_state);
2689+
26652690
delete state;
26662691
}
26672692
} // namespace
@@ -2683,18 +2708,20 @@ Iterator* DBImpl::NewInternalIterator(const ReadOptions& options,
26832708
for (unsigned int i = 0; i < immutables.size(); i++) {
26842709
immutables[i]->Ref();
26852710
}
2686-
// Collect iterators for files in L0 - Ln
26872711
versions_->current()->Ref();
26882712
version = versions_->current();
26892713
mutex_.Unlock();
26902714

26912715
std::vector<Iterator*> list;
26922716
list.push_back(mutable_mem->NewIterator(options));
26932717
cleanup->mem.push_back(mutable_mem);
2718+
2719+
// Collect all needed child iterators for immutable memtables
26942720
for (MemTable* m : immutables) {
26952721
list.push_back(m->NewIterator(options));
26962722
cleanup->mem.push_back(m);
26972723
}
2724+
// Collect iterators for files in L0 - Ln
26982725
version->AddIterators(options, storage_options_, &list);
26992726
Iterator* internal_iter =
27002727
NewMergingIterator(&internal_comparator_, &list[0], list.size());
@@ -2711,6 +2738,66 @@ Iterator* DBImpl::TEST_NewInternalIterator() {
27112738
return NewInternalIterator(ReadOptions(), &ignored);
27122739
}
27132740

2741+
std::pair<Iterator*, Iterator*> DBImpl::GetTailingIteratorPair(
2742+
const ReadOptions& options,
2743+
uint64_t* superversion_number) {
2744+
2745+
MemTable* mutable_mem;
2746+
std::vector<MemTable*> immutables;
2747+
Version* version;
2748+
2749+
immutables.reserve(options_.max_write_buffer_number);
2750+
2751+
// get all child iterators and bump their refcounts under lock
2752+
mutex_.Lock();
2753+
mutable_mem = mem_;
2754+
mutable_mem->Ref();
2755+
imm_.GetMemTables(&immutables);
2756+
for (size_t i = 0; i < immutables.size(); ++i) {
2757+
immutables[i]->Ref();
2758+
}
2759+
version = versions_->current();
2760+
version->Ref();
2761+
if (superversion_number != nullptr) {
2762+
*superversion_number = CurrentVersionNumber();
2763+
}
2764+
mutex_.Unlock();
2765+
2766+
Iterator* mutable_iter = mutable_mem->NewIterator(options);
2767+
IterState* mutable_cleanup = new IterState();
2768+
mutable_cleanup->mem.push_back(mutable_mem);
2769+
mutable_cleanup->db = this;
2770+
mutable_cleanup->mu = &mutex_;
2771+
mutable_iter->RegisterCleanup(CleanupIteratorState, mutable_cleanup, nullptr);
2772+
2773+
// create a DBIter that only uses memtable content; see NewIterator()
2774+
mutable_iter = NewDBIterator(&dbname_, env_, options_, user_comparator(),
2775+
mutable_iter, kMaxSequenceNumber);
2776+
2777+
Iterator* immutable_iter;
2778+
IterState* immutable_cleanup = new IterState();
2779+
std::vector<Iterator*> list;
2780+
for (MemTable* m : immutables) {
2781+
list.push_back(m->NewIterator(options));
2782+
immutable_cleanup->mem.push_back(m);
2783+
}
2784+
version->AddIterators(options, storage_options_, &list);
2785+
immutable_cleanup->version = version;
2786+
immutable_cleanup->db = this;
2787+
immutable_cleanup->mu = &mutex_;
2788+
2789+
immutable_iter =
2790+
NewMergingIterator(&internal_comparator_, &list[0], list.size());
2791+
immutable_iter->RegisterCleanup(CleanupIteratorState, immutable_cleanup,
2792+
nullptr);
2793+
2794+
// create a DBIter that only uses memtable content; see NewIterator()
2795+
immutable_iter = NewDBIterator(&dbname_, env_, options_, user_comparator(),
2796+
immutable_iter, kMaxSequenceNumber);
2797+
2798+
return std::make_pair(mutable_iter, immutable_iter);
2799+
}
2800+
27142801
int64_t DBImpl::TEST_MaxNextLevelOverlappingBytes() {
27152802
MutexLock l(&mutex_);
27162803
return versions_->current()->MaxNextLevelOverlappingBytes();
@@ -2753,6 +2840,7 @@ DBImpl::SuperVersion* DBImpl::InstallSuperVersion(
27532840
new_superversion->Init(mem_, imm_, versions_->current());
27542841
SuperVersion* old_superversion = super_version_;
27552842
super_version_ = new_superversion;
2843+
++super_version_number_;
27562844
if (old_superversion != nullptr && old_superversion->Unref()) {
27572845
old_superversion->Cleanup();
27582846
return old_superversion; // will let caller delete outside of mutex
@@ -2975,13 +3063,21 @@ bool DBImpl::KeyMayExist(const ReadOptions& options,
29753063

29763064
Iterator* DBImpl::NewIterator(const ReadOptions& options,
29773065
const ColumnFamilyHandle& column_family) {
2978-
SequenceNumber latest_snapshot;
2979-
Iterator* iter = NewInternalIterator(options, &latest_snapshot);
2980-
iter = NewDBIterator(
2981-
&dbname_, env_, options_, user_comparator(), iter,
2982-
(options.snapshot != nullptr
2983-
? reinterpret_cast<const SnapshotImpl*>(options.snapshot)->number_
2984-
: latest_snapshot));
3066+
Iterator* iter;
3067+
3068+
if (options.tailing) {
3069+
iter = new TailingIterator(this, options, user_comparator());
3070+
} else {
3071+
SequenceNumber latest_snapshot;
3072+
iter = NewInternalIterator(options, &latest_snapshot);
3073+
3074+
iter = NewDBIterator(
3075+
&dbname_, env_, options_, user_comparator(), iter,
3076+
(options.snapshot != nullptr
3077+
? reinterpret_cast<const SnapshotImpl*>(options.snapshot)->number_
3078+
: latest_snapshot));
3079+
}
3080+
29853081
if (options.prefix) {
29863082
// use extra wrapper to exclude any keys from the results which
29873083
// don't begin with the prefix

0 commit comments

Comments
 (0)