Merge branch 'performance' of github.com:facebook/rocksdb into performance
Conflicts: db/builder.cc db/db_impl.cc db/version_set.cc include/leveldb/statistics.h
This commit is contained in:
commit
f5fa26b6a9
@ -28,6 +28,7 @@ Status BuildTable(const std::string& dbname,
|
|||||||
const SequenceNumber earliest_seqno_in_memtable) {
|
const SequenceNumber earliest_seqno_in_memtable) {
|
||||||
Status s;
|
Status s;
|
||||||
meta->file_size = 0;
|
meta->file_size = 0;
|
||||||
|
meta->smallest_seqno = meta->largest_seqno = 0;
|
||||||
iter->SeekToFirst();
|
iter->SeekToFirst();
|
||||||
|
|
||||||
// If the sequence number of the smallest entry in the memtable is
|
// If the sequence number of the smallest entry in the memtable is
|
||||||
@ -48,7 +49,10 @@ Status BuildTable(const std::string& dbname,
|
|||||||
TableBuilder* builder = new TableBuilder(options, file.get(), 0);
|
TableBuilder* builder = new TableBuilder(options, file.get(), 0);
|
||||||
|
|
||||||
// the first key is the smallest key
|
// the first key is the smallest key
|
||||||
meta->smallest.DecodeFrom(iter->key());
|
Slice key = iter->key();
|
||||||
|
meta->smallest.DecodeFrom(key);
|
||||||
|
meta->smallest_seqno = GetInternalKeySeqno(key);
|
||||||
|
meta->largest_seqno = meta->smallest_seqno;
|
||||||
|
|
||||||
MergeHelper merge(user_comparator, options.merge_operator,
|
MergeHelper merge(user_comparator, options.merge_operator,
|
||||||
options.info_log.get(),
|
options.info_log.get(),
|
||||||
@ -135,12 +139,18 @@ Status BuildTable(const std::string& dbname,
|
|||||||
|
|
||||||
// The last key is the largest key
|
// The last key is the largest key
|
||||||
meta->largest.DecodeFrom(Slice(prev_key));
|
meta->largest.DecodeFrom(Slice(prev_key));
|
||||||
|
SequenceNumber seqno = GetInternalKeySeqno(Slice(prev_key));
|
||||||
|
meta->smallest_seqno = std::min(meta->smallest_seqno, seqno);
|
||||||
|
meta->largest_seqno = std::max(meta->largest_seqno, seqno);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
for (; iter->Valid(); iter->Next()) {
|
for (; iter->Valid(); iter->Next()) {
|
||||||
Slice key = iter->key();
|
Slice key = iter->key();
|
||||||
meta->largest.DecodeFrom(key);
|
meta->largest.DecodeFrom(key);
|
||||||
builder->Add(key, iter->value());
|
builder->Add(key, iter->value());
|
||||||
|
SequenceNumber seqno = GetInternalKeySeqno(key);
|
||||||
|
meta->smallest_seqno = std::min(meta->smallest_seqno, seqno);
|
||||||
|
meta->largest_seqno = std::max(meta->largest_seqno, seqno);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "db/db_impl.h"
|
#include "db/db_impl.h"
|
||||||
#include "db/version_set.h"
|
#include "db/version_set.h"
|
||||||
#include "db/db_statistics.h"
|
#include "db/db_statistics.h"
|
||||||
|
#include "leveldb/options.h"
|
||||||
#include "leveldb/cache.h"
|
#include "leveldb/cache.h"
|
||||||
#include "leveldb/db.h"
|
#include "leveldb/db.h"
|
||||||
#include "leveldb/env.h"
|
#include "leveldb/env.h"
|
||||||
@ -125,7 +126,7 @@ static int FLAGS_max_write_buffer_number = 0;
|
|||||||
// The minimum number of write buffers that will be merged together
|
// The minimum number of write buffers that will be merged together
|
||||||
// before writing to storage. This is cheap because it is an
|
// before writing to storage. This is cheap because it is an
|
||||||
// in-memory merge. If this feature is not enabled, then all these
|
// in-memory merge. If this feature is not enabled, then all these
|
||||||
// write buffers are fushed to L0 as seperate files and this increases
|
// write buffers are fushed to L0 as separate files and this increases
|
||||||
// read amplification because a get request has to check in all of these
|
// read amplification because a get request has to check in all of these
|
||||||
// files. Also, an in-memory merge may result in writing lesser
|
// files. Also, an in-memory merge may result in writing lesser
|
||||||
// data to storage if there are duplicate records in each of these
|
// data to storage if there are duplicate records in each of these
|
||||||
@ -137,6 +138,15 @@ static int FLAGS_min_write_buffer_number_to_merge = 0;
|
|||||||
// This is initialized to default value of 1 in "main" function.
|
// This is initialized to default value of 1 in "main" function.
|
||||||
static int FLAGS_max_background_compactions = 0;
|
static int FLAGS_max_background_compactions = 0;
|
||||||
|
|
||||||
|
// style of compaction: level-based vs universal
|
||||||
|
static leveldb::CompactionStyle FLAGS_compaction_style = leveldb::kCompactionStyleLevel;
|
||||||
|
|
||||||
|
// Percentage flexibilty while comparing file size.
|
||||||
|
static int FLAGS_universal_size_ratio = 1;
|
||||||
|
|
||||||
|
// The minimum number of files in a single compaction run.
|
||||||
|
static int FLAGS_compaction_universal_min_merge_width = 2;
|
||||||
|
|
||||||
// Number of bytes to use as a cache of uncompressed data.
|
// Number of bytes to use as a cache of uncompressed data.
|
||||||
// Negative means use default settings.
|
// Negative means use default settings.
|
||||||
static long FLAGS_cache_size = -1;
|
static long FLAGS_cache_size = -1;
|
||||||
@ -1104,6 +1114,10 @@ unique_ptr<char []> GenerateKeyFromInt(int v, const char* suffix = "")
|
|||||||
options.min_write_buffer_number_to_merge =
|
options.min_write_buffer_number_to_merge =
|
||||||
FLAGS_min_write_buffer_number_to_merge;
|
FLAGS_min_write_buffer_number_to_merge;
|
||||||
options.max_background_compactions = FLAGS_max_background_compactions;
|
options.max_background_compactions = FLAGS_max_background_compactions;
|
||||||
|
options.compaction_style = FLAGS_compaction_style;
|
||||||
|
options.compaction_options_universal.size_ratio = FLAGS_universal_size_ratio;
|
||||||
|
options.compaction_options_universal.min_merge_width =
|
||||||
|
FLAGS_compaction_universal_min_merge_width;
|
||||||
options.block_size = FLAGS_block_size;
|
options.block_size = FLAGS_block_size;
|
||||||
options.filter_policy = filter_policy_;
|
options.filter_policy = filter_policy_;
|
||||||
options.max_open_files = FLAGS_open_files;
|
options.max_open_files = FLAGS_open_files;
|
||||||
@ -1988,6 +2002,11 @@ int main(int argc, char** argv) {
|
|||||||
FLAGS_open_files = leveldb::Options().max_open_files;
|
FLAGS_open_files = leveldb::Options().max_open_files;
|
||||||
FLAGS_max_background_compactions =
|
FLAGS_max_background_compactions =
|
||||||
leveldb::Options().max_background_compactions;
|
leveldb::Options().max_background_compactions;
|
||||||
|
FLAGS_compaction_style = leveldb::Options().compaction_style;
|
||||||
|
FLAGS_universal_size_ratio =
|
||||||
|
leveldb::Options().compaction_options_universal.size_ratio;
|
||||||
|
FLAGS_compaction_universal_min_merge_width =
|
||||||
|
leveldb::Options().compaction_options_universal.min_merge_width;
|
||||||
// Compression test code above refers to FLAGS_block_size
|
// Compression test code above refers to FLAGS_block_size
|
||||||
FLAGS_block_size = leveldb::Options().block_size;
|
FLAGS_block_size = leveldb::Options().block_size;
|
||||||
FLAGS_use_os_buffer = leveldb::EnvOptions().use_os_buffer;
|
FLAGS_use_os_buffer = leveldb::EnvOptions().use_os_buffer;
|
||||||
@ -2047,6 +2066,13 @@ int main(int argc, char** argv) {
|
|||||||
} else if (sscanf(argv[i], "--max_background_compactions=%d%c", &n, &junk)
|
} else if (sscanf(argv[i], "--max_background_compactions=%d%c", &n, &junk)
|
||||||
== 1) {
|
== 1) {
|
||||||
FLAGS_max_background_compactions = n;
|
FLAGS_max_background_compactions = n;
|
||||||
|
} else if (sscanf(argv[i], "--compaction_style=%d%c", &n, &junk) == 1) {
|
||||||
|
FLAGS_compaction_style = (leveldb::CompactionStyle)n;
|
||||||
|
} else if (sscanf(argv[i], "--universal_size_ratio=%d%c", &n, &junk) == 1) {
|
||||||
|
FLAGS_universal_size_ratio = n;
|
||||||
|
} else if (sscanf(argv[i], "--universal_min_merge_width=%d%c",
|
||||||
|
&n, &junk) == 1) {
|
||||||
|
FLAGS_compaction_universal_min_merge_width = n;
|
||||||
} else if (sscanf(argv[i], "--cache_size=%ld%c", &l, &junk) == 1) {
|
} else if (sscanf(argv[i], "--cache_size=%ld%c", &l, &junk) == 1) {
|
||||||
FLAGS_cache_size = l;
|
FLAGS_cache_size = l;
|
||||||
} else if (sscanf(argv[i], "--block_size=%d%c", &n, &junk) == 1) {
|
} else if (sscanf(argv[i], "--block_size=%d%c", &n, &junk) == 1) {
|
||||||
|
@ -76,6 +76,7 @@ struct DBImpl::CompactionState {
|
|||||||
uint64_t number;
|
uint64_t number;
|
||||||
uint64_t file_size;
|
uint64_t file_size;
|
||||||
InternalKey smallest, largest;
|
InternalKey smallest, largest;
|
||||||
|
SequenceNumber smallest_seqno, largest_seqno;
|
||||||
};
|
};
|
||||||
std::vector<Output> outputs;
|
std::vector<Output> outputs;
|
||||||
std::list<uint64_t> allocated_file_numbers;
|
std::list<uint64_t> allocated_file_numbers;
|
||||||
@ -780,7 +781,8 @@ Status DBImpl::WriteLevel0TableForRecovery(MemTable* mem, VersionEdit* edit) {
|
|||||||
int level = 0;
|
int level = 0;
|
||||||
if (s.ok() && meta.file_size > 0) {
|
if (s.ok() && meta.file_size > 0) {
|
||||||
edit->AddFile(level, meta.number, meta.file_size,
|
edit->AddFile(level, meta.number, meta.file_size,
|
||||||
meta.smallest, meta.largest);
|
meta.smallest, meta.largest,
|
||||||
|
meta.smallest_seqno, meta.largest_seqno);
|
||||||
}
|
}
|
||||||
|
|
||||||
CompactionStats stats;
|
CompactionStats stats;
|
||||||
@ -854,11 +856,13 @@ Status DBImpl::WriteLevel0Table(std::vector<MemTable*> &mems, VersionEdit* edit,
|
|||||||
// insert files directly into higher levels because some other
|
// insert files directly into higher levels because some other
|
||||||
// threads could be concurrently producing compacted files for
|
// threads could be concurrently producing compacted files for
|
||||||
// that key range.
|
// that key range.
|
||||||
if (base != nullptr && options_.max_background_compactions <= 1) {
|
if (base != nullptr && options_.max_background_compactions <= 1 &&
|
||||||
|
options_.compaction_style == kCompactionStyleLevel) {
|
||||||
level = base->PickLevelForMemTableOutput(min_user_key, max_user_key);
|
level = base->PickLevelForMemTableOutput(min_user_key, max_user_key);
|
||||||
}
|
}
|
||||||
edit->AddFile(level, meta.number, meta.file_size,
|
edit->AddFile(level, meta.number, meta.file_size,
|
||||||
meta.smallest, meta.largest);
|
meta.smallest, meta.largest,
|
||||||
|
meta.smallest_seqno, meta.largest_seqno);
|
||||||
}
|
}
|
||||||
|
|
||||||
CompactionStats stats;
|
CompactionStats stats;
|
||||||
@ -991,7 +995,8 @@ void DBImpl::ReFitLevel(int level) {
|
|||||||
VersionEdit edit(NumberLevels());
|
VersionEdit edit(NumberLevels());
|
||||||
for (const auto& f : versions_->current()->files_[level]) {
|
for (const auto& f : versions_->current()->files_[level]) {
|
||||||
edit.DeleteFile(level, f->number);
|
edit.DeleteFile(level, f->number);
|
||||||
edit.AddFile(to_level, f->number, f->file_size, f->smallest, f->largest);
|
edit.AddFile(to_level, f->number, f->file_size, f->smallest, f->largest,
|
||||||
|
f->smallest_seqno, f->largest_seqno);
|
||||||
}
|
}
|
||||||
Log(options_.info_log, "Apply version edit:\n%s",
|
Log(options_.info_log, "Apply version edit:\n%s",
|
||||||
edit.DebugString().data());
|
edit.DebugString().data());
|
||||||
@ -1452,7 +1457,8 @@ Status DBImpl::BackgroundCompaction(bool* madeProgress,
|
|||||||
FileMetaData* f = c->input(0, 0);
|
FileMetaData* f = c->input(0, 0);
|
||||||
c->edit()->DeleteFile(c->level(), f->number);
|
c->edit()->DeleteFile(c->level(), f->number);
|
||||||
c->edit()->AddFile(c->level() + 1, f->number, f->file_size,
|
c->edit()->AddFile(c->level() + 1, f->number, f->file_size,
|
||||||
f->smallest, f->largest);
|
f->smallest, f->largest,
|
||||||
|
f->smallest_seqno, f->largest_seqno);
|
||||||
status = versions_->LogAndApply(c->edit(), &mutex_);
|
status = versions_->LogAndApply(c->edit(), &mutex_);
|
||||||
VersionSet::LevelSummaryStorage tmp;
|
VersionSet::LevelSummaryStorage tmp;
|
||||||
Log(options_.info_log, "Moved #%lld to level-%d %lld bytes %s: %s\n",
|
Log(options_.info_log, "Moved #%lld to level-%d %lld bytes %s: %s\n",
|
||||||
@ -1564,6 +1570,7 @@ Status DBImpl::OpenCompactionOutputFile(CompactionState* compact) {
|
|||||||
out.number = file_number;
|
out.number = file_number;
|
||||||
out.smallest.Clear();
|
out.smallest.Clear();
|
||||||
out.largest.Clear();
|
out.largest.Clear();
|
||||||
|
out.smallest_seqno = out.largest_seqno = 0;
|
||||||
compact->outputs.push_back(out);
|
compact->outputs.push_back(out);
|
||||||
|
|
||||||
// Make the output file
|
// Make the output file
|
||||||
@ -1574,10 +1581,10 @@ 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->level() + 1));
|
1.1 * versions_->MaxFileSizeForLevel(compact->compaction->output_level()));
|
||||||
|
|
||||||
compact->builder.reset(new TableBuilder(options_, compact->outfile.get(),
|
compact->builder.reset(new TableBuilder(options_, compact->outfile.get(),
|
||||||
compact->compaction->level() + 1));
|
compact->compaction->output_level()));
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@ -1668,8 +1675,10 @@ Status DBImpl::InstallCompactionResults(CompactionState* compact) {
|
|||||||
for (size_t i = 0; i < compact->outputs.size(); i++) {
|
for (size_t i = 0; i < compact->outputs.size(); i++) {
|
||||||
const CompactionState::Output& out = compact->outputs[i];
|
const CompactionState::Output& out = compact->outputs[i];
|
||||||
compact->compaction->edit()->AddFile(
|
compact->compaction->edit()->AddFile(
|
||||||
level + 1,
|
(options_.compaction_style == kCompactionStyleUniversal) ?
|
||||||
out.number, out.file_size, out.smallest, out.largest);
|
level : level + 1,
|
||||||
|
out.number, out.file_size, out.smallest, out.largest,
|
||||||
|
out.smallest_seqno, out.largest_seqno);
|
||||||
}
|
}
|
||||||
return versions_->LogAndApply(compact->compaction->edit(), &mutex_);
|
return versions_->LogAndApply(compact->compaction->edit(), &mutex_);
|
||||||
}
|
}
|
||||||
@ -1950,7 +1959,8 @@ Status DBImpl::DoCompactionWork(CompactionState* compact) {
|
|||||||
// If this is the bottommost level (no files in lower levels)
|
// If this is the bottommost level (no files in lower levels)
|
||||||
// and the earliest snapshot is larger than this seqno
|
// and the earliest snapshot is larger than this seqno
|
||||||
// then we can squash the seqno to zero.
|
// then we can squash the seqno to zero.
|
||||||
if (bottommost_level && ikey.sequence < earliest_snapshot &&
|
if (options_.compaction_style == kCompactionStyleLevel &&
|
||||||
|
bottommost_level && ikey.sequence < earliest_snapshot &&
|
||||||
ikey.type != kTypeMerge) {
|
ikey.type != kTypeMerge) {
|
||||||
assert(ikey.type != kTypeDeletion);
|
assert(ikey.type != kTypeDeletion);
|
||||||
// make a copy because updating in place would cause problems
|
// make a copy because updating in place would cause problems
|
||||||
@ -1970,11 +1980,19 @@ Status DBImpl::DoCompactionWork(CompactionState* compact) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SequenceNumber seqno = GetInternalKeySeqno(newkey);
|
||||||
if (compact->builder->NumEntries() == 0) {
|
if (compact->builder->NumEntries() == 0) {
|
||||||
compact->current_output()->smallest.DecodeFrom(newkey);
|
compact->current_output()->smallest.DecodeFrom(newkey);
|
||||||
|
compact->current_output()->smallest_seqno = seqno;
|
||||||
|
} else {
|
||||||
|
compact->current_output()->smallest_seqno =
|
||||||
|
std::min(compact->current_output()->smallest_seqno, seqno);
|
||||||
}
|
}
|
||||||
compact->current_output()->largest.DecodeFrom(newkey);
|
compact->current_output()->largest.DecodeFrom(newkey);
|
||||||
compact->builder->Add(newkey, value);
|
compact->builder->Add(newkey, value);
|
||||||
|
compact->current_output()->largest_seqno =
|
||||||
|
std::max(compact->current_output()->largest_seqno, seqno);
|
||||||
|
|
||||||
// Close output file if it is big enough
|
// Close output file if it is big enough
|
||||||
if (compact->builder->FileSize() >=
|
if (compact->builder->FileSize() >=
|
||||||
|
@ -3401,7 +3401,7 @@ void BM_LogAndApply(int iters, int num_base_files) {
|
|||||||
for (int i = 0; i < num_base_files; i++) {
|
for (int i = 0; i < num_base_files; i++) {
|
||||||
InternalKey start(MakeKey(2*fnum), 1, kTypeValue);
|
InternalKey start(MakeKey(2*fnum), 1, kTypeValue);
|
||||||
InternalKey limit(MakeKey(2*fnum+1), 1, kTypeDeletion);
|
InternalKey limit(MakeKey(2*fnum+1), 1, kTypeDeletion);
|
||||||
vbase.AddFile(2, fnum++, 1 /* file size */, start, limit);
|
vbase.AddFile(2, fnum++, 1 /* file size */, start, limit, 1, 1);
|
||||||
}
|
}
|
||||||
ASSERT_OK(vset.LogAndApply(&vbase, &mu));
|
ASSERT_OK(vset.LogAndApply(&vbase, &mu));
|
||||||
|
|
||||||
@ -3412,7 +3412,7 @@ void BM_LogAndApply(int iters, int num_base_files) {
|
|||||||
vedit.DeleteFile(2, fnum);
|
vedit.DeleteFile(2, fnum);
|
||||||
InternalKey start(MakeKey(2*fnum), 1, kTypeValue);
|
InternalKey start(MakeKey(2*fnum), 1, kTypeValue);
|
||||||
InternalKey limit(MakeKey(2*fnum+1), 1, kTypeDeletion);
|
InternalKey limit(MakeKey(2*fnum+1), 1, kTypeDeletion);
|
||||||
vedit.AddFile(2, fnum++, 1 /* file size */, start, limit);
|
vedit.AddFile(2, fnum++, 1 /* file size */, start, limit, 1, 1);
|
||||||
vset.LogAndApply(&vedit, &mu);
|
vset.LogAndApply(&vedit, &mu);
|
||||||
}
|
}
|
||||||
uint64_t stop_micros = env->NowMicros();
|
uint64_t stop_micros = env->NowMicros();
|
||||||
|
@ -173,6 +173,15 @@ inline void UpdateInternalKey(char* internal_key,
|
|||||||
EncodeFixed64(seqtype, newval);
|
EncodeFixed64(seqtype, newval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the sequence number from the internal key
|
||||||
|
inline uint64_t GetInternalKeySeqno(const Slice& internal_key) {
|
||||||
|
const size_t n = internal_key.size();
|
||||||
|
assert(n >= 8);
|
||||||
|
uint64_t num = DecodeFixed64(internal_key.data() + n - 8);
|
||||||
|
return num >> 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// A helper class useful for DBImpl::Get()
|
// A helper class useful for DBImpl::Get()
|
||||||
class LookupKey {
|
class LookupKey {
|
||||||
public:
|
public:
|
||||||
|
@ -88,6 +88,7 @@ class Repairer {
|
|||||||
private:
|
private:
|
||||||
struct TableInfo {
|
struct TableInfo {
|
||||||
FileMetaData meta;
|
FileMetaData meta;
|
||||||
|
SequenceNumber min_sequence;
|
||||||
SequenceNumber max_sequence;
|
SequenceNumber max_sequence;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -264,6 +265,7 @@ class Repairer {
|
|||||||
ReadOptions(), storage_options_, t->meta.number, t->meta.file_size);
|
ReadOptions(), storage_options_, t->meta.number, t->meta.file_size);
|
||||||
bool empty = true;
|
bool empty = true;
|
||||||
ParsedInternalKey parsed;
|
ParsedInternalKey parsed;
|
||||||
|
t->min_sequence = 0;
|
||||||
t->max_sequence = 0;
|
t->max_sequence = 0;
|
||||||
for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {
|
for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {
|
||||||
Slice key = iter->key();
|
Slice key = iter->key();
|
||||||
@ -280,6 +282,9 @@ class Repairer {
|
|||||||
t->meta.smallest.DecodeFrom(key);
|
t->meta.smallest.DecodeFrom(key);
|
||||||
}
|
}
|
||||||
t->meta.largest.DecodeFrom(key);
|
t->meta.largest.DecodeFrom(key);
|
||||||
|
if (parsed.sequence < t->min_sequence) {
|
||||||
|
t->min_sequence = parsed.sequence;
|
||||||
|
}
|
||||||
if (parsed.sequence > t->max_sequence) {
|
if (parsed.sequence > t->max_sequence) {
|
||||||
t->max_sequence = parsed.sequence;
|
t->max_sequence = parsed.sequence;
|
||||||
}
|
}
|
||||||
@ -320,7 +325,8 @@ class Repairer {
|
|||||||
// TODO(opt): separate out into multiple levels
|
// TODO(opt): separate out into multiple levels
|
||||||
const TableInfo& t = tables_[i];
|
const TableInfo& t = tables_[i];
|
||||||
edit_->AddFile(0, t.meta.number, t.meta.file_size,
|
edit_->AddFile(0, t.meta.number, t.meta.file_size,
|
||||||
t.meta.smallest, t.meta.largest);
|
t.meta.smallest, t.meta.largest,
|
||||||
|
t.min_sequence, t.max_sequence);
|
||||||
}
|
}
|
||||||
|
|
||||||
//fprintf(stderr, "NewDescriptor:\n%s\n", edit_.DebugString().c_str());
|
//fprintf(stderr, "NewDescriptor:\n%s\n", edit_.DebugString().c_str());
|
||||||
|
@ -20,7 +20,10 @@ enum Tag {
|
|||||||
kDeletedFile = 6,
|
kDeletedFile = 6,
|
||||||
kNewFile = 7,
|
kNewFile = 7,
|
||||||
// 8 was used for large value refs
|
// 8 was used for large value refs
|
||||||
kPrevLogNumber = 9
|
kPrevLogNumber = 9,
|
||||||
|
|
||||||
|
// these are new formats divergent from open source leveldb
|
||||||
|
kNewFile2 = 100 // store smallest & largest seqno
|
||||||
};
|
};
|
||||||
|
|
||||||
void VersionEdit::Clear() {
|
void VersionEdit::Clear() {
|
||||||
@ -76,12 +79,14 @@ void VersionEdit::EncodeTo(std::string* dst) const {
|
|||||||
|
|
||||||
for (size_t i = 0; i < new_files_.size(); i++) {
|
for (size_t i = 0; i < new_files_.size(); i++) {
|
||||||
const FileMetaData& f = new_files_[i].second;
|
const FileMetaData& f = new_files_[i].second;
|
||||||
PutVarint32(dst, kNewFile);
|
PutVarint32(dst, kNewFile2);
|
||||||
PutVarint32(dst, new_files_[i].first); // level
|
PutVarint32(dst, new_files_[i].first); // level
|
||||||
PutVarint64(dst, f.number);
|
PutVarint64(dst, f.number);
|
||||||
PutVarint64(dst, f.file_size);
|
PutVarint64(dst, f.file_size);
|
||||||
PutLengthPrefixedSlice(dst, f.smallest.Encode());
|
PutLengthPrefixedSlice(dst, f.smallest.Encode());
|
||||||
PutLengthPrefixedSlice(dst, f.largest.Encode());
|
PutLengthPrefixedSlice(dst, f.largest.Encode());
|
||||||
|
PutVarint64(dst, f.smallest_seqno);
|
||||||
|
PutVarint64(dst, f.largest_seqno);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,6 +206,22 @@ Status VersionEdit::DecodeFrom(const Slice& src) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case kNewFile2:
|
||||||
|
if (GetLevel(&input, &level, &msg) &&
|
||||||
|
GetVarint64(&input, &f.number) &&
|
||||||
|
GetVarint64(&input, &f.file_size) &&
|
||||||
|
GetInternalKey(&input, &f.smallest) &&
|
||||||
|
GetInternalKey(&input, &f.largest) &&
|
||||||
|
GetVarint64(&input, &f.smallest_seqno) &&
|
||||||
|
GetVarint64(&input, &f.largest_seqno) ) {
|
||||||
|
new_files_.push_back(std::make_pair(level, f));
|
||||||
|
} else {
|
||||||
|
if (!msg) {
|
||||||
|
msg = "new-file2 entry";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
msg = "unknown tag";
|
msg = "unknown tag";
|
||||||
break;
|
break;
|
||||||
|
@ -22,6 +22,8 @@ struct FileMetaData {
|
|||||||
InternalKey smallest; // Smallest internal key served by table
|
InternalKey smallest; // Smallest internal key served by table
|
||||||
InternalKey largest; // Largest internal key served by table
|
InternalKey largest; // Largest internal key served by table
|
||||||
bool being_compacted; // Is this file undergoing compaction?
|
bool being_compacted; // Is this file undergoing compaction?
|
||||||
|
SequenceNumber smallest_seqno;// The smallest seqno in this file
|
||||||
|
SequenceNumber largest_seqno; // The largest seqno in this file
|
||||||
|
|
||||||
FileMetaData() : refs(0), allowed_seeks(1 << 30), file_size(0),
|
FileMetaData() : refs(0), allowed_seeks(1 << 30), file_size(0),
|
||||||
being_compacted(false) { }
|
being_compacted(false) { }
|
||||||
@ -67,12 +69,17 @@ class VersionEdit {
|
|||||||
void AddFile(int level, uint64_t file,
|
void AddFile(int level, uint64_t file,
|
||||||
uint64_t file_size,
|
uint64_t file_size,
|
||||||
const InternalKey& smallest,
|
const InternalKey& smallest,
|
||||||
const InternalKey& largest) {
|
const InternalKey& largest,
|
||||||
|
const SequenceNumber& smallest_seqno,
|
||||||
|
const SequenceNumber& largest_seqno) {
|
||||||
FileMetaData f;
|
FileMetaData f;
|
||||||
f.number = file;
|
f.number = file;
|
||||||
f.file_size = file_size;
|
f.file_size = file_size;
|
||||||
f.smallest = smallest;
|
f.smallest = smallest;
|
||||||
f.largest = largest;
|
f.largest = largest;
|
||||||
|
f.smallest_seqno = smallest_seqno;
|
||||||
|
f.largest_seqno = largest_seqno;
|
||||||
|
assert(smallest_seqno <= largest_seqno);
|
||||||
new_files_.push_back(std::make_pair(level, f));
|
new_files_.push_back(std::make_pair(level, f));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,7 +27,9 @@ TEST(VersionEditTest, EncodeDecode) {
|
|||||||
TestEncodeDecode(edit);
|
TestEncodeDecode(edit);
|
||||||
edit.AddFile(3, kBig + 300 + i, kBig + 400 + i,
|
edit.AddFile(3, kBig + 300 + i, kBig + 400 + i,
|
||||||
InternalKey("foo", kBig + 500 + i, kTypeValue),
|
InternalKey("foo", kBig + 500 + i, kTypeValue),
|
||||||
InternalKey("zoo", kBig + 600 + i, kTypeDeletion));
|
InternalKey("zoo", kBig + 600 + i, kTypeDeletion),
|
||||||
|
kBig + 500 + i,
|
||||||
|
kBig + 600 + i);
|
||||||
edit.DeleteFile(4, kBig + 700 + i);
|
edit.DeleteFile(4, kBig + 700 + i);
|
||||||
edit.SetCompactPointer(i, InternalKey("x", kBig + 900 + i, kTypeValue));
|
edit.SetCompactPointer(i, InternalKey("x", kBig + 900 + i, kTypeValue));
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include "db/version_set.h"
|
#include "db/version_set.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <climits>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "db/filename.h"
|
#include "db/filename.h"
|
||||||
#include "db/log_reader.h"
|
#include "db/log_reader.h"
|
||||||
@ -22,8 +23,8 @@
|
|||||||
|
|
||||||
namespace leveldb {
|
namespace leveldb {
|
||||||
|
|
||||||
static int64_t TotalFileSize(const std::vector<FileMetaData*>& files) {
|
static uint64_t TotalFileSize(const std::vector<FileMetaData*>& files) {
|
||||||
int64_t sum = 0;
|
uint64_t sum = 0;
|
||||||
for (size_t i = 0; i < files.size() && files[i]; i++) {
|
for (size_t i = 0; i < files.size() && files[i]; i++) {
|
||||||
sum += files[i]->file_size;
|
sum += files[i]->file_size;
|
||||||
}
|
}
|
||||||
@ -338,6 +339,14 @@ static bool SaveValue(void* arg, const Slice& ikey, const Slice& v, bool didIO){
|
|||||||
static bool NewestFirst(FileMetaData* a, FileMetaData* b) {
|
static bool NewestFirst(FileMetaData* a, FileMetaData* b) {
|
||||||
return a->number > b->number;
|
return a->number > b->number;
|
||||||
}
|
}
|
||||||
|
static bool NewestFirstBySeqNo(FileMetaData* a, FileMetaData* b) {
|
||||||
|
if (a->smallest_seqno > b->smallest_seqno) {
|
||||||
|
assert(a->largest_seqno > b->largest_seqno);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
assert(a->largest_seqno <= b->largest_seqno);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
Version::Version(VersionSet* vset, uint64_t version_number)
|
Version::Version(VersionSet* vset, uint64_t version_number)
|
||||||
: vset_(vset), next_(this), prev_(this), refs_(0),
|
: vset_(vset), next_(this), prev_(this), refs_(0),
|
||||||
@ -434,7 +443,11 @@ void Version::Get(const ReadOptions& options,
|
|||||||
if (important_files.empty()) continue;
|
if (important_files.empty()) continue;
|
||||||
|
|
||||||
if (level == 0) {
|
if (level == 0) {
|
||||||
|
if (vset_->options_->compaction_style == kCompactionStyleUniversal) {
|
||||||
|
std::sort(important_files.begin(), important_files.end(), NewestFirstBySeqNo);
|
||||||
|
} else {
|
||||||
std::sort(important_files.begin(), important_files.end(), NewestFirst);
|
std::sort(important_files.begin(), important_files.end(), NewestFirst);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Sanity check to make sure that the files are correctly sorted
|
// Sanity check to make sure that the files are correctly sorted
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
@ -565,7 +578,7 @@ int Version::PickLevelForMemTableOutput(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
GetOverlappingInputs(level + 2, &start, &limit, &overlaps);
|
GetOverlappingInputs(level + 2, &start, &limit, &overlaps);
|
||||||
const int64_t sum = TotalFileSize(overlaps);
|
const uint64_t sum = TotalFileSize(overlaps);
|
||||||
if (sum > vset_->MaxGrandParentOverlapBytes(level)) {
|
if (sum > vset_->MaxGrandParentOverlapBytes(level)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1109,7 +1122,10 @@ void VersionSet::Init(int num_levels) {
|
|||||||
int target_file_size_multiplier = options_->target_file_size_multiplier;
|
int target_file_size_multiplier = options_->target_file_size_multiplier;
|
||||||
int max_bytes_multiplier = options_->max_bytes_for_level_multiplier;
|
int max_bytes_multiplier = options_->max_bytes_for_level_multiplier;
|
||||||
for (int i = 0; i < num_levels; i++) {
|
for (int i = 0; i < num_levels; i++) {
|
||||||
if (i > 1) {
|
if (i == 0 && options_->compaction_style == kCompactionStyleUniversal) {
|
||||||
|
max_file_size_[i] = ULLONG_MAX;
|
||||||
|
level_max_bytes_[i] = options_->max_bytes_for_level_base;
|
||||||
|
} else if (i > 1) {
|
||||||
max_file_size_[i] = max_file_size_[i-1] * target_file_size_multiplier;
|
max_file_size_[i] = max_file_size_[i-1] * target_file_size_multiplier;
|
||||||
level_max_bytes_[i] = level_max_bytes_[i-1] * max_bytes_multiplier *
|
level_max_bytes_[i] = level_max_bytes_[i-1] * max_bytes_multiplier *
|
||||||
options_->max_bytes_for_level_multiplier_additional[i-1];
|
options_->max_bytes_for_level_multiplier_additional[i-1];
|
||||||
@ -1656,17 +1672,32 @@ void VersionSet::Finalize(Version* v,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// a static compator used to sort files based on their size
|
// A static compator used to sort files based on their size
|
||||||
static bool compareSize(const VersionSet::Fsize& first,
|
// In normal mode: descending size
|
||||||
|
static bool compareSizeDescending(const VersionSet::Fsize& first,
|
||||||
const VersionSet::Fsize& second) {
|
const VersionSet::Fsize& second) {
|
||||||
return (first.file->file_size > second.file->file_size);
|
return (first.file->file_size > second.file->file_size);
|
||||||
}
|
}
|
||||||
|
// A static compator used to sort files based on their seqno
|
||||||
|
// In universal style : descending seqno
|
||||||
|
static bool compareSeqnoDescending(const VersionSet::Fsize& first,
|
||||||
|
const VersionSet::Fsize& second) {
|
||||||
|
if (first.file->smallest_seqno > second.file->smallest_seqno) {
|
||||||
|
assert(first.file->largest_seqno > second.file->largest_seqno);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
assert(first.file->largest_seqno <= second.file->largest_seqno);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// sort all files in level1 to level(n-1) based on file size
|
// sort all files in level1 to level(n-1) based on file size
|
||||||
void VersionSet::UpdateFilesBySize(Version* v) {
|
void VersionSet::UpdateFilesBySize(Version* v) {
|
||||||
|
|
||||||
// No need to sort the highest level because it is never compacted.
|
// No need to sort the highest level because it is never compacted.
|
||||||
for (int level = 0; level < NumberLevels()-1; level++) {
|
int max_level = (options_->compaction_style == kCompactionStyleUniversal) ?
|
||||||
|
NumberLevels() : NumberLevels() - 1;
|
||||||
|
|
||||||
|
for (int level = 0; level < max_level; level++) {
|
||||||
|
|
||||||
const std::vector<FileMetaData*>& files = v->files_[level];
|
const std::vector<FileMetaData*>& files = v->files_[level];
|
||||||
std::vector<int>& files_by_size = v->files_by_size_[level];
|
std::vector<int>& files_by_size = v->files_by_size_[level];
|
||||||
@ -1680,12 +1711,18 @@ void VersionSet::UpdateFilesBySize(Version* v) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 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 (options_->compaction_style == kCompactionStyleUniversal) {
|
||||||
|
int num = temp.size();
|
||||||
|
std::partial_sort(temp.begin(), temp.begin() + num,
|
||||||
|
temp.end(), compareSeqnoDescending);
|
||||||
|
} else {
|
||||||
int num = Version::number_of_files_to_sort_;
|
int num = Version::number_of_files_to_sort_;
|
||||||
if (num > (int)temp.size()) {
|
if (num > (int)temp.size()) {
|
||||||
num = temp.size();
|
num = temp.size();
|
||||||
}
|
}
|
||||||
std::partial_sort(temp.begin(), temp.begin() + num,
|
std::partial_sort(temp.begin(), temp.begin() + num,
|
||||||
temp.end(), compareSize);
|
temp.end(), compareSizeDescending);
|
||||||
|
}
|
||||||
assert(temp.size() == files.size());
|
assert(temp.size() == files.size());
|
||||||
|
|
||||||
// initialize files_by_size_
|
// initialize files_by_size_
|
||||||
@ -1718,7 +1755,8 @@ Status VersionSet::WriteSnapshot(log::Writer* log) {
|
|||||||
const std::vector<FileMetaData*>& files = current_->files_[level];
|
const std::vector<FileMetaData*>& files = current_->files_[level];
|
||||||
for (size_t i = 0; i < files.size(); i++) {
|
for (size_t i = 0; i < files.size(); i++) {
|
||||||
const FileMetaData* f = files[i];
|
const FileMetaData* f = files[i];
|
||||||
edit.AddFile(level, f->number, f->file_size, f->smallest, f->largest);
|
edit.AddFile(level, f->number, f->file_size, f->smallest, f->largest,
|
||||||
|
f->smallest_seqno, f->largest_seqno);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1762,6 +1800,23 @@ const char* VersionSet::LevelDataSizeSummary(
|
|||||||
return scratch->buffer;
|
return scratch->buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* VersionSet::LevelFileSummary(
|
||||||
|
FileSummaryStorage* scratch, int level) const {
|
||||||
|
int len = snprintf(scratch->buffer, sizeof(scratch->buffer), "files_size[");
|
||||||
|
for (unsigned int i = 0; i < current_->files_[level].size(); i++) {
|
||||||
|
FileMetaData* f = current_->files_[level][i];
|
||||||
|
int sz = sizeof(scratch->buffer) - len;
|
||||||
|
int ret = snprintf(scratch->buffer + len, sz, "#%ld(seq=%ld,sz=%ld,%d) ",
|
||||||
|
f->number, f->smallest_seqno,
|
||||||
|
f->file_size, f->being_compacted);
|
||||||
|
if (ret < 0 || ret >= sz)
|
||||||
|
break;
|
||||||
|
len += ret;
|
||||||
|
}
|
||||||
|
snprintf(scratch->buffer + len, sizeof(scratch->buffer) - len, "]");
|
||||||
|
return scratch->buffer;
|
||||||
|
}
|
||||||
|
|
||||||
// Opens the mainfest file and reads all records
|
// Opens the mainfest file and reads all records
|
||||||
// till it finds the record we are looking for.
|
// till it finds the record we are looking for.
|
||||||
bool VersionSet::ManifestContains(const std::string& record) const {
|
bool VersionSet::ManifestContains(const std::string& record) const {
|
||||||
@ -1867,14 +1922,14 @@ int64_t VersionSet::NumLevelBytes(int level) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int64_t VersionSet::MaxNextLevelOverlappingBytes() {
|
int64_t VersionSet::MaxNextLevelOverlappingBytes() {
|
||||||
int64_t result = 0;
|
uint64_t result = 0;
|
||||||
std::vector<FileMetaData*> overlaps;
|
std::vector<FileMetaData*> overlaps;
|
||||||
for (int level = 1; level < NumberLevels() - 1; level++) {
|
for (int level = 1; level < NumberLevels() - 1; level++) {
|
||||||
for (size_t i = 0; i < current_->files_[level].size(); i++) {
|
for (size_t i = 0; i < current_->files_[level].size(); i++) {
|
||||||
const FileMetaData* f = current_->files_[level][i];
|
const FileMetaData* f = current_->files_[level][i];
|
||||||
current_->GetOverlappingInputs(level+1, &f->smallest, &f->largest,
|
current_->GetOverlappingInputs(level+1, &f->smallest, &f->largest,
|
||||||
&overlaps);
|
&overlaps);
|
||||||
const int64_t sum = TotalFileSize(overlaps);
|
const uint64_t sum = TotalFileSize(overlaps);
|
||||||
if (sum > result) {
|
if (sum > result) {
|
||||||
result = sum;
|
result = sum;
|
||||||
}
|
}
|
||||||
@ -1970,13 +2025,13 @@ uint64_t VersionSet::MaxFileSizeForLevel(int level) {
|
|||||||
return max_file_size_[level];
|
return max_file_size_[level];
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t VersionSet::ExpandedCompactionByteSizeLimit(int level) {
|
uint64_t VersionSet::ExpandedCompactionByteSizeLimit(int level) {
|
||||||
uint64_t result = MaxFileSizeForLevel(level);
|
uint64_t result = MaxFileSizeForLevel(level);
|
||||||
result *= options_->expanded_compaction_factor;
|
result *= options_->expanded_compaction_factor;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t VersionSet::MaxGrandParentOverlapBytes(int level) {
|
uint64_t VersionSet::MaxGrandParentOverlapBytes(int level) {
|
||||||
uint64_t result = MaxFileSizeForLevel(level);
|
uint64_t result = MaxFileSizeForLevel(level);
|
||||||
result *= options_->max_grandparent_overlap_factor;
|
result *= options_->max_grandparent_overlap_factor;
|
||||||
return result;
|
return result;
|
||||||
@ -2059,6 +2114,176 @@ void VersionSet::SizeBeingCompacted(std::vector<uint64_t>& sizes) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Compaction* VersionSet::PickCompactionUniversal(int level, double score) {
|
||||||
|
assert (level == 0);
|
||||||
|
|
||||||
|
// percentage flexibilty while comparing file sizes
|
||||||
|
uint64_t ratio = options_->compaction_options_universal.size_ratio;
|
||||||
|
unsigned int min_merge_width =
|
||||||
|
options_->compaction_options_universal.min_merge_width;
|
||||||
|
unsigned int max_merge_width =
|
||||||
|
options_->compaction_options_universal.max_merge_width;
|
||||||
|
|
||||||
|
if ((current_->files_[level].size() <=
|
||||||
|
(unsigned int)options_->level0_file_num_compaction_trigger)) {
|
||||||
|
Log(options_->info_log, "Universal: nothing to do\n");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
VersionSet::FileSummaryStorage tmp;
|
||||||
|
Log(options_->info_log, "Universal: candidate files(%lu): %s\n",
|
||||||
|
current_->files_[level].size(),
|
||||||
|
LevelFileSummary(&tmp, 0));
|
||||||
|
|
||||||
|
Compaction* c = nullptr;
|
||||||
|
c = new Compaction(level, level, MaxFileSizeForLevel(level),
|
||||||
|
LLONG_MAX, NumberLevels());
|
||||||
|
c->score_ = score;
|
||||||
|
|
||||||
|
// The files are sorted from newest first to oldest last.
|
||||||
|
std::vector<int>& file_by_time = current_->files_by_size_[level];
|
||||||
|
FileMetaData* f = nullptr;
|
||||||
|
bool done = false;
|
||||||
|
assert(file_by_time.size() == current_->files_[level].size());
|
||||||
|
|
||||||
|
unsigned int max_files_to_compact = std::min(max_merge_width, UINT_MAX);
|
||||||
|
|
||||||
|
// Make two pass. The first pass considers a candidate file
|
||||||
|
// only if it is smaller than the total size accumulated so far.
|
||||||
|
// The second pass does not look at the slope of the
|
||||||
|
// file-size curve to decide what to pick for compaction.
|
||||||
|
for (int iter = 0; !done && iter < 2; iter++) {
|
||||||
|
|
||||||
|
for (unsigned int loop = 0; loop < file_by_time.size(); ) {
|
||||||
|
|
||||||
|
// Skip files that are already being compacted
|
||||||
|
for (f = nullptr; loop < file_by_time.size(); loop++) {
|
||||||
|
int index = file_by_time[loop];
|
||||||
|
f = current_->files_[level][index];
|
||||||
|
|
||||||
|
if (!f->being_compacted) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Log(options_->info_log, "Universal: file %ld[%d] being compacted, skipping",
|
||||||
|
f->number, loop);
|
||||||
|
f = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This file is not being compacted. Consider it as the
|
||||||
|
// first candidate to be compacted.
|
||||||
|
unsigned int candidate_count = 1;
|
||||||
|
uint64_t candidate_size = f != nullptr? f->file_size : 0;
|
||||||
|
if (f != nullptr) {
|
||||||
|
Log(options_->info_log, "Universal: Possible candidate file %ld[%d] %s.",
|
||||||
|
f->number, loop, iter == 0? "" : "forced ");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the suceeding files need compaction.
|
||||||
|
for (unsigned int i = loop+1;
|
||||||
|
candidate_count < max_files_to_compact && i < file_by_time.size();
|
||||||
|
i++) {
|
||||||
|
int index = file_by_time[i];
|
||||||
|
FileMetaData* f = current_->files_[level][index];
|
||||||
|
if (f->being_compacted) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// If this is the first iteration, then we pick files if the
|
||||||
|
// total candidate file size (increased by the specified ratio)
|
||||||
|
// is still larger than the next candidate file.
|
||||||
|
if (iter == 0) {
|
||||||
|
uint64_t sz = (candidate_size * (100 + ratio)) /100;
|
||||||
|
if (sz < f->file_size) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
candidate_count++;
|
||||||
|
candidate_size += f->file_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Found a series of consecutive files that need compaction.
|
||||||
|
if (candidate_count >= (unsigned int)min_merge_width) {
|
||||||
|
for (unsigned int i = loop; i < loop + candidate_count; i++) {
|
||||||
|
int index = file_by_time[i];
|
||||||
|
FileMetaData* f = current_->files_[level][index];
|
||||||
|
c->inputs_[0].push_back(f);
|
||||||
|
Log(options_->info_log, "Universal: Picking file %ld[%d] with size %ld %s",
|
||||||
|
f->number, i, f->file_size,
|
||||||
|
(iter == 0 ? "" : "forced"));
|
||||||
|
}
|
||||||
|
done = true;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
for (unsigned int i = loop;
|
||||||
|
i < loop + candidate_count && i < file_by_time.size(); i++) {
|
||||||
|
int index = file_by_time[i];
|
||||||
|
FileMetaData* f = current_->files_[level][index];
|
||||||
|
Log(options_->info_log, "Universal: Skipping file %ld[%d] with size %ld %d %s",
|
||||||
|
f->number, i, f->file_size, f->being_compacted,
|
||||||
|
(iter == 0 ? "" : "forced"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
loop += candidate_count;
|
||||||
|
}
|
||||||
|
assert(done || c->inputs_[0].size() == 0);
|
||||||
|
|
||||||
|
// If we are unable to find a normal compaction run and we are still
|
||||||
|
// above the compaction threshold, iterate again to pick compaction
|
||||||
|
// candidates, this time without considering their size differences.
|
||||||
|
if (!done) {
|
||||||
|
int files_not_in_compaction = 0;
|
||||||
|
for (unsigned int i = 0; i < current_->files_[level].size(); i++) {
|
||||||
|
f = current_->files_[level][i];
|
||||||
|
if (!f->being_compacted) {
|
||||||
|
files_not_in_compaction++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int expected_num_files = files_not_in_compaction +
|
||||||
|
compactions_in_progress_[level].size();
|
||||||
|
if (expected_num_files <=
|
||||||
|
options_->level0_file_num_compaction_trigger + 1) {
|
||||||
|
done = true; // nothing more to do
|
||||||
|
} else {
|
||||||
|
max_files_to_compact = std::min((int)max_merge_width,
|
||||||
|
expected_num_files - options_->level0_file_num_compaction_trigger);
|
||||||
|
Log(options_->info_log, "Universal: second loop with maxfiles %d",
|
||||||
|
max_files_to_compact);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (c->inputs_[0].size() <= 1) {
|
||||||
|
Log(options_->info_log, "Universal: only %ld files, nothing to do.\n",
|
||||||
|
c->inputs_[0].size());
|
||||||
|
delete c;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// validate that all the chosen files are non overlapping in time
|
||||||
|
FileMetaData* newerfile __attribute__((unused)) = nullptr;
|
||||||
|
for (unsigned int i = 0; i < c->inputs_[0].size(); i++) {
|
||||||
|
FileMetaData* f = c->inputs_[0][i];
|
||||||
|
assert (f->smallest_seqno <= f->largest_seqno);
|
||||||
|
assert(newerfile == nullptr ||
|
||||||
|
newerfile->smallest_seqno > f->largest_seqno);
|
||||||
|
newerfile = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// update statistics
|
||||||
|
if (options_->statistics != nullptr) {
|
||||||
|
options_->statistics->measureTime(NUM_FILES_IN_SINGLE_COMPACTION,
|
||||||
|
c->inputs_[0].size());
|
||||||
|
}
|
||||||
|
|
||||||
|
c->input_version_ = current_;
|
||||||
|
c->input_version_->Ref();
|
||||||
|
|
||||||
|
// mark all the files that are being compacted
|
||||||
|
c->MarkFilesBeingCompacted(true);
|
||||||
|
|
||||||
|
// remember this currently undergoing compaction
|
||||||
|
compactions_in_progress_[level].insert(c);
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
Compaction* VersionSet::PickCompactionBySize(int level, double score) {
|
Compaction* VersionSet::PickCompactionBySize(int level, double score) {
|
||||||
Compaction* c = nullptr;
|
Compaction* c = nullptr;
|
||||||
|
|
||||||
@ -2072,7 +2297,7 @@ Compaction* VersionSet::PickCompactionBySize(int level, double score) {
|
|||||||
|
|
||||||
assert(level >= 0);
|
assert(level >= 0);
|
||||||
assert(level+1 < NumberLevels());
|
assert(level+1 < NumberLevels());
|
||||||
c = new Compaction(level, MaxFileSizeForLevel(level+1),
|
c = new Compaction(level, level+1, MaxFileSizeForLevel(level+1),
|
||||||
MaxGrandParentOverlapBytes(level), NumberLevels());
|
MaxGrandParentOverlapBytes(level), NumberLevels());
|
||||||
c->score_ = score;
|
c->score_ = score;
|
||||||
|
|
||||||
@ -2142,6 +2367,13 @@ Compaction* VersionSet::PickCompaction() {
|
|||||||
current_->vset_->SizeBeingCompacted(size_being_compacted);
|
current_->vset_->SizeBeingCompacted(size_being_compacted);
|
||||||
Finalize(current_, size_being_compacted);
|
Finalize(current_, size_being_compacted);
|
||||||
|
|
||||||
|
// In universal style of compaction, compact L0 files back into L0.
|
||||||
|
if (options_->compaction_style == kCompactionStyleUniversal) {
|
||||||
|
int level = 0;
|
||||||
|
c = PickCompactionUniversal(level, current_->compaction_score_[level]);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
// We prefer compactions triggered by too much data in a level over
|
// We prefer compactions triggered by too much data in a level over
|
||||||
// the compactions triggered by seeks.
|
// the compactions triggered by seeks.
|
||||||
//
|
//
|
||||||
@ -2171,7 +2403,7 @@ Compaction* VersionSet::PickCompaction() {
|
|||||||
if (level != 0 || compactions_in_progress_[0].empty()) {
|
if (level != 0 || compactions_in_progress_[0].empty()) {
|
||||||
if(!ParentRangeInCompaction(&f->smallest, &f->largest, level,
|
if(!ParentRangeInCompaction(&f->smallest, &f->largest, level,
|
||||||
&parent_index)) {
|
&parent_index)) {
|
||||||
c = new Compaction(level, MaxFileSizeForLevel(level+1),
|
c = new Compaction(level, level, MaxFileSizeForLevel(level+1),
|
||||||
MaxGrandParentOverlapBytes(level), NumberLevels(), true);
|
MaxGrandParentOverlapBytes(level), NumberLevels(), true);
|
||||||
c->inputs_[0].push_back(f);
|
c->inputs_[0].push_back(f);
|
||||||
c->parent_index_ = parent_index;
|
c->parent_index_ = parent_index;
|
||||||
@ -2331,10 +2563,10 @@ void VersionSet::SetupOtherInputs(Compaction* c) {
|
|||||||
std::vector<FileMetaData*> expanded0;
|
std::vector<FileMetaData*> expanded0;
|
||||||
current_->GetOverlappingInputs(level, &all_start, &all_limit, &expanded0,
|
current_->GetOverlappingInputs(level, &all_start, &all_limit, &expanded0,
|
||||||
c->base_index_, nullptr);
|
c->base_index_, nullptr);
|
||||||
const int64_t inputs0_size = TotalFileSize(c->inputs_[0]);
|
const uint64_t inputs0_size = TotalFileSize(c->inputs_[0]);
|
||||||
const int64_t inputs1_size = TotalFileSize(c->inputs_[1]);
|
const uint64_t inputs1_size = TotalFileSize(c->inputs_[1]);
|
||||||
const int64_t expanded0_size = TotalFileSize(expanded0);
|
const uint64_t expanded0_size = TotalFileSize(expanded0);
|
||||||
int64_t limit = ExpandedCompactionByteSizeLimit(level);
|
uint64_t limit = ExpandedCompactionByteSizeLimit(level);
|
||||||
if (expanded0.size() > c->inputs_[0].size() &&
|
if (expanded0.size() > c->inputs_[0].size() &&
|
||||||
inputs1_size + expanded0_size < limit &&
|
inputs1_size + expanded0_size < limit &&
|
||||||
!FilesInCompaction(expanded0) &&
|
!FilesInCompaction(expanded0) &&
|
||||||
@ -2414,7 +2646,10 @@ Compaction* VersionSet::CompactRange(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Compaction* c = new Compaction(level, MaxFileSizeForLevel(level+1),
|
int out_level = (options_->compaction_style == kCompactionStyleUniversal) ?
|
||||||
|
level : level+1;
|
||||||
|
|
||||||
|
Compaction* c = new Compaction(level, out_level, MaxFileSizeForLevel(out_level),
|
||||||
MaxGrandParentOverlapBytes(level), NumberLevels());
|
MaxGrandParentOverlapBytes(level), NumberLevels());
|
||||||
|
|
||||||
c->inputs_[0] = inputs;
|
c->inputs_[0] = inputs;
|
||||||
@ -2435,10 +2670,11 @@ Compaction* VersionSet::CompactRange(
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
Compaction::Compaction(int level, uint64_t target_file_size,
|
Compaction::Compaction(int level, int out_level, uint64_t target_file_size,
|
||||||
uint64_t max_grandparent_overlap_bytes, int number_levels,
|
uint64_t max_grandparent_overlap_bytes, int number_levels,
|
||||||
bool seek_compaction)
|
bool seek_compaction)
|
||||||
: level_(level),
|
: level_(level),
|
||||||
|
out_level_(out_level),
|
||||||
max_output_file_size_(target_file_size),
|
max_output_file_size_(target_file_size),
|
||||||
maxGrandParentOverlapBytes_(max_grandparent_overlap_bytes),
|
maxGrandParentOverlapBytes_(max_grandparent_overlap_bytes),
|
||||||
input_version_(nullptr),
|
input_version_(nullptr),
|
||||||
|
@ -352,6 +352,9 @@ class VersionSet {
|
|||||||
struct LevelSummaryStorage {
|
struct LevelSummaryStorage {
|
||||||
char buffer[100];
|
char buffer[100];
|
||||||
};
|
};
|
||||||
|
struct FileSummaryStorage {
|
||||||
|
char buffer[1000];
|
||||||
|
};
|
||||||
const char* LevelSummary(LevelSummaryStorage* scratch) const;
|
const char* LevelSummary(LevelSummaryStorage* scratch) const;
|
||||||
|
|
||||||
// printf contents (for debugging)
|
// printf contents (for debugging)
|
||||||
@ -362,6 +365,10 @@ class VersionSet {
|
|||||||
// of files per level. Uses *scratch as backing store.
|
// of files per level. Uses *scratch as backing store.
|
||||||
const char* LevelDataSizeSummary(LevelSummaryStorage* scratch) const;
|
const char* LevelDataSizeSummary(LevelSummaryStorage* scratch) const;
|
||||||
|
|
||||||
|
// Return a human-readable short (single-line) summary of files
|
||||||
|
// in a specified level. Uses *scratch as backing store.
|
||||||
|
const char* LevelFileSummary(FileSummaryStorage* scratch, int level) const;
|
||||||
|
|
||||||
// Return the size of the current manifest file
|
// Return the size of the current manifest file
|
||||||
const uint64_t ManifestFileSize() { return current_->offset_manifest_file_; }
|
const uint64_t ManifestFileSize() { return current_->offset_manifest_file_; }
|
||||||
|
|
||||||
@ -371,6 +378,9 @@ class VersionSet {
|
|||||||
// function will return nullptr.
|
// function will return nullptr.
|
||||||
Compaction* PickCompactionBySize(int level, double score);
|
Compaction* PickCompactionBySize(int level, double score);
|
||||||
|
|
||||||
|
// Pick files to compact in Universal mode
|
||||||
|
Compaction* PickCompactionUniversal(int level, double score);
|
||||||
|
|
||||||
// Free up the files that were participated in a compaction
|
// Free up the files that were participated in a compaction
|
||||||
void ReleaseCompactionFiles(Compaction* c, Status status);
|
void ReleaseCompactionFiles(Compaction* c, Status status);
|
||||||
|
|
||||||
@ -426,9 +436,9 @@ class VersionSet {
|
|||||||
|
|
||||||
bool ManifestContains(const std::string& record) const;
|
bool ManifestContains(const std::string& record) const;
|
||||||
|
|
||||||
int64_t ExpandedCompactionByteSizeLimit(int level);
|
uint64_t ExpandedCompactionByteSizeLimit(int level);
|
||||||
|
|
||||||
int64_t MaxGrandParentOverlapBytes(int level);
|
uint64_t MaxGrandParentOverlapBytes(int level);
|
||||||
|
|
||||||
Env* const env_;
|
Env* const env_;
|
||||||
const std::string dbname_;
|
const std::string dbname_;
|
||||||
@ -503,9 +513,12 @@ class Compaction {
|
|||||||
~Compaction();
|
~Compaction();
|
||||||
|
|
||||||
// Return the level that is being compacted. Inputs from "level"
|
// Return the level that is being compacted. Inputs from "level"
|
||||||
// and "level+1" will be merged to produce a set of "level+1" files.
|
// will be merged.
|
||||||
int level() const { return level_; }
|
int level() const { return level_; }
|
||||||
|
|
||||||
|
// Outputs will go to this level
|
||||||
|
int output_level() const { return out_level_; }
|
||||||
|
|
||||||
// Return the object that holds the edits to the descriptor done
|
// Return the object that holds the edits to the descriptor done
|
||||||
// by this compaction.
|
// by this compaction.
|
||||||
VersionEdit* edit() { return edit_; }
|
VersionEdit* edit() { return edit_; }
|
||||||
@ -548,13 +561,14 @@ class Compaction {
|
|||||||
friend class Version;
|
friend class Version;
|
||||||
friend class VersionSet;
|
friend class VersionSet;
|
||||||
|
|
||||||
explicit Compaction(int level, uint64_t target_file_size,
|
explicit Compaction(int level, int out_level, uint64_t target_file_size,
|
||||||
uint64_t max_grandparent_overlap_bytes, int number_levels,
|
uint64_t max_grandparent_overlap_bytes, int number_levels,
|
||||||
bool seek_compaction = false);
|
bool seek_compaction = false);
|
||||||
|
|
||||||
int level_;
|
int level_;
|
||||||
|
int out_level_; // levels to which output files are stored
|
||||||
uint64_t max_output_file_size_;
|
uint64_t max_output_file_size_;
|
||||||
int64_t maxGrandParentOverlapBytes_;
|
uint64_t maxGrandParentOverlapBytes_;
|
||||||
Version* input_version_;
|
Version* input_version_;
|
||||||
VersionEdit* edit_;
|
VersionEdit* edit_;
|
||||||
int number_levels_;
|
int number_levels_;
|
||||||
@ -569,7 +583,7 @@ class Compaction {
|
|||||||
std::vector<FileMetaData*> grandparents_;
|
std::vector<FileMetaData*> grandparents_;
|
||||||
size_t grandparent_index_; // Index in grandparent_starts_
|
size_t grandparent_index_; // Index in grandparent_starts_
|
||||||
bool seen_key_; // Some output key has been seen
|
bool seen_key_; // Some output key has been seen
|
||||||
int64_t overlapped_bytes_; // Bytes of overlap between current output
|
uint64_t overlapped_bytes_; // Bytes of overlap between current output
|
||||||
// and grandparent files
|
// and grandparent files
|
||||||
int base_index_; // index of the file in files_[level_]
|
int base_index_; // index of the file in files_[level_]
|
||||||
int parent_index_; // index of some file with same range in files_[level_+1]
|
int parent_index_; // index of some file with same range in files_[level_+1]
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "leveldb/slice.h"
|
#include "leveldb/slice.h"
|
||||||
#include "leveldb/statistics.h"
|
#include "leveldb/statistics.h"
|
||||||
|
#include "leveldb/universal_compaction.h"
|
||||||
#include "leveldb/memtablerep.h"
|
#include "leveldb/memtablerep.h"
|
||||||
|
|
||||||
namespace leveldb {
|
namespace leveldb {
|
||||||
@ -40,6 +41,11 @@ enum CompressionType {
|
|||||||
kBZip2Compression = 0x3
|
kBZip2Compression = 0x3
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum CompactionStyle {
|
||||||
|
kCompactionStyleLevel = 0x0, // level based compaction style
|
||||||
|
kCompactionStyleUniversal = 0x1 // Universal compaction style
|
||||||
|
};
|
||||||
|
|
||||||
// Compression options for different compression algorithms like Zlib
|
// Compression options for different compression algorithms like Zlib
|
||||||
struct CompressionOptions {
|
struct CompressionOptions {
|
||||||
int window_bits;
|
int window_bits;
|
||||||
@ -483,6 +489,12 @@ struct Options {
|
|||||||
// Default: 0
|
// Default: 0
|
||||||
uint64_t bytes_per_sync;
|
uint64_t bytes_per_sync;
|
||||||
|
|
||||||
|
// The compaction style. Default: kCompactionStyleLevel
|
||||||
|
CompactionStyle compaction_style;
|
||||||
|
|
||||||
|
// The options needed to support Universal Style compactions
|
||||||
|
CompactionOptionsUniversal compaction_options_universal;
|
||||||
|
|
||||||
// Use KeyMayExist API to filter deletes when this is true.
|
// Use KeyMayExist API to filter deletes when this is true.
|
||||||
// If KeyMayExist returns false, i.e. the key definitely does not exist, then
|
// If KeyMayExist returns false, i.e. the key definitely does not exist, then
|
||||||
// the delete is a noop. KeyMayExist only incurs in-memory look up.
|
// the delete is a noop. KeyMayExist only incurs in-memory look up.
|
||||||
@ -494,7 +506,6 @@ struct Options {
|
|||||||
// Default: a factory that provides a skip-list-based implementation of
|
// Default: a factory that provides a skip-list-based implementation of
|
||||||
// MemTableRep.
|
// MemTableRep.
|
||||||
std::shared_ptr<MemTableRepFactory> memtable_factory;
|
std::shared_ptr<MemTableRepFactory> memtable_factory;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Options that control read operations
|
// Options that control read operations
|
||||||
|
@ -115,7 +115,8 @@ enum Histograms {
|
|||||||
STALL_L0_NUM_FILES_COUNT = 14,
|
STALL_L0_NUM_FILES_COUNT = 14,
|
||||||
HARD_RATE_LIMIT_DELAY_COUNT = 15,
|
HARD_RATE_LIMIT_DELAY_COUNT = 15,
|
||||||
SOFT_RATE_LIMIT_DELAY_COUNT = 16,
|
SOFT_RATE_LIMIT_DELAY_COUNT = 16,
|
||||||
HISTOGRAM_ENUM_MAX = 17
|
NUM_FILES_IN_SINGLE_COMPACTION = 17,
|
||||||
|
HISTOGRAM_ENUM_MAX = 18
|
||||||
};
|
};
|
||||||
|
|
||||||
const std::vector<std::pair<Histograms, std::string>> HistogramsNameMap = {
|
const std::vector<std::pair<Histograms, std::string>> HistogramsNameMap = {
|
||||||
@ -135,7 +136,8 @@ const std::vector<std::pair<Histograms, std::string>> HistogramsNameMap = {
|
|||||||
{ STALL_MEMTABLE_COMPACTION_COUNT, "rocksdb.memtable.compaction.count"},
|
{ STALL_MEMTABLE_COMPACTION_COUNT, "rocksdb.memtable.compaction.count"},
|
||||||
{ STALL_L0_NUM_FILES_COUNT, "rocksdb.num.files.stall.count"},
|
{ STALL_L0_NUM_FILES_COUNT, "rocksdb.num.files.stall.count"},
|
||||||
{ HARD_RATE_LIMIT_DELAY_COUNT, "rocksdb.hard.rate.limit.delay.count"},
|
{ HARD_RATE_LIMIT_DELAY_COUNT, "rocksdb.hard.rate.limit.delay.count"},
|
||||||
{ SOFT_RATE_LIMIT_DELAY_COUNT, "rocksdb.soft.rate.limit.delay.count"}
|
{ SOFT_RATE_LIMIT_DELAY_COUNT, "rocksdb.soft.rate.limit.delay.count"},
|
||||||
|
{ NUM_FILES_IN_SINGLE_COMPACTION, "rocksdb.numfiles.in.singlecompaction" }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct HistogramData {
|
struct HistogramData {
|
||||||
|
57
include/leveldb/universal_compaction.h
Normal file
57
include/leveldb/universal_compaction.h
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file. See the AUTHORS file for names of contributors.
|
||||||
|
|
||||||
|
#ifndef STORAGE_ROCKSDB_UNIVERSAL_COMPACTION_OPTIONS_H
|
||||||
|
#define STORAGE_ROCKSDB_UNIVERSAL_COMPACTION_OPTIONS_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <climits>
|
||||||
|
#include "leveldb/slice.h"
|
||||||
|
#include "leveldb/statistics.h"
|
||||||
|
|
||||||
|
namespace leveldb {
|
||||||
|
|
||||||
|
//
|
||||||
|
// Algorithm used to make a compaction request stop picking new files
|
||||||
|
// into a single compaction run
|
||||||
|
//
|
||||||
|
enum CompactionStopStyle {
|
||||||
|
kCompactionStopStyleSimilarSize, // pick files of similar size
|
||||||
|
kCompactionStopStyleTotalSize // total size of picked files > next file
|
||||||
|
};
|
||||||
|
|
||||||
|
class CompactionOptionsUniversal {
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Percentage flexibilty while comparing file size. If the candidate file(s)
|
||||||
|
// size is 1% smaller than the next file's size, then include next file into
|
||||||
|
// this candidate set. // Default: 1
|
||||||
|
unsigned int size_ratio;
|
||||||
|
|
||||||
|
// The minimum number of files in a single compaction run. Default: 2
|
||||||
|
unsigned int min_merge_width;
|
||||||
|
|
||||||
|
// The maximum number of files in a single compaction run. Default: INT_MAX
|
||||||
|
unsigned int max_merge_width;
|
||||||
|
|
||||||
|
// The algorithm used to stop picking files into a single compaction run
|
||||||
|
// Default: kCompactionStopStyleTotalSize
|
||||||
|
CompactionStopStyle stop_style;
|
||||||
|
|
||||||
|
// Default set of parameters
|
||||||
|
CompactionOptionsUniversal() :
|
||||||
|
size_ratio(1),
|
||||||
|
min_merge_width(2),
|
||||||
|
max_merge_width(UINT_MAX),
|
||||||
|
stop_style(kCompactionStopStyleTotalSize) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace leveldb
|
||||||
|
|
||||||
|
#endif // STORAGE_ROCKSDB_UNIVERSAL_COMPACTION_OPTIONS_H
|
@ -88,6 +88,9 @@ static int FLAGS_max_write_buffer_number = 0;
|
|||||||
// This is initialized to default value of 1 in "main" function.
|
// This is initialized to default value of 1 in "main" function.
|
||||||
static int FLAGS_max_background_compactions = 0;
|
static int FLAGS_max_background_compactions = 0;
|
||||||
|
|
||||||
|
// This is initialized to default value of false
|
||||||
|
static leveldb::CompactionStyle FLAGS_compaction_style = leveldb::kCompactionStyleLevel;
|
||||||
|
|
||||||
// Number of bytes to use as a cache of uncompressed data.
|
// Number of bytes to use as a cache of uncompressed data.
|
||||||
static long FLAGS_cache_size = 2 * KB * KB * KB;
|
static long FLAGS_cache_size = 2 * KB * KB * KB;
|
||||||
|
|
||||||
@ -935,6 +938,7 @@ class StressTest {
|
|||||||
options.write_buffer_size = FLAGS_write_buffer_size;
|
options.write_buffer_size = FLAGS_write_buffer_size;
|
||||||
options.max_write_buffer_number = FLAGS_max_write_buffer_number;
|
options.max_write_buffer_number = FLAGS_max_write_buffer_number;
|
||||||
options.max_background_compactions = FLAGS_max_background_compactions;
|
options.max_background_compactions = FLAGS_max_background_compactions;
|
||||||
|
options.compaction_style = FLAGS_compaction_style;
|
||||||
options.block_size = FLAGS_block_size;
|
options.block_size = FLAGS_block_size;
|
||||||
options.filter_policy = filter_policy_;
|
options.filter_policy = filter_policy_;
|
||||||
options.max_open_files = FLAGS_open_files;
|
options.max_open_files = FLAGS_open_files;
|
||||||
@ -1021,6 +1025,8 @@ int main(int argc, char** argv) {
|
|||||||
FLAGS_open_files = leveldb::Options().max_open_files;
|
FLAGS_open_files = leveldb::Options().max_open_files;
|
||||||
FLAGS_max_background_compactions =
|
FLAGS_max_background_compactions =
|
||||||
leveldb::Options().max_background_compactions;
|
leveldb::Options().max_background_compactions;
|
||||||
|
FLAGS_compaction_style =
|
||||||
|
leveldb::Options().compaction_style;
|
||||||
FLAGS_level0_file_num_compaction_trigger =
|
FLAGS_level0_file_num_compaction_trigger =
|
||||||
leveldb::Options().level0_file_num_compaction_trigger;
|
leveldb::Options().level0_file_num_compaction_trigger;
|
||||||
FLAGS_level0_slowdown_writes_trigger =
|
FLAGS_level0_slowdown_writes_trigger =
|
||||||
@ -1073,6 +1079,8 @@ int main(int argc, char** argv) {
|
|||||||
FLAGS_max_write_buffer_number = n;
|
FLAGS_max_write_buffer_number = n;
|
||||||
} else if (sscanf(argv[i], "--max_background_compactions=%d%c", &n, &junk) == 1) {
|
} else if (sscanf(argv[i], "--max_background_compactions=%d%c", &n, &junk) == 1) {
|
||||||
FLAGS_max_background_compactions = n;
|
FLAGS_max_background_compactions = n;
|
||||||
|
} else if (sscanf(argv[i], "--compaction_style=%d%c", &n, &junk) == 1) {
|
||||||
|
FLAGS_compaction_style = (leveldb::CompactionStyle)n;
|
||||||
} else if (sscanf(argv[i], "--cache_size=%ld%c", &l, &junk) == 1) {
|
} else if (sscanf(argv[i], "--cache_size=%ld%c", &l, &junk) == 1) {
|
||||||
FLAGS_cache_size = l;
|
FLAGS_cache_size = l;
|
||||||
} else if (sscanf(argv[i], "--block_size=%d%c", &n, &junk) == 1) {
|
} else if (sscanf(argv[i], "--block_size=%d%c", &n, &junk) == 1) {
|
||||||
|
@ -1197,7 +1197,7 @@ void ApproxSizeCommand::DoCommand() {
|
|||||||
uint64_t sizes[1];
|
uint64_t sizes[1];
|
||||||
db_->GetApproximateSizes(ranges, 1, sizes);
|
db_->GetApproximateSizes(ranges, 1, sizes);
|
||||||
fprintf(stdout, "%ld\n", sizes[0]);
|
fprintf(stdout, "%ld\n", sizes[0]);
|
||||||
/* Wierd that GetApproximateSizes() returns void, although documentation
|
/* Weird that GetApproximateSizes() returns void, although documentation
|
||||||
* says that it returns a Status object.
|
* says that it returns a Status object.
|
||||||
if (!st.ok()) {
|
if (!st.ok()) {
|
||||||
exec_state_ = LDBCommandExecuteResult::FAILED(st.ToString());
|
exec_state_ = LDBCommandExecuteResult::FAILED(st.ToString());
|
||||||
|
@ -78,6 +78,7 @@ Options::Options()
|
|||||||
access_hint_on_compaction_start(NORMAL),
|
access_hint_on_compaction_start(NORMAL),
|
||||||
use_adaptive_mutex(false),
|
use_adaptive_mutex(false),
|
||||||
bytes_per_sync(0),
|
bytes_per_sync(0),
|
||||||
|
compaction_style(kCompactionStyleLevel),
|
||||||
filter_deletes(false),
|
filter_deletes(false),
|
||||||
memtable_factory(std::shared_ptr<SkipListFactory>(new SkipListFactory)) {
|
memtable_factory(std::shared_ptr<SkipListFactory>(new SkipListFactory)) {
|
||||||
assert(memtable_factory.get() != nullptr);
|
assert(memtable_factory.get() != nullptr);
|
||||||
@ -218,6 +219,14 @@ Options::Dump(Logger* log) const
|
|||||||
bytes_per_sync);
|
bytes_per_sync);
|
||||||
Log(log," Options.filter_deletes: %d",
|
Log(log," Options.filter_deletes: %d",
|
||||||
filter_deletes);
|
filter_deletes);
|
||||||
|
Log(log," Options.compaction_style: %d",
|
||||||
|
compaction_style);
|
||||||
|
Log(log," Options.compaction_options_universal.size_ratio: %d",
|
||||||
|
compaction_options_universal.size_ratio);
|
||||||
|
Log(log," Options.compaction_options_universal.min_merge_width: %d",
|
||||||
|
compaction_options_universal.min_merge_width);
|
||||||
|
Log(log," Options.compaction_options_universal.max_merge_width: %d",
|
||||||
|
compaction_options_universal.max_merge_width);
|
||||||
} // Options::Dump
|
} // Options::Dump
|
||||||
|
|
||||||
//
|
//
|
||||||
|
Loading…
Reference in New Issue
Block a user