Assertion failure while running with unit tests with OPT=-g

Summary:
When we expand the range of keys for a level 0 compaction, we
need to invoke ParentFilesInCompaction() only once for the
entire range of keys that is being compacted. We were invoking
it for each file that was being compacted, but this triggers
an assertion because each file's range were contiguous but
non-overlapping.

I renamed ParentFilesInCompaction to ParentRangeInCompaction
to adequately represent that it is the range-of-keys and
not individual files that we compact in a single compaction run.

Here is the assertion that is fixed by this patch.
db_test: db/version_set.cc:585: void leveldb::Version::ExtendOverlappingInputs(int, const leveldb::Slice&, const leveldb::Slice&, std::vector<leveldb::FileMetaData*, std::allocator<leveldb::FileMetaData*> >*, int): Assertion `user_cmp->Compare(flimit, user_begin) >= 0' failed.

Test Plan: make clean check OPT=-g

Reviewers: sheki

Reviewed By: sheki

CC: MarkCallaghan, emayanke, leveldb

Differential Revision: https://reviews.facebook.net/D6963
This commit is contained in:
Dhruba Borthakur 2012-11-26 01:49:50 -08:00
parent 7c6f5278a2
commit 2a39699900
2 changed files with 18 additions and 8 deletions

View File

@ -474,6 +474,9 @@ void Version::GetOverlappingInputs(
if (end != NULL) { if (end != NULL) {
user_end = end->user_key(); user_end = end->user_key();
} }
if (file_index) {
*file_index = -1;
}
const Comparator* user_cmp = vset_->icmp_.user_comparator(); const Comparator* user_cmp = vset_->icmp_.user_comparator();
if (begin != NULL && end != NULL && level > 0) { if (begin != NULL && end != NULL && level > 0) {
GetOverlappingInputsBinarySearch(level, user_begin, user_end, inputs, GetOverlappingInputsBinarySearch(level, user_begin, user_end, inputs,
@ -503,7 +506,7 @@ void Version::GetOverlappingInputs(
i = 0; i = 0;
} }
} else if (file_index) { } else if (file_index) {
*file_index = i; *file_index = i-1;
} }
} }
} }
@ -1835,7 +1838,8 @@ Compaction* VersionSet::PickCompactionBySize(int level) {
// Do not pick this file if its parents at level+1 are being compacted. // Do not pick this file if its parents at level+1 are being compacted.
// Maybe we can avoid redoing this work in SetupOtherInputs // Maybe we can avoid redoing this work in SetupOtherInputs
int parent_index = -1; int parent_index = -1;
if (ParentFilesInCompaction(f, level, &parent_index)) { if (ParentRangeInCompaction(&f->smallest, &f->largest, level,
&parent_index)) {
continue; continue;
} }
c->inputs_[0].push_back(f); c->inputs_[0].push_back(f);
@ -1904,10 +1908,14 @@ Compaction* VersionSet::PickCompaction() {
c->inputs_[0].clear(); c->inputs_[0].clear();
std::vector<FileMetaData*> more; std::vector<FileMetaData*> more;
current_->GetOverlappingInputs(0, &smallest, &largest, &more); current_->GetOverlappingInputs(0, &smallest, &largest, &more);
if (ParentRangeInCompaction(&smallest, &largest,
level, &c->parent_index_)) {
delete c;
return NULL;
}
for (unsigned int i = 0; i < more.size(); i++) { for (unsigned int i = 0; i < more.size(); i++) {
FileMetaData* f = more[i]; FileMetaData* f = more[i];
if (!f->being_compacted && if (!f->being_compacted) {
!ParentFilesInCompaction(f, level, &c->parent_index_)) {
c->inputs_[0].push_back(f); c->inputs_[0].push_back(f);
} }
} }
@ -1926,10 +1934,11 @@ Compaction* VersionSet::PickCompaction() {
} }
// Returns true if any one of the parent files are being compacted // Returns true if any one of the parent files are being compacted
bool VersionSet::ParentFilesInCompaction(FileMetaData* f, int level, bool VersionSet::ParentRangeInCompaction(const InternalKey* smallest,
int* parent_index) { const InternalKey* largest, int level, int* parent_index) {
std::vector<FileMetaData*> inputs; std::vector<FileMetaData*> inputs;
current_->GetOverlappingInputs(level+1, &f->smallest, &f->largest,
current_->GetOverlappingInputs(level+1, smallest, largest,
&inputs, *parent_index, parent_index); &inputs, *parent_index, parent_index);
return FilesInCompaction(inputs); return FilesInCompaction(inputs);
} }

View File

@ -448,7 +448,8 @@ class VersionSet {
uint64_t SizeBeingCompacted(int level); uint64_t SizeBeingCompacted(int level);
// Returns true if any one of the parent files are being compacted // Returns true if any one of the parent files are being compacted
bool ParentFilesInCompaction(FileMetaData* f, int level, int* index); bool ParentRangeInCompaction(const InternalKey* smallest,
const InternalKey* largest, int level, int* index);
// Returns true if any one of the specified files are being compacted // Returns true if any one of the specified files are being compacted
bool FilesInCompaction(std::vector<FileMetaData*>& files); bool FilesInCompaction(std::vector<FileMetaData*>& files);