Move compaction picker and internal key comparator to ColumnFamilyData
Summary: Compaction picker and internal key comparator are different for each column family (not global), so they should live in ColumnFamilyData Test Plan: make check Reviewers: dhruba, haobo CC: leveldb Differential Revision: https://reviews.facebook.net/D15801
This commit is contained in:
parent
5693db2a02
commit
f7489123e2
@ -14,6 +14,7 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include "db/version_set.h"
|
#include "db/version_set.h"
|
||||||
|
#include "db/compaction_picker.h"
|
||||||
|
|
||||||
namespace rocksdb {
|
namespace rocksdb {
|
||||||
|
|
||||||
@ -65,6 +66,7 @@ ColumnFamilyData::ColumnFamilyData(uint32_t id, const std::string& name,
|
|||||||
dummy_versions_(dummy_versions),
|
dummy_versions_(dummy_versions),
|
||||||
current_(nullptr),
|
current_(nullptr),
|
||||||
options_(options),
|
options_(options),
|
||||||
|
icmp_(options_.comparator),
|
||||||
mem_(nullptr),
|
mem_(nullptr),
|
||||||
imm_(options.min_write_buffer_number_to_merge),
|
imm_(options.min_write_buffer_number_to_merge),
|
||||||
super_version_(nullptr),
|
super_version_(nullptr),
|
||||||
@ -72,7 +74,13 @@ ColumnFamilyData::ColumnFamilyData(uint32_t id, const std::string& name,
|
|||||||
next_(nullptr),
|
next_(nullptr),
|
||||||
prev_(nullptr),
|
prev_(nullptr),
|
||||||
log_number_(0),
|
log_number_(0),
|
||||||
need_slowdown_for_num_level0_files_(false) {}
|
need_slowdown_for_num_level0_files_(false) {
|
||||||
|
if (options_.compaction_style == kCompactionStyleUniversal) {
|
||||||
|
compaction_picker_.reset(new UniversalCompactionPicker(&options_, &icmp_));
|
||||||
|
} else {
|
||||||
|
compaction_picker_.reset(new LevelCompactionPicker(&options_, &icmp_));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ColumnFamilyData::~ColumnFamilyData() {
|
ColumnFamilyData::~ColumnFamilyData() {
|
||||||
if (super_version_ != nullptr) {
|
if (super_version_ != nullptr) {
|
||||||
@ -114,6 +122,18 @@ void ColumnFamilyData::CreateNewMemtable() {
|
|||||||
mem_->Ref();
|
mem_->Ref();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Compaction* ColumnFamilyData::PickCompaction() {
|
||||||
|
return compaction_picker_->PickCompaction(current_);
|
||||||
|
}
|
||||||
|
|
||||||
|
Compaction* ColumnFamilyData::CompactRange(int input_level, int output_level,
|
||||||
|
const InternalKey* begin,
|
||||||
|
const InternalKey* end,
|
||||||
|
InternalKey** compaction_end) {
|
||||||
|
return compaction_picker_->CompactRange(current_, input_level, output_level,
|
||||||
|
begin, end, compaction_end);
|
||||||
|
}
|
||||||
|
|
||||||
SuperVersion* ColumnFamilyData::InstallSuperVersion(
|
SuperVersion* ColumnFamilyData::InstallSuperVersion(
|
||||||
SuperVersion* new_superversion) {
|
SuperVersion* new_superversion) {
|
||||||
new_superversion->Init(mem_, imm_.current(), current_);
|
new_superversion->Init(mem_, imm_.current(), current_);
|
||||||
|
@ -23,6 +23,9 @@ class Version;
|
|||||||
class VersionSet;
|
class VersionSet;
|
||||||
class MemTable;
|
class MemTable;
|
||||||
class MemTableListVersion;
|
class MemTableListVersion;
|
||||||
|
class CompactionPicker;
|
||||||
|
class Compaction;
|
||||||
|
class InternalKey;
|
||||||
|
|
||||||
// holds references to memtable, all immutable memtables and version
|
// holds references to memtable, all immutable memtables and version
|
||||||
struct SuperVersion {
|
struct SuperVersion {
|
||||||
@ -62,6 +65,8 @@ class ColumnFamilyData {
|
|||||||
uint32_t GetID() const { return id_; }
|
uint32_t GetID() const { return id_; }
|
||||||
const std::string& GetName() { return name_; }
|
const std::string& GetName() { return name_; }
|
||||||
|
|
||||||
|
int NumberLevels() const { return options_.num_levels; }
|
||||||
|
|
||||||
void SetLogNumber(uint64_t log_number) { log_number_ = log_number; }
|
void SetLogNumber(uint64_t log_number) { log_number_ = log_number; }
|
||||||
uint64_t GetLogNumber() const { return log_number_; }
|
uint64_t GetLogNumber() const { return log_number_; }
|
||||||
|
|
||||||
@ -75,6 +80,17 @@ class ColumnFamilyData {
|
|||||||
void SetCurrent(Version* current);
|
void SetCurrent(Version* current);
|
||||||
void CreateNewMemtable();
|
void CreateNewMemtable();
|
||||||
|
|
||||||
|
// See documentation in compaction_picker.h
|
||||||
|
Compaction* PickCompaction();
|
||||||
|
Compaction* CompactRange(int input_level, int output_level,
|
||||||
|
const InternalKey* begin, const InternalKey* end,
|
||||||
|
InternalKey** compaction_end);
|
||||||
|
|
||||||
|
CompactionPicker* compaction_picker() const {
|
||||||
|
return compaction_picker_.get();
|
||||||
|
}
|
||||||
|
const InternalKeyComparator& internal_comparator() const { return icmp_; }
|
||||||
|
|
||||||
SuperVersion* GetSuperVersion() const { return super_version_; }
|
SuperVersion* GetSuperVersion() const { return super_version_; }
|
||||||
uint64_t GetSuperVersionNumber() const {
|
uint64_t GetSuperVersionNumber() const {
|
||||||
return super_version_number_.load();
|
return super_version_number_.load();
|
||||||
@ -102,6 +118,8 @@ class ColumnFamilyData {
|
|||||||
Version* current_; // == dummy_versions->prev_
|
Version* current_; // == dummy_versions->prev_
|
||||||
ColumnFamilyOptions options_;
|
ColumnFamilyOptions options_;
|
||||||
|
|
||||||
|
const InternalKeyComparator icmp_;
|
||||||
|
|
||||||
MemTable* mem_;
|
MemTable* mem_;
|
||||||
MemTableList imm_;
|
MemTableList imm_;
|
||||||
SuperVersion* super_version_;
|
SuperVersion* super_version_;
|
||||||
@ -124,6 +142,10 @@ class ColumnFamilyData {
|
|||||||
// A flag indicating whether we should delay writes because
|
// A flag indicating whether we should delay writes because
|
||||||
// we have too many level 0 files
|
// we have too many level 0 files
|
||||||
bool need_slowdown_for_num_level0_files_;
|
bool need_slowdown_for_num_level0_files_;
|
||||||
|
|
||||||
|
// An object that keeps all the compaction stats
|
||||||
|
// and picks the next compaction
|
||||||
|
std::unique_ptr<CompactionPicker> compaction_picker_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Thread safe only for reading without a writer. All access should be
|
// Thread safe only for reading without a writer. All access should be
|
||||||
|
@ -41,7 +41,7 @@ uint64_t MultiplyCheckOverflow(uint64_t op1, int op2) {
|
|||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
CompactionPicker::CompactionPicker(const Options* options,
|
CompactionPicker::CompactionPicker(const ColumnFamilyOptions* options,
|
||||||
const InternalKeyComparator* icmp)
|
const InternalKeyComparator* icmp)
|
||||||
: compactions_in_progress_(options->num_levels),
|
: compactions_in_progress_(options->num_levels),
|
||||||
options_(options),
|
options_(options),
|
||||||
|
@ -24,7 +24,8 @@ class Version;
|
|||||||
|
|
||||||
class CompactionPicker {
|
class CompactionPicker {
|
||||||
public:
|
public:
|
||||||
CompactionPicker(const Options* options, const InternalKeyComparator* icmp);
|
CompactionPicker(const ColumnFamilyOptions* options,
|
||||||
|
const InternalKeyComparator* icmp);
|
||||||
virtual ~CompactionPicker();
|
virtual ~CompactionPicker();
|
||||||
|
|
||||||
// Pick level and inputs for a new compaction.
|
// Pick level and inputs for a new compaction.
|
||||||
@ -115,7 +116,7 @@ class CompactionPicker {
|
|||||||
// Per-level max bytes
|
// Per-level max bytes
|
||||||
std::unique_ptr<uint64_t[]> level_max_bytes_;
|
std::unique_ptr<uint64_t[]> level_max_bytes_;
|
||||||
|
|
||||||
const Options* const options_;
|
const ColumnFamilyOptions* const options_;
|
||||||
private:
|
private:
|
||||||
int num_levels_;
|
int num_levels_;
|
||||||
|
|
||||||
@ -124,7 +125,7 @@ class CompactionPicker {
|
|||||||
|
|
||||||
class UniversalCompactionPicker : public CompactionPicker {
|
class UniversalCompactionPicker : public CompactionPicker {
|
||||||
public:
|
public:
|
||||||
UniversalCompactionPicker(const Options* options,
|
UniversalCompactionPicker(const ColumnFamilyOptions* options,
|
||||||
const InternalKeyComparator* icmp)
|
const InternalKeyComparator* icmp)
|
||||||
: CompactionPicker(options, icmp) {}
|
: CompactionPicker(options, icmp) {}
|
||||||
virtual Compaction* PickCompaction(Version* version) override;
|
virtual Compaction* PickCompaction(Version* version) override;
|
||||||
@ -141,7 +142,7 @@ class UniversalCompactionPicker : public CompactionPicker {
|
|||||||
|
|
||||||
class LevelCompactionPicker : public CompactionPicker {
|
class LevelCompactionPicker : public CompactionPicker {
|
||||||
public:
|
public:
|
||||||
LevelCompactionPicker(const Options* options,
|
LevelCompactionPicker(const ColumnFamilyOptions* options,
|
||||||
const InternalKeyComparator* icmp)
|
const InternalKeyComparator* icmp)
|
||||||
: CompactionPicker(options, icmp) {}
|
: CompactionPicker(options, icmp) {}
|
||||||
virtual Compaction* PickCompaction(Version* version) override;
|
virtual Compaction* PickCompaction(Version* version) override;
|
||||||
|
@ -1312,7 +1312,10 @@ int DBImpl::FindMinimumEmptyLevelFitting(int level) {
|
|||||||
// stop if level i is not empty
|
// stop if level i is not empty
|
||||||
if (current->NumLevelFiles(i) > 0) break;
|
if (current->NumLevelFiles(i) > 0) break;
|
||||||
// stop if level i is too small (cannot fit the level files)
|
// stop if level i is too small (cannot fit the level files)
|
||||||
if (versions_->MaxBytesForLevel(i) < current->NumLevelBytes(level)) break;
|
if (default_cfd_->compaction_picker()->MaxBytesForLevel(i) <
|
||||||
|
current->NumLevelBytes(level)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
minimum_level = i;
|
minimum_level = i;
|
||||||
}
|
}
|
||||||
@ -1943,8 +1946,8 @@ Status DBImpl::BackgroundCompaction(bool* madeProgress,
|
|||||||
if (is_manual) {
|
if (is_manual) {
|
||||||
ManualCompaction* m = manual_compaction_;
|
ManualCompaction* m = manual_compaction_;
|
||||||
assert(m->in_progress);
|
assert(m->in_progress);
|
||||||
c.reset(versions_->CompactRange(
|
c.reset(default_cfd_->CompactRange(m->input_level, m->output_level,
|
||||||
m->input_level, m->output_level, m->begin, m->end, &manual_end));
|
m->begin, m->end, &manual_end));
|
||||||
if (!c) {
|
if (!c) {
|
||||||
m->done = true;
|
m->done = true;
|
||||||
}
|
}
|
||||||
@ -1959,7 +1962,7 @@ Status DBImpl::BackgroundCompaction(bool* madeProgress,
|
|||||||
? "(end)"
|
? "(end)"
|
||||||
: manual_end->DebugString().c_str()));
|
: manual_end->DebugString().c_str()));
|
||||||
} else if (!options_.disable_auto_compactions) {
|
} else if (!options_.disable_auto_compactions) {
|
||||||
c.reset(versions_->PickCompaction());
|
c.reset(default_cfd_->PickCompaction());
|
||||||
}
|
}
|
||||||
|
|
||||||
Status status;
|
Status status;
|
||||||
@ -1983,14 +1986,14 @@ Status DBImpl::BackgroundCompaction(bool* madeProgress,
|
|||||||
static_cast<unsigned long long>(f->number), c->level() + 1,
|
static_cast<unsigned long long>(f->number), c->level() + 1,
|
||||||
static_cast<unsigned long long>(f->file_size),
|
static_cast<unsigned long long>(f->file_size),
|
||||||
status.ToString().c_str(), default_cfd_->current()->LevelSummary(&tmp));
|
status.ToString().c_str(), default_cfd_->current()->LevelSummary(&tmp));
|
||||||
versions_->ReleaseCompactionFiles(c.get(), status);
|
default_cfd_->compaction_picker()->ReleaseCompactionFiles(c.get(), status);
|
||||||
*madeProgress = true;
|
*madeProgress = true;
|
||||||
} else {
|
} else {
|
||||||
MaybeScheduleFlushOrCompaction(); // do more compaction work in parallel.
|
MaybeScheduleFlushOrCompaction(); // do more compaction work in parallel.
|
||||||
CompactionState* compact = new CompactionState(c.get());
|
CompactionState* compact = new CompactionState(c.get());
|
||||||
status = DoCompactionWork(compact, deletion_state);
|
status = DoCompactionWork(compact, deletion_state);
|
||||||
CleanupCompaction(compact, status);
|
CleanupCompaction(compact, status);
|
||||||
versions_->ReleaseCompactionFiles(c.get(), status);
|
default_cfd_->compaction_picker()->ReleaseCompactionFiles(c.get(), status);
|
||||||
c->ReleaseInputs();
|
c->ReleaseInputs();
|
||||||
*madeProgress = true;
|
*madeProgress = true;
|
||||||
}
|
}
|
||||||
@ -2121,7 +2124,8 @@ Status DBImpl::OpenCompactionOutputFile(CompactionState* compact) {
|
|||||||
// Over-estimate slightly so we don't end up just barely crossing
|
// Over-estimate slightly so we don't end up just barely crossing
|
||||||
// the threshold.
|
// the threshold.
|
||||||
compact->outfile->SetPreallocationBlockSize(
|
compact->outfile->SetPreallocationBlockSize(
|
||||||
1.1 * versions_->MaxFileSizeForLevel(compact->compaction->output_level()));
|
1.1 * default_cfd_->compaction_picker()->MaxFileSizeForLevel(
|
||||||
|
compact->compaction->output_level()));
|
||||||
|
|
||||||
CompressionType compression_type = GetCompressionType(
|
CompressionType compression_type = GetCompressionType(
|
||||||
options_, compact->compaction->output_level(),
|
options_, compact->compaction->output_level(),
|
||||||
@ -3534,9 +3538,7 @@ bool DBImpl::GetProperty(const ColumnFamilyHandle& column_family,
|
|||||||
const Slice& property, std::string* value) {
|
const Slice& property, std::string* value) {
|
||||||
value->clear();
|
value->clear();
|
||||||
MutexLock l(&mutex_);
|
MutexLock l(&mutex_);
|
||||||
return internal_stats_.GetProperty(property, value, versions_.get(),
|
return internal_stats_.GetProperty(property, value, default_cfd_);
|
||||||
default_cfd_->current(),
|
|
||||||
default_cfd_->imm()->size());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DBImpl::GetApproximateSizes(const ColumnFamilyHandle& column_family,
|
void DBImpl::GetApproximateSizes(const ColumnFamilyHandle& column_family,
|
||||||
|
@ -8,14 +8,14 @@
|
|||||||
// found in the LICENSE file. See the AUTHORS file for names of contributors.
|
// found in the LICENSE file. See the AUTHORS file for names of contributors.
|
||||||
|
|
||||||
#include "db/internal_stats.h"
|
#include "db/internal_stats.h"
|
||||||
|
#include "db/column_family.h"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace rocksdb {
|
namespace rocksdb {
|
||||||
|
|
||||||
bool InternalStats::GetProperty(const Slice& property, std::string* value,
|
bool InternalStats::GetProperty(const Slice& property, std::string* value,
|
||||||
VersionSet* version_set, Version* current,
|
ColumnFamilyData* cfd) {
|
||||||
int immsize) {
|
|
||||||
Slice in = property;
|
Slice in = property;
|
||||||
Slice prefix("rocksdb.");
|
Slice prefix("rocksdb.");
|
||||||
if (!in.starts_with(prefix)) return false;
|
if (!in.starts_with(prefix)) return false;
|
||||||
@ -30,7 +30,7 @@ bool InternalStats::GetProperty(const Slice& property, std::string* value,
|
|||||||
} else {
|
} else {
|
||||||
char buf[100];
|
char buf[100];
|
||||||
snprintf(buf, sizeof(buf), "%d",
|
snprintf(buf, sizeof(buf), "%d",
|
||||||
current->NumLevelFiles(static_cast<int>(level)));
|
cfd->current()->NumLevelFiles(static_cast<int>(level)));
|
||||||
*value = buf;
|
*value = buf;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -43,8 +43,8 @@ bool InternalStats::GetProperty(const Slice& property, std::string* value,
|
|||||||
|
|
||||||
for (int level = 0; level < number_levels_; level++) {
|
for (int level = 0; level < number_levels_; level++) {
|
||||||
snprintf(buf, sizeof(buf), "%3d %8d %8.0f\n", level,
|
snprintf(buf, sizeof(buf), "%3d %8d %8.0f\n", level,
|
||||||
current->NumLevelFiles(level),
|
cfd->current()->NumLevelFiles(level),
|
||||||
current->NumLevelBytes(level) / 1048576.0);
|
cfd->current()->NumLevelBytes(level) / 1048576.0);
|
||||||
value->append(buf);
|
value->append(buf);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -87,7 +87,7 @@ bool InternalStats::GetProperty(const Slice& property, std::string* value,
|
|||||||
);
|
);
|
||||||
value->append(buf);
|
value->append(buf);
|
||||||
for (int level = 0; level < number_levels_; level++) {
|
for (int level = 0; level < number_levels_; level++) {
|
||||||
int files = current->NumLevelFiles(level);
|
int files = cfd->current()->NumLevelFiles(level);
|
||||||
if (compaction_stats_[level].micros > 0 || files > 0) {
|
if (compaction_stats_[level].micros > 0 || files > 0) {
|
||||||
int64_t bytes_read = compaction_stats_[level].bytes_readn +
|
int64_t bytes_read = compaction_stats_[level].bytes_readn +
|
||||||
compaction_stats_[level].bytes_readnp1;
|
compaction_stats_[level].bytes_readnp1;
|
||||||
@ -117,9 +117,9 @@ bool InternalStats::GetProperty(const Slice& property, std::string* value,
|
|||||||
"%3d %8d %8.0f %5.1f %9.0f %9.0f %9.0f %9.0f %9.0f %9.0f "
|
"%3d %8d %8.0f %5.1f %9.0f %9.0f %9.0f %9.0f %9.0f %9.0f "
|
||||||
"%10.1f %9.1f %11.1f %8d %8d %8d %8d %8d %8d %9.1f %9.1f "
|
"%10.1f %9.1f %11.1f %8d %8d %8d %8d %8d %8d %9.1f %9.1f "
|
||||||
"%9lu\n",
|
"%9lu\n",
|
||||||
level, files, current->NumLevelBytes(level) / 1048576.0,
|
level, files, cfd->current()->NumLevelBytes(level) / 1048576.0,
|
||||||
current->NumLevelBytes(level) /
|
cfd->current()->NumLevelBytes(level) /
|
||||||
version_set->MaxBytesForLevel(level),
|
cfd->compaction_picker()->MaxBytesForLevel(level),
|
||||||
compaction_stats_[level].micros / 1e6, bytes_read / 1048576.0,
|
compaction_stats_[level].micros / 1e6, bytes_read / 1048576.0,
|
||||||
compaction_stats_[level].bytes_written / 1048576.0,
|
compaction_stats_[level].bytes_written / 1048576.0,
|
||||||
compaction_stats_[level].bytes_readn / 1048576.0,
|
compaction_stats_[level].bytes_readn / 1048576.0,
|
||||||
@ -285,10 +285,10 @@ bool InternalStats::GetProperty(const Slice& property, std::string* value,
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
} else if (in == "sstables") {
|
} else if (in == "sstables") {
|
||||||
*value = current->DebugString();
|
*value = cfd->current()->DebugString();
|
||||||
return true;
|
return true;
|
||||||
} else if (in == "num-immutable-mem-table") {
|
} else if (in == "num-immutable-mem-table") {
|
||||||
*value = std::to_string(immsize);
|
*value = std::to_string(cfd->imm()->size());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,8 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
class ColumnFamilyData;
|
||||||
|
|
||||||
namespace rocksdb {
|
namespace rocksdb {
|
||||||
class InternalStats {
|
class InternalStats {
|
||||||
public:
|
public:
|
||||||
@ -100,7 +102,7 @@ class InternalStats {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool GetProperty(const Slice& property, std::string* value,
|
bool GetProperty(const Slice& property, std::string* value,
|
||||||
VersionSet* version_set, Version* current, int immsize);
|
ColumnFamilyData* cfd);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<CompactionStats> compaction_stats_;
|
std::vector<CompactionStats> compaction_stats_;
|
||||||
|
@ -409,8 +409,10 @@ static bool NewestFirstBySeqNo(FileMetaData* a, FileMetaData* b) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Version::Version(VersionSet* vset, uint64_t version_number)
|
Version::Version(ColumnFamilyData* cfd, VersionSet* vset,
|
||||||
: vset_(vset),
|
uint64_t version_number)
|
||||||
|
: cfd_(cfd),
|
||||||
|
vset_(vset),
|
||||||
next_(this),
|
next_(this),
|
||||||
prev_(this),
|
prev_(this),
|
||||||
refs_(0),
|
refs_(0),
|
||||||
@ -434,7 +436,7 @@ void Version::Get(const ReadOptions& options,
|
|||||||
bool* value_found) {
|
bool* value_found) {
|
||||||
Slice ikey = k.internal_key();
|
Slice ikey = k.internal_key();
|
||||||
Slice user_key = k.user_key();
|
Slice user_key = k.user_key();
|
||||||
const Comparator* ucmp = vset_->icmp_.user_comparator();
|
const Comparator* ucmp = cfd_->internal_comparator().user_comparator();
|
||||||
|
|
||||||
auto merge_operator = db_options.merge_operator.get();
|
auto merge_operator = db_options.merge_operator.get();
|
||||||
auto logger = db_options.info_log;
|
auto logger = db_options.info_log;
|
||||||
@ -481,7 +483,7 @@ void Version::Get(const ReadOptions& options,
|
|||||||
// On Level-n (n>=1), files are sorted.
|
// On Level-n (n>=1), files are sorted.
|
||||||
// Binary search to find earliest index whose largest key >= ikey.
|
// Binary search to find earliest index whose largest key >= ikey.
|
||||||
// We will also stop when the file no longer overlaps ikey
|
// We will also stop when the file no longer overlaps ikey
|
||||||
start_index = FindFile(vset_->icmp_, files_[level], ikey);
|
start_index = FindFile(cfd_->internal_comparator(), files_[level], ikey);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Traverse each relevant file to find the desired key
|
// Traverse each relevant file to find the desired key
|
||||||
@ -507,11 +509,12 @@ void Version::Get(const ReadOptions& options,
|
|||||||
// Sanity check to make sure that the files are correctly sorted
|
// Sanity check to make sure that the files are correctly sorted
|
||||||
if (prev_file) {
|
if (prev_file) {
|
||||||
if (level != 0) {
|
if (level != 0) {
|
||||||
int comp_sign = vset_->icmp_.Compare(prev_file->largest, f->smallest);
|
int comp_sign = cfd_->internal_comparator().Compare(
|
||||||
|
prev_file->largest, f->smallest);
|
||||||
assert(comp_sign < 0);
|
assert(comp_sign < 0);
|
||||||
} else {
|
} else {
|
||||||
// level == 0, the current file cannot be newer than the previous one.
|
// level == 0, the current file cannot be newer than the previous one.
|
||||||
if (vset_->options_->compaction_style == kCompactionStyleUniversal) {
|
if (cfd_->options()->compaction_style == kCompactionStyleUniversal) {
|
||||||
assert(!NewestFirstBySeqNo(f, prev_file));
|
assert(!NewestFirstBySeqNo(f, prev_file));
|
||||||
} else {
|
} else {
|
||||||
assert(!NewestFirst(f, prev_file));
|
assert(!NewestFirst(f, prev_file));
|
||||||
@ -597,7 +600,7 @@ bool Version::UpdateStats(const GetStats& stats) {
|
|||||||
|
|
||||||
void Version::Finalize(std::vector<uint64_t>& size_being_compacted) {
|
void Version::Finalize(std::vector<uint64_t>& size_being_compacted) {
|
||||||
// Pre-sort level0 for Get()
|
// Pre-sort level0 for Get()
|
||||||
if (vset_->options_->compaction_style == kCompactionStyleUniversal) {
|
if (cfd_->options()->compaction_style == kCompactionStyleUniversal) {
|
||||||
std::sort(files_[0].begin(), files_[0].end(), NewestFirstBySeqNo);
|
std::sort(files_[0].begin(), files_[0].end(), NewestFirstBySeqNo);
|
||||||
} else {
|
} else {
|
||||||
std::sort(files_[0].begin(), files_[0].end(), NewestFirst);
|
std::sort(files_[0].begin(), files_[0].end(), NewestFirst);
|
||||||
@ -607,7 +610,7 @@ void Version::Finalize(std::vector<uint64_t>& size_being_compacted) {
|
|||||||
int max_score_level = 0;
|
int max_score_level = 0;
|
||||||
|
|
||||||
int num_levels_to_check =
|
int num_levels_to_check =
|
||||||
(vset_->options_->compaction_style != kCompactionStyleUniversal)
|
(cfd_->options()->compaction_style != kCompactionStyleUniversal)
|
||||||
? NumberLevels() - 1
|
? NumberLevels() - 1
|
||||||
: 1;
|
: 1;
|
||||||
|
|
||||||
@ -633,15 +636,15 @@ void Version::Finalize(std::vector<uint64_t>& size_being_compacted) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If we are slowing down writes, then we better compact that first
|
// If we are slowing down writes, then we better compact that first
|
||||||
if (numfiles >= vset_->options_->level0_stop_writes_trigger) {
|
if (numfiles >= cfd_->options()->level0_stop_writes_trigger) {
|
||||||
score = 1000000;
|
score = 1000000;
|
||||||
// Log(options_->info_log, "XXX score l0 = 1000000000 max");
|
// Log(options_->info_log, "XXX score l0 = 1000000000 max");
|
||||||
} else if (numfiles >= vset_->options_->level0_slowdown_writes_trigger) {
|
} else if (numfiles >= cfd_->options()->level0_slowdown_writes_trigger) {
|
||||||
score = 10000;
|
score = 10000;
|
||||||
// Log(options_->info_log, "XXX score l0 = 1000000 medium");
|
// Log(options_->info_log, "XXX score l0 = 1000000 medium");
|
||||||
} else {
|
} else {
|
||||||
score = static_cast<double>(numfiles) /
|
score = static_cast<double>(numfiles) /
|
||||||
vset_->options_->level0_file_num_compaction_trigger;
|
cfd_->options()->level0_file_num_compaction_trigger;
|
||||||
if (score >= 1) {
|
if (score >= 1) {
|
||||||
// Log(options_->info_log, "XXX score l0 = %d least", (int)score);
|
// Log(options_->info_log, "XXX score l0 = %d least", (int)score);
|
||||||
}
|
}
|
||||||
@ -650,7 +653,8 @@ void Version::Finalize(std::vector<uint64_t>& size_being_compacted) {
|
|||||||
// Compute the ratio of current size to size limit.
|
// Compute the ratio of current size to size limit.
|
||||||
const uint64_t level_bytes =
|
const uint64_t level_bytes =
|
||||||
TotalFileSize(files_[level]) - size_being_compacted[level];
|
TotalFileSize(files_[level]) - size_being_compacted[level];
|
||||||
score = static_cast<double>(level_bytes) / vset_->MaxBytesForLevel(level);
|
score = static_cast<double>(level_bytes) /
|
||||||
|
cfd_->compaction_picker()->MaxBytesForLevel(level);
|
||||||
if (score > 1) {
|
if (score > 1) {
|
||||||
// Log(options_->info_log, "XXX score l%d = %d ", level, (int)score);
|
// Log(options_->info_log, "XXX score l%d = %d ", level, (int)score);
|
||||||
}
|
}
|
||||||
@ -708,7 +712,7 @@ bool CompareSeqnoDescending(const Version::Fsize& first,
|
|||||||
void Version::UpdateFilesBySize() {
|
void Version::UpdateFilesBySize() {
|
||||||
// No need to sort the highest level because it is never compacted.
|
// No need to sort the highest level because it is never compacted.
|
||||||
int max_level =
|
int max_level =
|
||||||
(vset_->options_->compaction_style == kCompactionStyleUniversal)
|
(cfd_->options()->compaction_style == kCompactionStyleUniversal)
|
||||||
? NumberLevels()
|
? NumberLevels()
|
||||||
: NumberLevels() - 1;
|
: NumberLevels() - 1;
|
||||||
|
|
||||||
@ -725,7 +729,7 @@ void Version::UpdateFilesBySize() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// sort the top number_of_files_to_sort_ based on file size
|
// sort the top number_of_files_to_sort_ based on file size
|
||||||
if (vset_->options_->compaction_style == kCompactionStyleUniversal) {
|
if (cfd_->options()->compaction_style == kCompactionStyleUniversal) {
|
||||||
int num = temp.size();
|
int num = temp.size();
|
||||||
std::partial_sort(temp.begin(), temp.begin() + num, temp.end(),
|
std::partial_sort(temp.begin(), temp.begin() + num, temp.end(),
|
||||||
CompareSeqnoDescending);
|
CompareSeqnoDescending);
|
||||||
@ -772,8 +776,9 @@ bool Version::NeedsCompaction() const {
|
|||||||
// TODO(sdong): improve this function to be accurate for universal
|
// TODO(sdong): improve this function to be accurate for universal
|
||||||
// compactions.
|
// compactions.
|
||||||
int num_levels_to_check =
|
int num_levels_to_check =
|
||||||
(vset_->options_->compaction_style != kCompactionStyleUniversal) ?
|
(cfd_->options()->compaction_style != kCompactionStyleUniversal)
|
||||||
NumberLevels() - 1 : 1;
|
? NumberLevels() - 1
|
||||||
|
: 1;
|
||||||
for (int i = 0; i < num_levels_to_check; i++) {
|
for (int i = 0; i < num_levels_to_check; i++) {
|
||||||
if (compaction_score_[i] >= 1) {
|
if (compaction_score_[i] >= 1) {
|
||||||
return true;
|
return true;
|
||||||
@ -785,8 +790,9 @@ bool Version::NeedsCompaction() const {
|
|||||||
bool Version::OverlapInLevel(int level,
|
bool Version::OverlapInLevel(int level,
|
||||||
const Slice* smallest_user_key,
|
const Slice* smallest_user_key,
|
||||||
const Slice* largest_user_key) {
|
const Slice* largest_user_key) {
|
||||||
return SomeFileOverlapsRange(vset_->icmp_, (level > 0), files_[level],
|
return SomeFileOverlapsRange(cfd_->internal_comparator(), (level > 0),
|
||||||
smallest_user_key, largest_user_key);
|
files_[level], smallest_user_key,
|
||||||
|
largest_user_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Version::PickLevelForMemTableOutput(
|
int Version::PickLevelForMemTableOutput(
|
||||||
@ -799,7 +805,7 @@ int Version::PickLevelForMemTableOutput(
|
|||||||
InternalKey start(smallest_user_key, kMaxSequenceNumber, kValueTypeForSeek);
|
InternalKey start(smallest_user_key, kMaxSequenceNumber, kValueTypeForSeek);
|
||||||
InternalKey limit(largest_user_key, 0, static_cast<ValueType>(0));
|
InternalKey limit(largest_user_key, 0, static_cast<ValueType>(0));
|
||||||
std::vector<FileMetaData*> overlaps;
|
std::vector<FileMetaData*> overlaps;
|
||||||
int max_mem_compact_level = vset_->options_->max_mem_compaction_level;
|
int max_mem_compact_level = cfd_->options()->max_mem_compaction_level;
|
||||||
while (max_mem_compact_level > 0 && level < max_mem_compact_level) {
|
while (max_mem_compact_level > 0 && level < max_mem_compact_level) {
|
||||||
if (OverlapInLevel(level + 1, &smallest_user_key, &largest_user_key)) {
|
if (OverlapInLevel(level + 1, &smallest_user_key, &largest_user_key)) {
|
||||||
break;
|
break;
|
||||||
@ -810,7 +816,7 @@ int Version::PickLevelForMemTableOutput(
|
|||||||
}
|
}
|
||||||
GetOverlappingInputs(level + 2, &start, &limit, &overlaps);
|
GetOverlappingInputs(level + 2, &start, &limit, &overlaps);
|
||||||
const uint64_t sum = TotalFileSize(overlaps);
|
const uint64_t sum = TotalFileSize(overlaps);
|
||||||
if (sum > vset_->compaction_picker_->MaxGrandParentOverlapBytes(level)) {
|
if (sum > cfd_->compaction_picker()->MaxGrandParentOverlapBytes(level)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
level++;
|
level++;
|
||||||
@ -841,7 +847,7 @@ void Version::GetOverlappingInputs(int level,
|
|||||||
if (file_index) {
|
if (file_index) {
|
||||||
*file_index = -1;
|
*file_index = -1;
|
||||||
}
|
}
|
||||||
const Comparator* user_cmp = vset_->icmp_.user_comparator();
|
const Comparator* user_cmp = cfd_->internal_comparator().user_comparator();
|
||||||
if (begin != nullptr && end != nullptr && level > 0) {
|
if (begin != nullptr && end != nullptr && level > 0) {
|
||||||
GetOverlappingInputsBinarySearch(level, user_begin, user_end, inputs,
|
GetOverlappingInputsBinarySearch(level, user_begin, user_end, inputs,
|
||||||
hint_index, file_index);
|
hint_index, file_index);
|
||||||
@ -893,7 +899,7 @@ void Version::GetOverlappingInputsBinarySearch(
|
|||||||
int mid = 0;
|
int mid = 0;
|
||||||
int max = files_[level].size() -1;
|
int max = files_[level].size() -1;
|
||||||
bool foundOverlap = false;
|
bool foundOverlap = false;
|
||||||
const Comparator* user_cmp = vset_->icmp_.user_comparator();
|
const Comparator* user_cmp = cfd_->internal_comparator().user_comparator();
|
||||||
|
|
||||||
// if the caller already knows the index of a file that has overlap,
|
// if the caller already knows the index of a file that has overlap,
|
||||||
// then we can skip the binary search.
|
// then we can skip the binary search.
|
||||||
@ -939,7 +945,7 @@ void Version::ExtendOverlappingInputs(
|
|||||||
std::vector<FileMetaData*>* inputs,
|
std::vector<FileMetaData*>* inputs,
|
||||||
unsigned int midIndex) {
|
unsigned int midIndex) {
|
||||||
|
|
||||||
const Comparator* user_cmp = vset_->icmp_.user_comparator();
|
const Comparator* user_cmp = cfd_->internal_comparator().user_comparator();
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
{
|
{
|
||||||
// assert that the file at midIndex overlaps with the range
|
// assert that the file at midIndex overlaps with the range
|
||||||
@ -1003,12 +1009,12 @@ bool Version::HasOverlappingUserKey(
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Comparator* user_cmp = vset_->icmp_.user_comparator();
|
const Comparator* user_cmp = cfd_->internal_comparator().user_comparator();
|
||||||
const std::vector<FileMetaData*>& files = files_[level];
|
const std::vector<FileMetaData*>& files = files_[level];
|
||||||
const size_t kNumFiles = files.size();
|
const size_t kNumFiles = files.size();
|
||||||
|
|
||||||
// Check the last file in inputs against the file after it
|
// Check the last file in inputs against the file after it
|
||||||
size_t last_file = FindFile(vset_->icmp_, files,
|
size_t last_file = FindFile(cfd_->internal_comparator(), files,
|
||||||
inputs->back()->largest.Encode());
|
inputs->back()->largest.Encode());
|
||||||
assert(0 <= last_file && last_file < kNumFiles); // File should exist!
|
assert(0 <= last_file && last_file < kNumFiles); // File should exist!
|
||||||
if (last_file < kNumFiles-1) { // If not the last file
|
if (last_file < kNumFiles-1) { // If not the last file
|
||||||
@ -1021,7 +1027,7 @@ bool Version::HasOverlappingUserKey(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check the first file in inputs against the file just before it
|
// Check the first file in inputs against the file just before it
|
||||||
size_t first_file = FindFile(vset_->icmp_, files,
|
size_t first_file = FindFile(cfd_->internal_comparator(), files,
|
||||||
inputs->front()->smallest.Encode());
|
inputs->front()->smallest.Encode());
|
||||||
assert(0 <= first_file && first_file <= last_file); // File should exist!
|
assert(0 <= first_file && first_file <= last_file); // File should exist!
|
||||||
if (first_file > 0) { // If not first file
|
if (first_file > 0) { // If not first file
|
||||||
@ -1164,17 +1170,17 @@ class VersionSet::Builder {
|
|||||||
FileSet* added_files;
|
FileSet* added_files;
|
||||||
};
|
};
|
||||||
|
|
||||||
VersionSet* vset_;
|
ColumnFamilyData* cfd_;
|
||||||
Version* base_;
|
Version* base_;
|
||||||
LevelState* levels_;
|
LevelState* levels_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Initialize a builder with the files from *base and other info from *vset
|
// Initialize a builder with the files from *base and other info from *vset
|
||||||
Builder(VersionSet* vset, Version* base) : vset_(vset), base_(base) {
|
Builder(ColumnFamilyData* cfd, Version* base) : cfd_(cfd), base_(base) {
|
||||||
base_->Ref();
|
base_->Ref();
|
||||||
levels_ = new LevelState[base->NumberLevels()];
|
levels_ = new LevelState[base->NumberLevels()];
|
||||||
BySmallestKey cmp;
|
BySmallestKey cmp;
|
||||||
cmp.internal_comparator = &vset_->icmp_;
|
cmp.internal_comparator = &cfd_->internal_comparator();
|
||||||
for (int level = 0; level < base->NumberLevels(); level++) {
|
for (int level = 0; level < base->NumberLevels(); level++) {
|
||||||
levels_[level].added_files = new FileSet(cmp);
|
levels_[level].added_files = new FileSet(cmp);
|
||||||
}
|
}
|
||||||
@ -1210,7 +1216,7 @@ class VersionSet::Builder {
|
|||||||
for (uint32_t i = 1; i < v->files_[level].size(); i++) {
|
for (uint32_t i = 1; i < v->files_[level].size(); i++) {
|
||||||
const InternalKey& prev_end = v->files_[level][i-1]->largest;
|
const InternalKey& prev_end = v->files_[level][i-1]->largest;
|
||||||
const InternalKey& this_begin = v->files_[level][i]->smallest;
|
const InternalKey& this_begin = v->files_[level][i]->smallest;
|
||||||
if (vset_->icmp_.Compare(prev_end, this_begin) >= 0) {
|
if (cfd_->internal_comparator().Compare(prev_end, this_begin) >= 0) {
|
||||||
fprintf(stderr, "overlapping ranges in same level %s vs. %s\n",
|
fprintf(stderr, "overlapping ranges in same level %s vs. %s\n",
|
||||||
prev_end.DebugString().c_str(),
|
prev_end.DebugString().c_str(),
|
||||||
this_begin.DebugString().c_str());
|
this_begin.DebugString().c_str());
|
||||||
@ -1315,7 +1321,7 @@ class VersionSet::Builder {
|
|||||||
CheckConsistency(base_);
|
CheckConsistency(base_);
|
||||||
CheckConsistency(v);
|
CheckConsistency(v);
|
||||||
BySmallestKey cmp;
|
BySmallestKey cmp;
|
||||||
cmp.internal_comparator = &vset_->icmp_;
|
cmp.internal_comparator = &cfd_->internal_comparator();
|
||||||
for (int level = 0; level < base_->NumberLevels(); level++) {
|
for (int level = 0; level < base_->NumberLevels(); level++) {
|
||||||
// Merge the set of added files with the set of pre-existing files.
|
// Merge the set of added files with the set of pre-existing files.
|
||||||
// Drop any deleted files. Store the result in *v.
|
// Drop any deleted files. Store the result in *v.
|
||||||
@ -1354,8 +1360,8 @@ class VersionSet::Builder {
|
|||||||
std::vector<FileMetaData*>* files = &v->files_[level];
|
std::vector<FileMetaData*>* files = &v->files_[level];
|
||||||
if (level > 0 && !files->empty()) {
|
if (level > 0 && !files->empty()) {
|
||||||
// Must not overlap
|
// Must not overlap
|
||||||
assert(vset_->icmp_.Compare((*files)[files->size()-1]->largest,
|
assert(cfd_->internal_comparator().Compare(
|
||||||
f->smallest) < 0);
|
(*files)[files->size() - 1]->largest, f->smallest) < 0);
|
||||||
}
|
}
|
||||||
f->refs++;
|
f->refs++;
|
||||||
files->push_back(f);
|
files->push_back(f);
|
||||||
@ -1382,11 +1388,6 @@ VersionSet::VersionSet(const std::string& dbname, const Options* options,
|
|||||||
manifest_file_size_(0),
|
manifest_file_size_(0),
|
||||||
storage_options_(storage_options),
|
storage_options_(storage_options),
|
||||||
storage_options_compactions_(storage_options_) {
|
storage_options_compactions_(storage_options_) {
|
||||||
if (options_->compaction_style == kCompactionStyleUniversal) {
|
|
||||||
compaction_picker_.reset(new UniversalCompactionPicker(options_, &icmp_));
|
|
||||||
} else {
|
|
||||||
compaction_picker_.reset(new LevelCompactionPicker(options_, &icmp_));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VersionSet::~VersionSet() {
|
VersionSet::~VersionSet() {
|
||||||
@ -1439,8 +1440,8 @@ Status VersionSet::LogAndApply(ColumnFamilyData* column_family_data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::vector<VersionEdit*> batch_edits;
|
std::vector<VersionEdit*> batch_edits;
|
||||||
Version* v = new Version(this, current_version_number_++);
|
Version* v = new Version(column_family_data, this, current_version_number_++);
|
||||||
Builder builder(this, column_family_data->current());
|
Builder builder(column_family_data, column_family_data->current());
|
||||||
|
|
||||||
// process all requests in the queue
|
// process all requests in the queue
|
||||||
ManifestWriter* last_writer = &w;
|
ManifestWriter* last_writer = &w;
|
||||||
@ -1483,7 +1484,8 @@ Status VersionSet::LogAndApply(ColumnFamilyData* column_family_data,
|
|||||||
{
|
{
|
||||||
// calculate the amount of data being compacted at every level
|
// calculate the amount of data being compacted at every level
|
||||||
std::vector<uint64_t> size_being_compacted(v->NumberLevels() - 1);
|
std::vector<uint64_t> size_being_compacted(v->NumberLevels() - 1);
|
||||||
compaction_picker_->SizeBeingCompacted(size_being_compacted);
|
column_family_data->compaction_picker()->SizeBeingCompacted(
|
||||||
|
size_being_compacted);
|
||||||
|
|
||||||
mu->Unlock();
|
mu->Unlock();
|
||||||
|
|
||||||
@ -1679,7 +1681,7 @@ Status VersionSet::Recover(
|
|||||||
} else {
|
} else {
|
||||||
ColumnFamilyData* default_cfd =
|
ColumnFamilyData* default_cfd =
|
||||||
CreateColumnFamily(default_cf_iter->second, &default_cf_edit);
|
CreateColumnFamily(default_cf_iter->second, &default_cf_edit);
|
||||||
builders.insert({0, new Builder(this, default_cfd->current())});
|
builders.insert({0, new Builder(default_cfd, default_cfd->current())});
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -1725,7 +1727,7 @@ Status VersionSet::Recover(
|
|||||||
ColumnFamilyData* new_cfd =
|
ColumnFamilyData* new_cfd =
|
||||||
CreateColumnFamily(cf_options->second, &edit);
|
CreateColumnFamily(cf_options->second, &edit);
|
||||||
builders.insert(
|
builders.insert(
|
||||||
{edit.column_family_, new Builder(this, new_cfd->current())});
|
{edit.column_family_, new Builder(new_cfd, new_cfd->current())});
|
||||||
}
|
}
|
||||||
} else if (edit.is_column_family_drop_) {
|
} else if (edit.is_column_family_drop_) {
|
||||||
if (cf_in_builders) {
|
if (cf_in_builders) {
|
||||||
@ -1815,12 +1817,12 @@ Status VersionSet::Recover(
|
|||||||
|
|
||||||
if (s.ok()) {
|
if (s.ok()) {
|
||||||
for (auto cfd : *column_family_set_) {
|
for (auto cfd : *column_family_set_) {
|
||||||
Version* v = new Version(this, current_version_number_++);
|
Version* v = new Version(cfd, this, current_version_number_++);
|
||||||
builders[cfd->GetID()]->SaveTo(v);
|
builders[cfd->GetID()]->SaveTo(v);
|
||||||
|
|
||||||
// Install recovered version
|
// Install recovered version
|
||||||
std::vector<uint64_t> size_being_compacted(v->NumberLevels() - 1);
|
std::vector<uint64_t> size_being_compacted(v->NumberLevels() - 1);
|
||||||
compaction_picker_->SizeBeingCompacted(size_being_compacted);
|
cfd->compaction_picker()->SizeBeingCompacted(size_being_compacted);
|
||||||
v->Finalize(size_being_compacted);
|
v->Finalize(size_being_compacted);
|
||||||
AppendVersion(cfd, v);
|
AppendVersion(cfd, v);
|
||||||
}
|
}
|
||||||
@ -2007,7 +2009,7 @@ Status VersionSet::DumpManifest(Options& options, std::string& dscname,
|
|||||||
uint64_t prev_log_number = 0;
|
uint64_t prev_log_number = 0;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
// TODO works only for default column family currently
|
// TODO works only for default column family currently
|
||||||
VersionSet::Builder builder(this,
|
VersionSet::Builder builder(column_family_set_->GetDefault(),
|
||||||
column_family_set_->GetDefault()->current());
|
column_family_set_->GetDefault()->current());
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -2084,7 +2086,7 @@ Status VersionSet::DumpManifest(Options& options, std::string& dscname,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (s.ok()) {
|
if (s.ok()) {
|
||||||
Version* v = new Version(this, 0);
|
Version* v = new Version(column_family_set_->GetDefault(), this, 0);
|
||||||
builder.SaveTo(v);
|
builder.SaveTo(v);
|
||||||
|
|
||||||
manifest_file_number_ = next_file;
|
manifest_file_number_ = next_file;
|
||||||
@ -2258,22 +2260,6 @@ void VersionSet::AddLiveFiles(std::vector<uint64_t>* live_list) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Compaction* VersionSet::PickCompaction() {
|
|
||||||
// TODO this only works for default column family now
|
|
||||||
Version* version = column_family_set_->GetDefault()->current();
|
|
||||||
return compaction_picker_->PickCompaction(version);
|
|
||||||
}
|
|
||||||
|
|
||||||
Compaction* VersionSet::CompactRange(int input_level, int output_level,
|
|
||||||
const InternalKey* begin,
|
|
||||||
const InternalKey* end,
|
|
||||||
InternalKey** compaction_end) {
|
|
||||||
// TODO this only works for default column family now
|
|
||||||
Version* version = column_family_set_->GetDefault()->current();
|
|
||||||
return compaction_picker_->CompactRange(version, input_level, output_level,
|
|
||||||
begin, end, compaction_end);
|
|
||||||
}
|
|
||||||
|
|
||||||
Iterator* VersionSet::MakeInputIterator(Compaction* c) {
|
Iterator* VersionSet::MakeInputIterator(Compaction* c) {
|
||||||
ReadOptions options;
|
ReadOptions options;
|
||||||
options.fill_cache = false;
|
options.fill_cache = false;
|
||||||
@ -2295,7 +2281,9 @@ Iterator* VersionSet::MakeInputIterator(Compaction* c) {
|
|||||||
} else {
|
} else {
|
||||||
// Create concatenating iterator for the files from this level
|
// Create concatenating iterator for the files from this level
|
||||||
list[num++] = NewTwoLevelIterator(
|
list[num++] = NewTwoLevelIterator(
|
||||||
new Version::LevelFileNumIterator(icmp_, c->inputs(which)),
|
new Version::LevelFileNumIterator(
|
||||||
|
c->input_version()->cfd_->internal_comparator(),
|
||||||
|
c->inputs(which)),
|
||||||
&GetFileIterator, table_cache_, options, storage_options_,
|
&GetFileIterator, table_cache_, options, storage_options_,
|
||||||
true /* for compaction */);
|
true /* for compaction */);
|
||||||
}
|
}
|
||||||
@ -2307,14 +2295,6 @@ Iterator* VersionSet::MakeInputIterator(Compaction* c) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
double VersionSet::MaxBytesForLevel(int level) {
|
|
||||||
return compaction_picker_->MaxBytesForLevel(level);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t VersionSet::MaxFileSizeForLevel(int level) {
|
|
||||||
return compaction_picker_->MaxFileSizeForLevel(level);
|
|
||||||
}
|
|
||||||
|
|
||||||
// verify that the files listed in this compaction are present
|
// verify that the files listed in this compaction are present
|
||||||
// in the current version
|
// in the current version
|
||||||
bool VersionSet::VerifyCompactionFileConsistency(Compaction* c) {
|
bool VersionSet::VerifyCompactionFileConsistency(Compaction* c) {
|
||||||
@ -2365,10 +2345,6 @@ bool VersionSet::VerifyCompactionFileConsistency(Compaction* c) {
|
|||||||
return true; // everything good
|
return true; // everything good
|
||||||
}
|
}
|
||||||
|
|
||||||
void VersionSet::ReleaseCompactionFiles(Compaction* c, Status status) {
|
|
||||||
compaction_picker_->ReleaseCompactionFiles(c, status);
|
|
||||||
}
|
|
||||||
|
|
||||||
Status VersionSet::GetMetadataForFile(uint64_t number, int* filelevel,
|
Status VersionSet::GetMetadataForFile(uint64_t number, int* filelevel,
|
||||||
FileMetaData* meta,
|
FileMetaData* meta,
|
||||||
ColumnFamilyData** cfd) {
|
ColumnFamilyData** cfd) {
|
||||||
@ -2415,11 +2391,11 @@ ColumnFamilyData* VersionSet::CreateColumnFamily(
|
|||||||
const ColumnFamilyOptions& options, VersionEdit* edit) {
|
const ColumnFamilyOptions& options, VersionEdit* edit) {
|
||||||
assert(edit->is_column_family_add_);
|
assert(edit->is_column_family_add_);
|
||||||
|
|
||||||
Version* dummy_versions = new Version(this);
|
Version* dummy_versions = new Version(nullptr, this);
|
||||||
auto new_cfd = column_family_set_->CreateColumnFamily(
|
auto new_cfd = column_family_set_->CreateColumnFamily(
|
||||||
edit->column_family_name_, edit->column_family_, dummy_versions, options);
|
edit->column_family_name_, edit->column_family_, dummy_versions, options);
|
||||||
|
|
||||||
AppendVersion(new_cfd, new Version(this, current_version_number_++));
|
AppendVersion(new_cfd, new Version(new_cfd, this, current_version_number_++));
|
||||||
new_cfd->CreateNewMemtable();
|
new_cfd->CreateNewMemtable();
|
||||||
return new_cfd;
|
return new_cfd;
|
||||||
}
|
}
|
||||||
|
@ -217,6 +217,7 @@ class Version {
|
|||||||
// record results in files_by_size_. The largest files are listed first.
|
// record results in files_by_size_. The largest files are listed first.
|
||||||
void UpdateFilesBySize();
|
void UpdateFilesBySize();
|
||||||
|
|
||||||
|
ColumnFamilyData* cfd_; // ColumnFamilyData to which this Version belongs
|
||||||
VersionSet* vset_; // VersionSet to which this Version belongs
|
VersionSet* vset_; // VersionSet to which this Version belongs
|
||||||
Version* next_; // Next version in linked list
|
Version* next_; // Next version in linked list
|
||||||
Version* prev_; // Previous version in linked list
|
Version* prev_; // Previous version in linked list
|
||||||
@ -262,7 +263,7 @@ class Version {
|
|||||||
// used for debugging and logging purposes only.
|
// used for debugging and logging purposes only.
|
||||||
uint64_t version_number_;
|
uint64_t version_number_;
|
||||||
|
|
||||||
explicit Version(VersionSet* vset, uint64_t version_number = 0);
|
Version(ColumnFamilyData* cfd, VersionSet* vset, uint64_t version_number = 0);
|
||||||
|
|
||||||
~Version();
|
~Version();
|
||||||
|
|
||||||
@ -362,29 +363,6 @@ class VersionSet {
|
|||||||
|
|
||||||
int NumberLevels() const { return num_levels_; }
|
int NumberLevels() const { return num_levels_; }
|
||||||
|
|
||||||
// Pick level and inputs for a new compaction.
|
|
||||||
// Returns nullptr if there is no compaction to be done.
|
|
||||||
// Otherwise returns a pointer to a heap-allocated object that
|
|
||||||
// describes the compaction. Caller should delete the result.
|
|
||||||
Compaction* PickCompaction();
|
|
||||||
|
|
||||||
// Return a compaction object for compacting the range [begin,end] in
|
|
||||||
// the specified level. Returns nullptr if there is nothing in that
|
|
||||||
// level that overlaps the specified range. Caller should delete
|
|
||||||
// the result.
|
|
||||||
//
|
|
||||||
// The returned Compaction might not include the whole requested range.
|
|
||||||
// In that case, compaction_end will be set to the next key that needs
|
|
||||||
// compacting. In case the compaction will compact the whole range,
|
|
||||||
// compaction_end will be set to nullptr.
|
|
||||||
// Client is responsible for compaction_end storage -- when called,
|
|
||||||
// *compaction_end should point to valid InternalKey!
|
|
||||||
Compaction* CompactRange(int input_level,
|
|
||||||
int output_level,
|
|
||||||
const InternalKey* begin,
|
|
||||||
const InternalKey* end,
|
|
||||||
InternalKey** compaction_end);
|
|
||||||
|
|
||||||
// Create an iterator that reads over the compaction inputs for "*c".
|
// Create an iterator that reads over the compaction inputs for "*c".
|
||||||
// The caller should delete the iterator when no longer needed.
|
// The caller should delete the iterator when no longer needed.
|
||||||
Iterator* MakeInputIterator(Compaction* c);
|
Iterator* MakeInputIterator(Compaction* c);
|
||||||
@ -409,13 +387,6 @@ class VersionSet {
|
|||||||
// pick the same files to compact.
|
// pick the same files to compact.
|
||||||
bool VerifyCompactionFileConsistency(Compaction* c);
|
bool VerifyCompactionFileConsistency(Compaction* c);
|
||||||
|
|
||||||
double MaxBytesForLevel(int level);
|
|
||||||
|
|
||||||
// Get the max file size in a given level.
|
|
||||||
uint64_t MaxFileSizeForLevel(int level);
|
|
||||||
|
|
||||||
void ReleaseCompactionFiles(Compaction* c, Status status);
|
|
||||||
|
|
||||||
Status GetMetadataForFile(uint64_t number, int* filelevel,
|
Status GetMetadataForFile(uint64_t number, int* filelevel,
|
||||||
FileMetaData* metadata, ColumnFamilyData** cfd);
|
FileMetaData* metadata, ColumnFamilyData** cfd);
|
||||||
|
|
||||||
@ -471,10 +442,6 @@ class VersionSet {
|
|||||||
// Opened lazily
|
// Opened lazily
|
||||||
unique_ptr<log::Writer> descriptor_log_;
|
unique_ptr<log::Writer> descriptor_log_;
|
||||||
|
|
||||||
// An object that keeps all the compaction stats
|
|
||||||
// and picks the next compaction
|
|
||||||
std::unique_ptr<CompactionPicker> compaction_picker_;
|
|
||||||
|
|
||||||
// generates a increasing version number for every new version
|
// generates a increasing version number for every new version
|
||||||
uint64_t current_version_number_;
|
uint64_t current_version_number_;
|
||||||
|
|
||||||
|
@ -118,6 +118,12 @@ struct ColumnFamilyOptions {
|
|||||||
// Default: a factory that doesn't provide any object
|
// Default: a factory that doesn't provide any object
|
||||||
std::shared_ptr<CompactionFilterFactory> compaction_filter_factory;
|
std::shared_ptr<CompactionFilterFactory> compaction_filter_factory;
|
||||||
|
|
||||||
|
// Any internal progress/error information generated by the db will
|
||||||
|
// be written to info_log if it is non-nullptr, or to a file stored
|
||||||
|
// in the same directory as the DB contents if info_log is nullptr.
|
||||||
|
// Default: nullptr
|
||||||
|
shared_ptr<Logger> info_log;
|
||||||
|
|
||||||
// -------------------
|
// -------------------
|
||||||
// Parameters that affect performance
|
// Parameters that affect performance
|
||||||
|
|
||||||
@ -316,6 +322,11 @@ struct ColumnFamilyOptions {
|
|||||||
// stop building a single file in a level->level+1 compaction.
|
// stop building a single file in a level->level+1 compaction.
|
||||||
int max_grandparent_overlap_factor;
|
int max_grandparent_overlap_factor;
|
||||||
|
|
||||||
|
// If non-null, then we should collect metrics about database operations
|
||||||
|
// Statistics objects should not be shared between DB instances as
|
||||||
|
// it does not use any locks to prevent concurrent updates.
|
||||||
|
shared_ptr<Statistics> statistics;
|
||||||
|
|
||||||
// Disable compaction triggered by seek.
|
// Disable compaction triggered by seek.
|
||||||
// With bloomfilter and fast storage, a miss on one level
|
// With bloomfilter and fast storage, a miss on one level
|
||||||
// is very cheap if the file handle is cached in table cache
|
// is very cheap if the file handle is cached in table cache
|
||||||
@ -478,12 +489,6 @@ struct DBOptions {
|
|||||||
// Default: Env::Default()
|
// Default: Env::Default()
|
||||||
Env* env;
|
Env* env;
|
||||||
|
|
||||||
// Any internal progress/error information generated by the db will
|
|
||||||
// be written to info_log if it is non-nullptr, or to a file stored
|
|
||||||
// in the same directory as the DB contents if info_log is nullptr.
|
|
||||||
// Default: nullptr
|
|
||||||
shared_ptr<Logger> info_log;
|
|
||||||
|
|
||||||
// Number of open files that can be used by the DB. You may need to
|
// Number of open files that can be used by the DB. You may need to
|
||||||
// increase this if your database has a large working set (budget
|
// increase this if your database has a large working set (budget
|
||||||
// one open file per 2MB of working set).
|
// one open file per 2MB of working set).
|
||||||
@ -491,11 +496,6 @@ struct DBOptions {
|
|||||||
// Default: 1000
|
// Default: 1000
|
||||||
int max_open_files;
|
int max_open_files;
|
||||||
|
|
||||||
// If non-null, then we should collect metrics about database operations
|
|
||||||
// Statistics objects should not be shared between DB instances as
|
|
||||||
// it does not use any locks to prevent concurrent updates.
|
|
||||||
shared_ptr<Statistics> statistics;
|
|
||||||
|
|
||||||
// If true, then the contents of data files are not synced
|
// If true, then the contents of data files are not synced
|
||||||
// to stable storage. Their contents remain in the OS buffers till the
|
// to stable storage. Their contents remain in the OS buffers till the
|
||||||
// OS decides to flush them. This option is good for bulk-loading
|
// OS decides to flush them. This option is good for bulk-loading
|
||||||
|
@ -32,6 +32,7 @@ ColumnFamilyOptions::ColumnFamilyOptions()
|
|||||||
compaction_filter_factory(
|
compaction_filter_factory(
|
||||||
std::shared_ptr<CompactionFilterFactory>(
|
std::shared_ptr<CompactionFilterFactory>(
|
||||||
new DefaultCompactionFilterFactory())),
|
new DefaultCompactionFilterFactory())),
|
||||||
|
info_log(nullptr),
|
||||||
write_buffer_size(4<<20),
|
write_buffer_size(4<<20),
|
||||||
max_write_buffer_number(2),
|
max_write_buffer_number(2),
|
||||||
min_write_buffer_number_to_merge(1),
|
min_write_buffer_number_to_merge(1),
|
||||||
@ -56,6 +57,7 @@ ColumnFamilyOptions::ColumnFamilyOptions()
|
|||||||
expanded_compaction_factor(25),
|
expanded_compaction_factor(25),
|
||||||
source_compaction_factor(1),
|
source_compaction_factor(1),
|
||||||
max_grandparent_overlap_factor(10),
|
max_grandparent_overlap_factor(10),
|
||||||
|
statistics(nullptr),
|
||||||
disable_seek_compaction(false),
|
disable_seek_compaction(false),
|
||||||
soft_rate_limit(0.0),
|
soft_rate_limit(0.0),
|
||||||
hard_rate_limit(0.0),
|
hard_rate_limit(0.0),
|
||||||
@ -84,6 +86,7 @@ ColumnFamilyOptions::ColumnFamilyOptions(const Options& options)
|
|||||||
merge_operator(options.merge_operator),
|
merge_operator(options.merge_operator),
|
||||||
compaction_filter(options.compaction_filter),
|
compaction_filter(options.compaction_filter),
|
||||||
compaction_filter_factory(options.compaction_filter_factory),
|
compaction_filter_factory(options.compaction_filter_factory),
|
||||||
|
info_log(options.info_log),
|
||||||
write_buffer_size(options.write_buffer_size),
|
write_buffer_size(options.write_buffer_size),
|
||||||
max_write_buffer_number(options.max_write_buffer_number),
|
max_write_buffer_number(options.max_write_buffer_number),
|
||||||
min_write_buffer_number_to_merge(
|
min_write_buffer_number_to_merge(
|
||||||
@ -113,6 +116,7 @@ ColumnFamilyOptions::ColumnFamilyOptions(const Options& options)
|
|||||||
expanded_compaction_factor(options.expanded_compaction_factor),
|
expanded_compaction_factor(options.expanded_compaction_factor),
|
||||||
source_compaction_factor(options.source_compaction_factor),
|
source_compaction_factor(options.source_compaction_factor),
|
||||||
max_grandparent_overlap_factor(options.max_grandparent_overlap_factor),
|
max_grandparent_overlap_factor(options.max_grandparent_overlap_factor),
|
||||||
|
statistics(options.statistics),
|
||||||
disable_seek_compaction(options.disable_seek_compaction),
|
disable_seek_compaction(options.disable_seek_compaction),
|
||||||
soft_rate_limit(options.soft_rate_limit),
|
soft_rate_limit(options.soft_rate_limit),
|
||||||
hard_rate_limit(options.hard_rate_limit),
|
hard_rate_limit(options.hard_rate_limit),
|
||||||
@ -145,7 +149,6 @@ DBOptions::DBOptions()
|
|||||||
error_if_exists(false),
|
error_if_exists(false),
|
||||||
paranoid_checks(false),
|
paranoid_checks(false),
|
||||||
env(Env::Default()),
|
env(Env::Default()),
|
||||||
info_log(nullptr),
|
|
||||||
max_open_files(1000),
|
max_open_files(1000),
|
||||||
disableDataSync(false),
|
disableDataSync(false),
|
||||||
use_fsync(false),
|
use_fsync(false),
|
||||||
@ -178,9 +181,7 @@ DBOptions::DBOptions(const Options& options)
|
|||||||
error_if_exists(options.error_if_exists),
|
error_if_exists(options.error_if_exists),
|
||||||
paranoid_checks(options.paranoid_checks),
|
paranoid_checks(options.paranoid_checks),
|
||||||
env(options.env),
|
env(options.env),
|
||||||
info_log(options.info_log),
|
|
||||||
max_open_files(options.max_open_files),
|
max_open_files(options.max_open_files),
|
||||||
statistics(options.statistics),
|
|
||||||
disableDataSync(options.disableDataSync),
|
disableDataSync(options.disableDataSync),
|
||||||
use_fsync(options.use_fsync),
|
use_fsync(options.use_fsync),
|
||||||
db_stats_log_interval(options.db_stats_log_interval),
|
db_stats_log_interval(options.db_stats_log_interval),
|
||||||
|
Loading…
Reference in New Issue
Block a user