Skip to content

Commit

Permalink
A number of fixes:
Browse files Browse the repository at this point in the history
- Replace raw slice comparison with a call to user comparator.
  Added test for custom comparators.

- Fix end of namespace comments.

- Fixed bug in picking inputs for a level-0 compaction.

  When finding overlapping files, the covered range may expand
  as files are added to the input set.  We now correctly expand
  the range when this happens instead of continuing to use the
  old range.  For example, suppose L0 contains files with the
  following ranges:

      F1: a .. d
      F2:    c .. g
      F3:       f .. j

  and the initial compaction target is F3.  We used to search
  for range f..j which yielded {F2,F3}.  However we now expand
  the range as soon as another file is added.  In this case,
  when F2 is added, we expand the range to c..j and restart the
  search.  That picks up file F1 as well.

  This change fixes a bug related to deleted keys showing up
  incorrectly after a compaction as described in Issue 44.

(Sync with upstream @25072954)
  • Loading branch information
zmodem committed Oct 31, 2011
1 parent 299cced commit 36a5f8e
Show file tree
Hide file tree
Showing 102 changed files with 258 additions and 146 deletions.
2 changes: 1 addition & 1 deletion db/builder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,4 @@ Status BuildTable(const std::string& dbname,
return s;
}

}
} // namespace leveldb
2 changes: 1 addition & 1 deletion db/builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,6 @@ extern Status BuildTable(const std::string& dbname,
Iterator* iter,
FileMetaData* meta);

}
} // namespace leveldb

#endif // STORAGE_LEVELDB_DB_BUILDER_H_
2 changes: 1 addition & 1 deletion db/corruption_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@ TEST(CorruptionTest, UnrelatedKeys) {
ASSERT_EQ(Value(1000, &tmp2).ToString(), v);
}

}
} // namespace leveldb

int main(int argc, char** argv) {
return leveldb::test::RunAllTests();
Expand Down
4 changes: 2 additions & 2 deletions db/db_bench.cc
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ struct ThreadState {
}
};

}
} // namespace

class Benchmark {
private:
Expand Down Expand Up @@ -829,7 +829,7 @@ class Benchmark {
}
};

}
} // namespace leveldb

int main(int argc, char** argv) {
FLAGS_write_buffer_size = leveldb::Options().write_buffer_size;
Expand Down
4 changes: 2 additions & 2 deletions db/db_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -985,7 +985,7 @@ static void CleanupIteratorState(void* arg1, void* arg2) {
state->mu->Unlock();
delete state;
}
}
} // namespace

Iterator* DBImpl::NewInternalIterator(const ReadOptions& options,
SequenceNumber* latest_snapshot) {
Expand Down Expand Up @@ -1378,4 +1378,4 @@ Status DestroyDB(const std::string& dbname, const Options& options) {
return result;
}

}
} // namespace leveldb
2 changes: 1 addition & 1 deletion db/db_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,6 @@ extern Options SanitizeOptions(const std::string& db,
const InternalKeyComparator* icmp,
const Options& src);

}
} // namespace leveldb

#endif // STORAGE_LEVELDB_DB_DB_IMPL_H_
2 changes: 1 addition & 1 deletion db/db_iter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -296,4 +296,4 @@ Iterator* NewDBIterator(
return new DBIter(dbname, env, user_key_comparator, internal_iter, sequence);
}

}
} // namespace leveldb
2 changes: 1 addition & 1 deletion db/db_iter.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@ extern Iterator* NewDBIterator(
Iterator* internal_iter,
const SequenceNumber& sequence);

}
} // namespace leveldb

#endif // STORAGE_LEVELDB_DB_DB_ITER_H_
102 changes: 100 additions & 2 deletions db/db_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,33 @@ class DBTest {
return result;
}

// Return a string that contains all key,value pairs in order,
// formatted like "(k1->v1)(k2->v2)".
std::string Contents() {
std::vector<std::string> forward;
std::string result;
Iterator* iter = db_->NewIterator(ReadOptions());
for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {
std::string s = IterStatus(iter);
result.push_back('(');
result.append(s);
result.push_back(')');
forward.push_back(s);
}

// Check reverse iteration results are the reverse of forward results
int matched = 0;
for (iter->SeekToLast(); iter->Valid(); iter->Prev()) {
ASSERT_LT(matched, forward.size());
ASSERT_EQ(IterStatus(iter), forward[forward.size() - matched - 1]);
matched++;
}
ASSERT_EQ(matched, forward.size());

delete iter;
return result;
}

std::string AllEntriesFor(const Slice& user_key) {
Iterator* iter = dbfull()->TEST_NewInternalIterator();
InternalKey target(user_key, kMaxSequenceNumber, kTypeValue);
Expand Down Expand Up @@ -1048,6 +1075,49 @@ TEST(DBTest, OverlapInLevel0) {
ASSERT_EQ("NOT_FOUND", Get("600"));
}

TEST(DBTest, L0_CompactionBug_Issue44_a) {
Reopen();
ASSERT_OK(Put("b", "v"));
Reopen();
ASSERT_OK(Delete("b"));
ASSERT_OK(Delete("a"));
Reopen();
ASSERT_OK(Delete("a"));
Reopen();
ASSERT_OK(Put("a", "v"));
Reopen();
Reopen();
ASSERT_EQ("(a->v)", Contents());
env_->SleepForMicroseconds(1000000); // Wait for compaction to finish
ASSERT_EQ("(a->v)", Contents());
}

TEST(DBTest, L0_CompactionBug_Issue44_b) {
Reopen();
Put("","");
Reopen();
Delete("e");
Put("","");
Reopen();
Put("c", "cv");
Reopen();
Put("","");
Reopen();
Put("","");
env_->SleepForMicroseconds(1000000); // Wait for compaction to finish
Reopen();
Put("d","dv");
Reopen();
Put("","");
Reopen();
Delete("d");
Delete("b");
Reopen();
ASSERT_EQ("(->)(c->cv)", Contents());
env_->SleepForMicroseconds(1000000); // Wait for compaction to finish
ASSERT_EQ("(->)(c->cv)", Contents());
}

TEST(DBTest, ComparatorCheck) {
class NewComparator : public Comparator {
public:
Expand All @@ -1071,6 +1141,34 @@ TEST(DBTest, ComparatorCheck) {
<< s.ToString();
}

TEST(DBTest, CustomComparator) {
class NumberComparator : public Comparator {
public:
virtual const char* Name() const { return "test.NumberComparator"; }
virtual int Compare(const Slice& a, const Slice& b) const {
return (strtol(a.ToString().c_str(), NULL, 0) -
strtol(b.ToString().c_str(), NULL, 0));
}
virtual void FindShortestSeparator(std::string* s, const Slice& l) const {}
virtual void FindShortSuccessor(std::string* key) const {}
};
NumberComparator cmp;
Options new_options;
new_options.create_if_missing = true;
new_options.comparator = &cmp;
DestroyAndReopen(&new_options);
ASSERT_OK(Put("10", "ten"));
ASSERT_OK(Put("0x14", "twenty"));
for (int i = 0; i < 2; i++) {
ASSERT_EQ("ten", Get("10"));
ASSERT_EQ("ten", Get("0xa"));
ASSERT_EQ("twenty", Get("20"));
ASSERT_EQ("twenty", Get("0x14"));
Compact("0", "9999");
fprintf(stderr, "ss\n%s\n", DumpSSTableList().c_str());
}
}

TEST(DBTest, ManualCompaction) {
ASSERT_EQ(config::kMaxMemCompactLevel, 2)
<< "Need to update this test to match kMaxMemCompactLevel";
Expand Down Expand Up @@ -1207,7 +1305,7 @@ static void MTThreadBody(void* arg) {
fprintf(stderr, "... stopping thread %d after %d ops\n", t->id, int(counter));
}

}
} // namespace

TEST(DBTest, MultiThreaded) {
// Initialize state
Expand Down Expand Up @@ -1525,7 +1623,7 @@ void BM_LogAndApply(int iters, int num_base_files) {
buf, iters, us, ((float)us) / iters);
}

}
} // namespace leveldb

int main(int argc, char** argv) {
if (argc > 1 && std::string(argv[1]) == "--benchmark") {
Expand Down
2 changes: 1 addition & 1 deletion db/dbformat.cc
Original file line number Diff line number Diff line change
Expand Up @@ -115,4 +115,4 @@ LookupKey::LookupKey(const Slice& user_key, SequenceNumber s) {
end_ = dst;
}

}
} // namespace leveldb
4 changes: 2 additions & 2 deletions db/dbformat.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ static const int kL0_StopWritesTrigger = 12;
// space if the same key space is being repeatedly overwritten.
static const int kMaxMemCompactLevel = 2;

}
} // namespace config

class InternalKey;

Expand Down Expand Up @@ -210,6 +210,6 @@ inline LookupKey::~LookupKey() {
if (start_ != space_) delete[] start_;
}

}
} // namespace leveldb

#endif // STORAGE_LEVELDB_DB_FORMAT_H_
2 changes: 1 addition & 1 deletion db/dbformat_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ TEST(FormatTest, InternalKeyShortestSuccessor) {
ShortSuccessor(IKey("\xff\xff", 100, kTypeValue)));
}

}
} // namespace leveldb

int main(int argc, char** argv) {
return leveldb::test::RunAllTests();
Expand Down
2 changes: 1 addition & 1 deletion db/filename.cc
Original file line number Diff line number Diff line change
Expand Up @@ -132,4 +132,4 @@ Status SetCurrentFile(Env* env, const std::string& dbname,
return s;
}

}
} // namespace leveldb
2 changes: 1 addition & 1 deletion db/filename.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,6 @@ extern Status SetCurrentFile(Env* env, const std::string& dbname,
uint64_t descriptor_number);


}
} // namespace leveldb

#endif // STORAGE_LEVELDB_DB_FILENAME_H_
2 changes: 1 addition & 1 deletion db/filename_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ TEST(FileNameTest, Construction) {
ASSERT_EQ(kTempFile, type);
}

}
} // namespace leveldb

int main(int argc, char** argv) {
return leveldb::test::RunAllTests();
Expand Down
4 changes: 2 additions & 2 deletions db/log_format.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ static const int kBlockSize = 32768;
// Header is checksum (4 bytes), type (1 byte), length (2 bytes).
static const int kHeaderSize = 4 + 1 + 2;

}
}
} // namespace log
} // namespace leveldb

#endif // STORAGE_LEVELDB_DB_LOG_FORMAT_H_
4 changes: 2 additions & 2 deletions db/log_reader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -255,5 +255,5 @@ unsigned int Reader::ReadPhysicalRecord(Slice* result) {
}
}

}
}
} // namespace log
} // namespace leveldb
4 changes: 2 additions & 2 deletions db/log_reader.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ class Reader {
void operator=(const Reader&);
};

}
}
} // namespace log
} // namespace leveldb

#endif // STORAGE_LEVELDB_DB_LOG_READER_H_
4 changes: 2 additions & 2 deletions db/log_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -492,8 +492,8 @@ TEST(LogTest, ReadPastEnd) {
CheckOffsetPastEndReturnsNoRecords(5);
}

}
}
} // namespace log
} // namespace leveldb

int main(int argc, char** argv) {
return leveldb::test::RunAllTests();
Expand Down
4 changes: 2 additions & 2 deletions db/log_writer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -99,5 +99,5 @@ Status Writer::EmitPhysicalRecord(RecordType t, const char* ptr, size_t n) {
return s;
}

}
}
} // namespace log
} // namespace leveldb
4 changes: 2 additions & 2 deletions db/log_writer.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class Writer {
void operator=(const Writer&);
};

}
}
} // namespace log
} // namespace leveldb

#endif // STORAGE_LEVELDB_DB_LOG_WRITER_H_
2 changes: 1 addition & 1 deletion db/memtable.cc
Original file line number Diff line number Diff line change
Expand Up @@ -142,4 +142,4 @@ bool MemTable::Get(const LookupKey& key, std::string* value, Status* s) {
return false;
}

}
} // namespace leveldb
2 changes: 1 addition & 1 deletion db/memtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,6 @@ class MemTable {
void operator=(const MemTable&);
};

}
} // namespace leveldb

#endif // STORAGE_LEVELDB_DB_MEMTABLE_H_
4 changes: 2 additions & 2 deletions db/repair.cc
Original file line number Diff line number Diff line change
Expand Up @@ -377,11 +377,11 @@ class Repairer {
fname.c_str(), s.ToString().c_str());
}
};
}
} // namespace

Status RepairDB(const std::string& dbname, const Options& options) {
Repairer repairer(dbname, options);
return repairer.Run();
}

}
} // namespace leveldb
2 changes: 1 addition & 1 deletion db/skiplist.h
Original file line number Diff line number Diff line change
Expand Up @@ -375,4 +375,4 @@ bool SkipList<Key,Comparator>::Contains(const Key& key) const {
}
}

}
} // namespace leveldb
2 changes: 1 addition & 1 deletion db/skiplist_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ TEST(SkipTest, Concurrent3) { RunConcurrent(3); }
TEST(SkipTest, Concurrent4) { RunConcurrent(4); }
TEST(SkipTest, Concurrent5) { RunConcurrent(5); }

}
} // namespace leveldb

int main(int argc, char** argv) {
return leveldb::test::RunAllTests();
Expand Down
2 changes: 1 addition & 1 deletion db/snapshot.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,6 @@ class SnapshotList {
SnapshotImpl list_;
};

}
} // namespace leveldb

#endif // STORAGE_LEVELDB_DB_SNAPSHOT_H_
2 changes: 1 addition & 1 deletion db/table_cache.cc
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,4 @@ void TableCache::Evict(uint64_t file_number) {
cache_->Erase(Slice(buf, sizeof(buf)));
}

}
} // namespace leveldb
2 changes: 1 addition & 1 deletion db/table_cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,6 @@ class TableCache {
Cache* cache_;
};

}
} // namespace leveldb

#endif // STORAGE_LEVELDB_DB_TABLE_CACHE_H_
2 changes: 1 addition & 1 deletion db/version_edit.cc
Original file line number Diff line number Diff line change
Expand Up @@ -263,4 +263,4 @@ std::string VersionEdit::DebugString() const {
return r;
}

}
} // namespace leveldb
Loading

0 comments on commit 36a5f8e

Please sign in to comment.