Merge branch 'master' into performance

Conflicts:
	db/db_impl.cc
	db/version_set.cc
	util/options.cc
main
Dhruba Borthakur 12 years ago
commit 8143062edd
  1. 2
      Makefile
  2. 4
      db/corruption_test.cc
  3. 19
      db/db_bench.cc
  4. 27
      db/db_impl.cc
  5. 4
      db/db_impl.h
  6. 45
      db/db_test.cc
  7. 4
      db/dbformat_test.cc
  8. 16
      db/filename_test.cc
  9. 4
      db/log_reader.cc
  10. 28
      db/log_test.cc
  11. 12
      db/skiplist_test.cc
  12. 86
      db/version_set.cc
  13. 10
      db/version_set.h
  14. 2
      db/version_set_test.cc
  15. 3
      db/write_batch_test.cc
  16. 16
      helpers/memenv/memenv_test.cc
  17. 2
      table/filter_block_test.cc
  18. 1
      table/table.cc
  19. 18
      table/table_test.cc
  20. 21
      tools/db_stress.cc
  21. 2
      tools/sst_dump.cc
  22. 8
      util/arena_test.cc
  23. 9
      util/auto_split_logger.h
  24. 2
      util/bloom.cc
  25. 2
      util/bloom_test.cc
  26. 2
      util/cache.cc
  27. 16
      util/cache_test.cc
  28. 2
      util/coding.cc
  29. 12
      util/coding_test.cc
  30. 8
      util/crc32c_test.cc
  31. 2
      util/env_test.cc
  32. 21
      util/ldb_cmd.cc
  33. 2
      util/ldb_cmd.h
  34. 2
      util/logging.cc
  35. 14
      util/options.cc
  36. 2
      util/testharness.cc
  37. 2
      util/testutil.cc

@ -11,7 +11,7 @@ INSTALL_PATH ?= $(CURDIR)
# OPT ?= -O2 -DNDEBUG # (A) Production use (optimized mode) # OPT ?= -O2 -DNDEBUG # (A) Production use (optimized mode)
# OPT ?= -g2 # (B) Debug mode, w/ full line-level debugging symbols # OPT ?= -g2 # (B) Debug mode, w/ full line-level debugging symbols
OPT ?= -O2 -g2 -DNDEBUG # (C) Profiling mode: opt, but w/debugging symbols OPT ?= -O2 -g2 -DNDEBUG -Wall # (C) Profiling mode: opt, but w/debugging symbols
#----------------------------------------------- #-----------------------------------------------
# detect what platform we're building on # detect what platform we're building on

@ -82,7 +82,7 @@ class CorruptionTest {
} }
void Check(int min_expected, int max_expected) { void Check(int min_expected, int max_expected) {
int next_expected = 0; unsigned int next_expected = 0;
int missed = 0; int missed = 0;
int bad_keys = 0; int bad_keys = 0;
int bad_values = 0; int bad_values = 0;
@ -123,7 +123,7 @@ class CorruptionTest {
FileType type; FileType type;
std::string fname; std::string fname;
int picked_number = -1; int picked_number = -1;
for (int i = 0; i < filenames.size(); i++) { for (unsigned int i = 0; i < filenames.size(); i++) {
if (ParseFileName(filenames[i], &number, &type) && if (ParseFileName(filenames[i], &number, &type) &&
type == filetype && type == filetype &&
int(number) > picked_number) { // Pick latest file int(number) > picked_number) { // Pick latest file

@ -149,7 +149,7 @@ static bool FLAGS_use_fsync = false;
static bool FLAGS_disable_wal = false; static bool FLAGS_disable_wal = false;
// The total number of levels // The total number of levels
static int FLAGS_num_levels = 7; static unsigned int FLAGS_num_levels = 7;
// Target level-0 file size for compaction // Target level-0 file size for compaction
static int FLAGS_target_file_size_base = 2 * 1048576; static int FLAGS_target_file_size_base = 2 * 1048576;
@ -191,7 +191,7 @@ static enum leveldb::CompressionType FLAGS_compression_type =
// Allows compression for levels 0 and 1 to be disabled when // Allows compression for levels 0 and 1 to be disabled when
// other levels are compressed // other levels are compressed
static int FLAGS_min_level_to_compress = -1; static unsigned int FLAGS_min_level_to_compress = -1;
static int FLAGS_table_cache_numshardbits = 4; static int FLAGS_table_cache_numshardbits = 4;
@ -218,13 +218,11 @@ extern bool useMmapWrite;
namespace leveldb { namespace leveldb {
namespace {
// Helper for quickly generating random data. // Helper for quickly generating random data.
class RandomGenerator { class RandomGenerator {
private: private:
std::string data_; std::string data_;
int pos_; unsigned int pos_;
public: public:
RandomGenerator() { RandomGenerator() {
@ -252,11 +250,11 @@ class RandomGenerator {
} }
}; };
static Slice TrimSpace(Slice s) { static Slice TrimSpace(Slice s) {
int start = 0; unsigned int start = 0;
while (start < s.size() && isspace(s[start])) { while (start < s.size() && isspace(s[start])) {
start++; start++;
} }
int limit = s.size(); unsigned int limit = s.size();
while (limit > start && isspace(s[limit-1])) { while (limit > start && isspace(s[limit-1])) {
limit--; limit--;
} }
@ -446,8 +444,6 @@ struct ThreadState {
} }
}; };
} // namespace
class Benchmark { class Benchmark {
private: private:
Cache* cache_; Cache* cache_;
@ -534,6 +530,9 @@ class Benchmark {
strlen(text), &compressed); strlen(text), &compressed);
name = "BZip2"; name = "BZip2";
break; break;
case kNoCompression:
assert(false); // cannot happen
break;
} }
if (!result) { if (!result) {
@ -611,7 +610,7 @@ class Benchmark {
heap_counter_(0) { heap_counter_(0) {
std::vector<std::string> files; std::vector<std::string> files;
FLAGS_env->GetChildren(FLAGS_db, &files); FLAGS_env->GetChildren(FLAGS_db, &files);
for (int i = 0; i < files.size(); i++) { for (unsigned int i = 0; i < files.size(); i++) {
if (Slice(files[i]).starts_with("heap-")) { if (Slice(files[i]).starts_with("heap-")) {
FLAGS_env->DeleteFile(std::string(FLAGS_db) + "/" + files[i]); FLAGS_env->DeleteFile(std::string(FLAGS_db) + "/" + files[i]);
} }

@ -160,7 +160,7 @@ Options SanitizeOptions(const std::string& dbname,
} }
if (src.compression_per_level != NULL) { if (src.compression_per_level != NULL) {
result.compression_per_level = new CompressionType[src.num_levels]; result.compression_per_level = new CompressionType[src.num_levels];
for (unsigned int i = 0; i < src.num_levels; i++) { for (int i = 0; i < src.num_levels; i++) {
result.compression_per_level[i] = src.compression_per_level[i]; result.compression_per_level[i] = src.compression_per_level[i];
} }
} }
@ -191,10 +191,11 @@ DBImpl::DBImpl(const Options& options, const std::string& dbname)
disable_delete_obsolete_files_(false), disable_delete_obsolete_files_(false),
delete_obsolete_files_last_run_(0), delete_obsolete_files_last_run_(0),
stall_level0_slowdown_(0), stall_level0_slowdown_(0),
stall_leveln_slowdown_(0),
stall_memtable_compaction_(0), stall_memtable_compaction_(0),
stall_level0_num_files_(0), stall_level0_num_files_(0),
stall_leveln_slowdown_(0),
started_at_(options.env->NowMicros()), started_at_(options.env->NowMicros()),
flush_on_destroy_(false),
delayed_writes_(0) { delayed_writes_(0) {
mem_->Ref(); mem_->Ref();
@ -227,7 +228,10 @@ DBImpl::DBImpl(const Options& options, const std::string& dbname)
DBImpl::~DBImpl() { DBImpl::~DBImpl() {
// Wait for background work to finish // Wait for background work to finish
mutex_.Lock(); if (flush_on_destroy_) {
FlushMemTable(FlushOptions());
}
mutex_.Lock();
shutting_down_.Release_Store(this); // Any non-NULL value is ok shutting_down_.Release_Store(this); // Any non-NULL value is ok
while (bg_compaction_scheduled_ || bg_logstats_scheduled_) { while (bg_compaction_scheduled_ || bg_logstats_scheduled_) {
bg_cv_.Wait(); bg_cv_.Wait();
@ -316,7 +320,7 @@ void DBImpl::FindObsoleteFiles(DeletionState& deletion_state) {
// delete_obsolete_files_period_micros. // delete_obsolete_files_period_micros.
if (options_.delete_obsolete_files_period_micros != 0) { if (options_.delete_obsolete_files_period_micros != 0) {
const uint64_t now_micros = env_->NowMicros(); const uint64_t now_micros = env_->NowMicros();
if (delete_obsolete_files_last_run_ + if (delete_obsolete_files_last_run_ +
options_.delete_obsolete_files_period_micros > now_micros) { options_.delete_obsolete_files_period_micros > now_micros) {
return; return;
} }
@ -422,7 +426,6 @@ void DBImpl::DeleteObsoleteFiles() {
std::set<uint64_t> live; std::set<uint64_t> live;
std::vector<std::string> allfiles; std::vector<std::string> allfiles;
std::vector<uint64_t> files_to_evict; std::vector<uint64_t> files_to_evict;
uint64_t filenumber, lognumber, prevlognumber;
FindObsoleteFiles(deletion_state); FindObsoleteFiles(deletion_state);
PurgeObsoleteFiles(deletion_state); PurgeObsoleteFiles(deletion_state);
EvictObsoleteFiles(deletion_state); EvictObsoleteFiles(deletion_state);
@ -1084,7 +1087,7 @@ void DBImpl::AllocateCompactionOutputFileNumbers(CompactionState* compact) {
assert(compact != NULL); assert(compact != NULL);
assert(compact->builder == NULL); assert(compact->builder == NULL);
int filesNeeded = compact->compaction->num_input_files(1); int filesNeeded = compact->compaction->num_input_files(1);
for (unsigned i = 0; i < filesNeeded; i++) { for (int i = 0; i < filesNeeded; i++) {
uint64_t file_number = versions_->NewFileNumber(); uint64_t file_number = versions_->NewFileNumber();
pending_outputs_.insert(file_number); pending_outputs_.insert(file_number);
compact->allocated_file_numbers.push_back(file_number); compact->allocated_file_numbers.push_back(file_number);
@ -1324,8 +1327,8 @@ Status DBImpl::DoCompactionWork(CompactionState* compact) {
ikey.sequence < compact->smallest_snapshot) { ikey.sequence < compact->smallest_snapshot) {
// If the user has specified a compaction filter, then invoke // If the user has specified a compaction filter, then invoke
// it. If this key is not visible via any snapshot and the // it. If this key is not visible via any snapshot and the
// return value of the compaction filter is true and then // return value of the compaction filter is true and then
// drop this key from the output. // drop this key from the output.
drop = options_.CompactionFilter(compact->compaction->level(), drop = options_.CompactionFilter(compact->compaction->level(),
ikey.user_key, value, &compaction_filter_value); ikey.user_key, value, &compaction_filter_value);
@ -1605,6 +1608,10 @@ Status DBImpl::Write(const WriteOptions& options, WriteBatch* my_batch) {
// into mem_. // into mem_.
{ {
mutex_.Unlock(); mutex_.Unlock();
if (options.disableWAL) {
flush_on_destroy_ = true;
}
if (!options.disableWAL) { if (!options.disableWAL) {
status = log_->AddRecord(WriteBatchInternal::Contents(updates)); status = log_->AddRecord(WriteBatchInternal::Contents(updates));
if (status.ok() && options.sync) { if (status.ok() && options.sync) {
@ -1731,7 +1738,7 @@ Status DBImpl::MakeRoomForWrite(bool force) {
allow_delay = false; // Do not delay a single write more than once allow_delay = false; // Do not delay a single write more than once
//Log(options_.info_log, //Log(options_.info_log,
// "delaying write %llu usecs for level0_slowdown_writes_trigger\n", // "delaying write %llu usecs for level0_slowdown_writes_trigger\n",
// delayed); // (long long unsigned int)delayed);
mutex_.Lock(); mutex_.Lock();
delayed_writes_++; delayed_writes_++;
} else if (!force && } else if (!force &&
@ -1770,7 +1777,7 @@ Status DBImpl::MakeRoomForWrite(bool force) {
allow_delay = false; // Do not delay a single write more than once allow_delay = false; // Do not delay a single write more than once
Log(options_.info_log, Log(options_.info_log,
"delaying write %llu usecs for rate limits with max score %.2f\n", "delaying write %llu usecs for rate limits with max score %.2f\n",
delayed, score); (long long unsigned int)delayed, score);
mutex_.Lock(); mutex_.Lock();
} else { } else {
// Attempt to switch to a new memtable and trigger compaction of old // Attempt to switch to a new memtable and trigger compaction of old

@ -52,7 +52,7 @@ class DBImpl : public DB {
virtual Status Flush(const FlushOptions& options); virtual Status Flush(const FlushOptions& options);
virtual Status DisableFileDeletions(); virtual Status DisableFileDeletions();
virtual Status EnableFileDeletions(); virtual Status EnableFileDeletions();
virtual Status GetLiveFiles(std::vector<std::string>&, virtual Status GetLiveFiles(std::vector<std::string>&,
uint64_t* manifest_file_size); uint64_t* manifest_file_size);
// Extra methods (for testing) that are not in the public DB interface // Extra methods (for testing) that are not in the public DB interface
@ -233,6 +233,8 @@ class DBImpl : public DB {
// Time at which this instance was started. // Time at which this instance was started.
const uint64_t started_at_; const uint64_t started_at_;
bool flush_on_destroy_; // Used when disableWAL is true.
// Per level compaction stats. stats_[level] stores the stats for // Per level compaction stats. stats_[level] stores the stats for
// compactions that produced data for the specified "level". // compactions that produced data for the specified "level".
struct CompactionStats { struct CompactionStats {

@ -44,7 +44,7 @@ static std::string RandomString(Random* rnd, int len) {
return r; return r;
} }
namespace { namespace anon {
class AtomicCounter { class AtomicCounter {
private: private:
port::Mutex mu_; port::Mutex mu_;
@ -79,9 +79,9 @@ class SpecialEnv : public EnvWrapper {
port::AtomicPointer non_writable_; port::AtomicPointer non_writable_;
bool count_random_reads_; bool count_random_reads_;
AtomicCounter random_read_counter_; anon::AtomicCounter random_read_counter_;
AtomicCounter sleep_counter_; anon::AtomicCounter sleep_counter_;
explicit SpecialEnv(Env* base) : EnvWrapper(base) { explicit SpecialEnv(Env* base) : EnvWrapper(base) {
delay_sstable_sync_.Release_Store(NULL); delay_sstable_sync_.Release_Store(NULL);
@ -137,9 +137,9 @@ class SpecialEnv : public EnvWrapper {
class CountingFile : public RandomAccessFile { class CountingFile : public RandomAccessFile {
private: private:
RandomAccessFile* target_; RandomAccessFile* target_;
AtomicCounter* counter_; anon::AtomicCounter* counter_;
public: public:
CountingFile(RandomAccessFile* target, AtomicCounter* counter) CountingFile(RandomAccessFile* target, anon::AtomicCounter* counter)
: target_(target), counter_(counter) { : target_(target), counter_(counter) {
} }
virtual ~CountingFile() { delete target_; } virtual ~CountingFile() { delete target_; }
@ -310,7 +310,7 @@ class DBTest {
} }
// Check reverse iteration results are the reverse of forward results // Check reverse iteration results are the reverse of forward results
int matched = 0; unsigned int matched = 0;
for (iter->SeekToLast(); iter->Valid(); iter->Prev()) { for (iter->SeekToLast(); iter->Valid(); iter->Prev()) {
ASSERT_LT(matched, forward.size()); ASSERT_LT(matched, forward.size());
ASSERT_EQ(IterStatus(iter), forward[forward.size() - matched - 1]); ASSERT_EQ(IterStatus(iter), forward[forward.size() - matched - 1]);
@ -858,8 +858,8 @@ TEST(DBTest, WAL) {
ASSERT_OK(dbfull()->Put(writeOpt, "bar", "v1")); ASSERT_OK(dbfull()->Put(writeOpt, "bar", "v1"));
Reopen(); Reopen();
ASSERT_EQ("NOT_FOUND", Get("foo")); ASSERT_EQ("v1", Get("foo"));
ASSERT_EQ("NOT_FOUND", Get("bar")); ASSERT_EQ("v1", Get("bar"));
writeOpt.disableWAL = false; writeOpt.disableWAL = false;
ASSERT_OK(dbfull()->Put(writeOpt, "bar", "v2")); ASSERT_OK(dbfull()->Put(writeOpt, "bar", "v2"));
@ -867,10 +867,9 @@ TEST(DBTest, WAL) {
ASSERT_OK(dbfull()->Put(writeOpt, "foo", "v2")); ASSERT_OK(dbfull()->Put(writeOpt, "foo", "v2"));
Reopen(); Reopen();
// We garantee the 'bar' will be there // Both value's should be present.
// because its put has WAL enabled.
// But 'foo' may or may not be there.
ASSERT_EQ("v2", Get("bar")); ASSERT_EQ("v2", Get("bar"));
ASSERT_EQ("v2", Get("foo"));
writeOpt.disableWAL = true; writeOpt.disableWAL = true;
ASSERT_OK(dbfull()->Put(writeOpt, "bar", "v3")); ASSERT_OK(dbfull()->Put(writeOpt, "bar", "v3"));
@ -878,9 +877,9 @@ TEST(DBTest, WAL) {
ASSERT_OK(dbfull()->Put(writeOpt, "foo", "v3")); ASSERT_OK(dbfull()->Put(writeOpt, "foo", "v3"));
Reopen(); Reopen();
// 'foo' should be there because its put // again both values should be present.
// has WAL enabled.
ASSERT_EQ("v3", Get("foo")); ASSERT_EQ("v3", Get("foo"));
ASSERT_EQ("v3", Get("bar"));
} }
TEST(DBTest, CheckLock) { TEST(DBTest, CheckLock) {
@ -895,13 +894,13 @@ TEST(DBTest, FLUSH) {
WriteOptions writeOpt = WriteOptions(); WriteOptions writeOpt = WriteOptions();
writeOpt.disableWAL = true; writeOpt.disableWAL = true;
ASSERT_OK(dbfull()->Put(writeOpt, "foo", "v1")); ASSERT_OK(dbfull()->Put(writeOpt, "foo", "v1"));
// this will not flush the last 2 writes // this will now also flush the last 2 writes
dbfull()->Flush(FlushOptions()); dbfull()->Flush(FlushOptions());
ASSERT_OK(dbfull()->Put(writeOpt, "bar", "v1")); ASSERT_OK(dbfull()->Put(writeOpt, "bar", "v1"));
Reopen(); Reopen();
ASSERT_EQ("v1", Get("foo")); ASSERT_EQ("v1", Get("foo"));
ASSERT_EQ("NOT_FOUND", Get("bar")); ASSERT_EQ("v1", Get("bar"));
writeOpt.disableWAL = true; writeOpt.disableWAL = true;
ASSERT_OK(dbfull()->Put(writeOpt, "bar", "v2")); ASSERT_OK(dbfull()->Put(writeOpt, "bar", "v2"));
@ -1201,12 +1200,12 @@ static int cfilter_count;
static std::string NEW_VALUE = "NewValue"; static std::string NEW_VALUE = "NewValue";
static bool keep_filter(int level, const Slice& key, static bool keep_filter(int level, const Slice& key,
const Slice& value, Slice** new_value) { const Slice& value, Slice** new_value) {
cfilter_count++; cfilter_count++;
return false; return false;
} }
static bool delete_filter(int level, const Slice& key, static bool delete_filter(int level, const Slice& key,
const Slice& value, Slice** new_value) { const Slice& value, Slice** new_value) {
cfilter_count++; cfilter_count++;
return true; return true;
} }
static bool change_filter(int level, const Slice& key, static bool change_filter(int level, const Slice& key,
@ -1223,8 +1222,8 @@ TEST(DBTest, CompactionFilter) {
options.CompactionFilter = keep_filter; options.CompactionFilter = keep_filter;
Reopen(&options); Reopen(&options);
// Write 100K+1 keys, these are written to a few files // Write 100K+1 keys, these are written to a few files
// in L0. We do this so that the current snapshot points // in L0. We do this so that the current snapshot points
// to the 100001 key.The compaction filter is not invoked // to the 100001 key.The compaction filter is not invoked
// on keys that are visible via a snapshot because we // on keys that are visible via a snapshot because we
// anyways cannot delete it. // anyways cannot delete it.
@ -1324,8 +1323,8 @@ TEST(DBTest, CompactionFilterWithValueChange) {
options.CompactionFilter = change_filter; options.CompactionFilter = change_filter;
Reopen(&options); Reopen(&options);
// Write 100K+1 keys, these are written to a few files // Write 100K+1 keys, these are written to a few files
// in L0. We do this so that the current snapshot points // in L0. We do this so that the current snapshot points
// to the 100001 key.The compaction filter is not invoked // to the 100001 key.The compaction filter is not invoked
// on keys that are visible via a snapshot because we // on keys that are visible via a snapshot because we
// anyways cannot delete it. // anyways cannot delete it.
@ -2028,7 +2027,7 @@ TEST(DBTest, SnapshotFiles) {
dbfull()->GetLiveFiles(files, &manifest_size); dbfull()->GetLiveFiles(files, &manifest_size);
// CURRENT, MANIFEST, *.sst files // CURRENT, MANIFEST, *.sst files
ASSERT_EQ(files.size(), 3); ASSERT_EQ(files.size(), 3U);
uint64_t number = 0; uint64_t number = 0;
FileType type; FileType type;
@ -2251,7 +2250,7 @@ static void MTThreadBody(void* arg) {
ASSERT_EQ(k, key); ASSERT_EQ(k, key);
ASSERT_GE(w, 0); ASSERT_GE(w, 0);
ASSERT_LT(w, kNumThreads); ASSERT_LT(w, kNumThreads);
ASSERT_LE(c, reinterpret_cast<uintptr_t>( ASSERT_LE((unsigned int)c, reinterpret_cast<uintptr_t>(
t->state->counter[w].Acquire_Load())); t->state->counter[w].Acquire_Load()));
} }
} }

@ -54,8 +54,8 @@ TEST(FormatTest, InternalKey_EncodeDecode) {
(1ull << 16) - 1, 1ull << 16, (1ull << 16) + 1, (1ull << 16) - 1, 1ull << 16, (1ull << 16) + 1,
(1ull << 32) - 1, 1ull << 32, (1ull << 32) + 1 (1ull << 32) - 1, 1ull << 32, (1ull << 32) + 1
}; };
for (int k = 0; k < sizeof(keys) / sizeof(keys[0]); k++) { for (unsigned int k = 0; k < sizeof(keys) / sizeof(keys[0]); k++) {
for (int s = 0; s < sizeof(seq) / sizeof(seq[0]); s++) { for (unsigned int s = 0; s < sizeof(seq) / sizeof(seq[0]); s++) {
TestKey(keys[k], seq[s], kTypeValue); TestKey(keys[k], seq[s], kTypeValue);
TestKey("hello", 1, kTypeDeletion); TestKey("hello", 1, kTypeDeletion);
} }

@ -35,7 +35,7 @@ TEST(FileNameTest, Parse) {
{ "LOG.old", 0, kInfoLogFile }, { "LOG.old", 0, kInfoLogFile },
{ "18446744073709551615.log", 18446744073709551615ull, kLogFile }, { "18446744073709551615.log", 18446744073709551615ull, kLogFile },
}; };
for (int i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) { for (unsigned int i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) {
std::string f = cases[i].fname; std::string f = cases[i].fname;
ASSERT_TRUE(ParseFileName(f, &number, &type)) << f; ASSERT_TRUE(ParseFileName(f, &number, &type)) << f;
ASSERT_EQ(cases[i].type, type) << f; ASSERT_EQ(cases[i].type, type) << f;
@ -67,7 +67,7 @@ TEST(FileNameTest, Parse) {
"100.", "100.",
"100.lop" "100.lop"
}; };
for (int i = 0; i < sizeof(errors) / sizeof(errors[0]); i++) { for (unsigned int i = 0; i < sizeof(errors) / sizeof(errors[0]); i++) {
std::string f = errors[i]; std::string f = errors[i];
ASSERT_TRUE(!ParseFileName(f, &number, &type)) << f; ASSERT_TRUE(!ParseFileName(f, &number, &type)) << f;
}; };
@ -81,37 +81,37 @@ TEST(FileNameTest, Construction) {
fname = CurrentFileName("foo"); fname = CurrentFileName("foo");
ASSERT_EQ("foo/", std::string(fname.data(), 4)); ASSERT_EQ("foo/", std::string(fname.data(), 4));
ASSERT_TRUE(ParseFileName(fname.c_str() + 4, &number, &type)); ASSERT_TRUE(ParseFileName(fname.c_str() + 4, &number, &type));
ASSERT_EQ(0, number); ASSERT_EQ(0U, number);
ASSERT_EQ(kCurrentFile, type); ASSERT_EQ(kCurrentFile, type);
fname = LockFileName("foo"); fname = LockFileName("foo");
ASSERT_EQ("foo/", std::string(fname.data(), 4)); ASSERT_EQ("foo/", std::string(fname.data(), 4));
ASSERT_TRUE(ParseFileName(fname.c_str() + 4, &number, &type)); ASSERT_TRUE(ParseFileName(fname.c_str() + 4, &number, &type));
ASSERT_EQ(0, number); ASSERT_EQ(0U, number);
ASSERT_EQ(kDBLockFile, type); ASSERT_EQ(kDBLockFile, type);
fname = LogFileName("foo", 192); fname = LogFileName("foo", 192);
ASSERT_EQ("foo/", std::string(fname.data(), 4)); ASSERT_EQ("foo/", std::string(fname.data(), 4));
ASSERT_TRUE(ParseFileName(fname.c_str() + 4, &number, &type)); ASSERT_TRUE(ParseFileName(fname.c_str() + 4, &number, &type));
ASSERT_EQ(192, number); ASSERT_EQ(192U, number);
ASSERT_EQ(kLogFile, type); ASSERT_EQ(kLogFile, type);
fname = TableFileName("bar", 200); fname = TableFileName("bar", 200);
ASSERT_EQ("bar/", std::string(fname.data(), 4)); ASSERT_EQ("bar/", std::string(fname.data(), 4));
ASSERT_TRUE(ParseFileName(fname.c_str() + 4, &number, &type)); ASSERT_TRUE(ParseFileName(fname.c_str() + 4, &number, &type));
ASSERT_EQ(200, number); ASSERT_EQ(200U, number);
ASSERT_EQ(kTableFile, type); ASSERT_EQ(kTableFile, type);
fname = DescriptorFileName("bar", 100); fname = DescriptorFileName("bar", 100);
ASSERT_EQ("bar/", std::string(fname.data(), 4)); ASSERT_EQ("bar/", std::string(fname.data(), 4));
ASSERT_TRUE(ParseFileName(fname.c_str() + 4, &number, &type)); ASSERT_TRUE(ParseFileName(fname.c_str() + 4, &number, &type));
ASSERT_EQ(100, number); ASSERT_EQ(100U, number);
ASSERT_EQ(kDescriptorFile, type); ASSERT_EQ(kDescriptorFile, type);
fname = TempFileName("tmp", 999); fname = TempFileName("tmp", 999);
ASSERT_EQ("tmp/", std::string(fname.data(), 4)); ASSERT_EQ("tmp/", std::string(fname.data(), 4));
ASSERT_TRUE(ParseFileName(fname.c_str() + 4, &number, &type)); ASSERT_TRUE(ParseFileName(fname.c_str() + 4, &number, &type));
ASSERT_EQ(999, number); ASSERT_EQ(999U, number);
ASSERT_EQ(kTempFile, type); ASSERT_EQ(kTempFile, type);
} }

@ -178,7 +178,7 @@ void Reader::ReportDrop(size_t bytes, const Status& reason) {
unsigned int Reader::ReadPhysicalRecord(Slice* result) { unsigned int Reader::ReadPhysicalRecord(Slice* result) {
while (true) { while (true) {
if (buffer_.size() < kHeaderSize) { if (buffer_.size() < (size_t)kHeaderSize) {
if (!eof_) { if (!eof_) {
// Last read was a full read, so this is a trailer to skip // Last read was a full read, so this is a trailer to skip
buffer_.clear(); buffer_.clear();
@ -189,7 +189,7 @@ unsigned int Reader::ReadPhysicalRecord(Slice* result) {
ReportDrop(kBlockSize, status); ReportDrop(kBlockSize, status);
eof_ = true; eof_ = true;
return kEof; return kEof;
} else if (buffer_.size() < kBlockSize) { } else if (buffer_.size() < (size_t)kBlockSize) {
eof_ = true; eof_ = true;
} }
continue; continue;

@ -276,7 +276,7 @@ TEST(LogTest, MarginalTrailer) {
// Make a trailer that is exactly the same length as an empty record. // Make a trailer that is exactly the same length as an empty record.
const int n = kBlockSize - 2*kHeaderSize; const int n = kBlockSize - 2*kHeaderSize;
Write(BigString("foo", n)); Write(BigString("foo", n));
ASSERT_EQ(kBlockSize - kHeaderSize, WrittenBytes()); ASSERT_EQ((unsigned int)(kBlockSize - kHeaderSize), WrittenBytes());
Write(""); Write("");
Write("bar"); Write("bar");
ASSERT_EQ(BigString("foo", n), Read()); ASSERT_EQ(BigString("foo", n), Read());
@ -289,19 +289,19 @@ TEST(LogTest, MarginalTrailer2) {
// Make a trailer that is exactly the same length as an empty record. // Make a trailer that is exactly the same length as an empty record.
const int n = kBlockSize - 2*kHeaderSize; const int n = kBlockSize - 2*kHeaderSize;
Write(BigString("foo", n)); Write(BigString("foo", n));
ASSERT_EQ(kBlockSize - kHeaderSize, WrittenBytes()); ASSERT_EQ((unsigned int)(kBlockSize - kHeaderSize), WrittenBytes());
Write("bar"); Write("bar");
ASSERT_EQ(BigString("foo", n), Read()); ASSERT_EQ(BigString("foo", n), Read());
ASSERT_EQ("bar", Read()); ASSERT_EQ("bar", Read());
ASSERT_EQ("EOF", Read()); ASSERT_EQ("EOF", Read());
ASSERT_EQ(0, DroppedBytes()); ASSERT_EQ(0U, DroppedBytes());
ASSERT_EQ("", ReportMessage()); ASSERT_EQ("", ReportMessage());
} }
TEST(LogTest, ShortTrailer) { TEST(LogTest, ShortTrailer) {
const int n = kBlockSize - 2*kHeaderSize + 4; const int n = kBlockSize - 2*kHeaderSize + 4;
Write(BigString("foo", n)); Write(BigString("foo", n));
ASSERT_EQ(kBlockSize - kHeaderSize + 4, WrittenBytes()); ASSERT_EQ((unsigned int)(kBlockSize - kHeaderSize + 4), WrittenBytes());
Write(""); Write("");
Write("bar"); Write("bar");
ASSERT_EQ(BigString("foo", n), Read()); ASSERT_EQ(BigString("foo", n), Read());
@ -313,7 +313,7 @@ TEST(LogTest, ShortTrailer) {
TEST(LogTest, AlignedEof) { TEST(LogTest, AlignedEof) {
const int n = kBlockSize - 2*kHeaderSize + 4; const int n = kBlockSize - 2*kHeaderSize + 4;
Write(BigString("foo", n)); Write(BigString("foo", n));
ASSERT_EQ(kBlockSize - kHeaderSize + 4, WrittenBytes()); ASSERT_EQ((unsigned int)(kBlockSize - kHeaderSize + 4), WrittenBytes());
ASSERT_EQ(BigString("foo", n), Read()); ASSERT_EQ(BigString("foo", n), Read());
ASSERT_EQ("EOF", Read()); ASSERT_EQ("EOF", Read());
} }
@ -337,7 +337,7 @@ TEST(LogTest, ReadError) {
Write("foo"); Write("foo");
ForceError(); ForceError();
ASSERT_EQ("EOF", Read()); ASSERT_EQ("EOF", Read());
ASSERT_EQ(kBlockSize, DroppedBytes()); ASSERT_EQ((unsigned int)kBlockSize, DroppedBytes());
ASSERT_EQ("OK", MatchError("read error")); ASSERT_EQ("OK", MatchError("read error"));
} }
@ -347,7 +347,7 @@ TEST(LogTest, BadRecordType) {
IncrementByte(6, 100); IncrementByte(6, 100);
FixChecksum(0, 3); FixChecksum(0, 3);
ASSERT_EQ("EOF", Read()); ASSERT_EQ("EOF", Read());
ASSERT_EQ(3, DroppedBytes()); ASSERT_EQ(3U, DroppedBytes());
ASSERT_EQ("OK", MatchError("unknown record type")); ASSERT_EQ("OK", MatchError("unknown record type"));
} }
@ -355,7 +355,7 @@ TEST(LogTest, TruncatedTrailingRecord) {
Write("foo"); Write("foo");
ShrinkSize(4); // Drop all payload as well as a header byte ShrinkSize(4); // Drop all payload as well as a header byte
ASSERT_EQ("EOF", Read()); ASSERT_EQ("EOF", Read());
ASSERT_EQ(kHeaderSize - 1, DroppedBytes()); ASSERT_EQ((unsigned int)(kHeaderSize - 1), DroppedBytes());
ASSERT_EQ("OK", MatchError("truncated record at end of file")); ASSERT_EQ("OK", MatchError("truncated record at end of file"));
} }
@ -363,7 +363,7 @@ TEST(LogTest, BadLength) {
Write("foo"); Write("foo");
ShrinkSize(1); ShrinkSize(1);
ASSERT_EQ("EOF", Read()); ASSERT_EQ("EOF", Read());
ASSERT_EQ(kHeaderSize + 2, DroppedBytes()); ASSERT_EQ((unsigned int)(kHeaderSize + 2), DroppedBytes());
ASSERT_EQ("OK", MatchError("bad record length")); ASSERT_EQ("OK", MatchError("bad record length"));
} }
@ -371,7 +371,7 @@ TEST(LogTest, ChecksumMismatch) {
Write("foo"); Write("foo");
IncrementByte(0, 10); IncrementByte(0, 10);
ASSERT_EQ("EOF", Read()); ASSERT_EQ("EOF", Read());
ASSERT_EQ(10, DroppedBytes()); ASSERT_EQ(10U, DroppedBytes());
ASSERT_EQ("OK", MatchError("checksum mismatch")); ASSERT_EQ("OK", MatchError("checksum mismatch"));
} }
@ -380,7 +380,7 @@ TEST(LogTest, UnexpectedMiddleType) {
SetByte(6, kMiddleType); SetByte(6, kMiddleType);
FixChecksum(0, 3); FixChecksum(0, 3);
ASSERT_EQ("EOF", Read()); ASSERT_EQ("EOF", Read());
ASSERT_EQ(3, DroppedBytes()); ASSERT_EQ(3U, DroppedBytes());
ASSERT_EQ("OK", MatchError("missing start")); ASSERT_EQ("OK", MatchError("missing start"));
} }
@ -389,7 +389,7 @@ TEST(LogTest, UnexpectedLastType) {
SetByte(6, kLastType); SetByte(6, kLastType);
FixChecksum(0, 3); FixChecksum(0, 3);
ASSERT_EQ("EOF", Read()); ASSERT_EQ("EOF", Read());
ASSERT_EQ(3, DroppedBytes()); ASSERT_EQ(3U, DroppedBytes());
ASSERT_EQ("OK", MatchError("missing start")); ASSERT_EQ("OK", MatchError("missing start"));
} }
@ -400,7 +400,7 @@ TEST(LogTest, UnexpectedFullType) {
FixChecksum(0, 3); FixChecksum(0, 3);
ASSERT_EQ("bar", Read()); ASSERT_EQ("bar", Read());
ASSERT_EQ("EOF", Read()); ASSERT_EQ("EOF", Read());
ASSERT_EQ(3, DroppedBytes()); ASSERT_EQ(3U, DroppedBytes());
ASSERT_EQ("OK", MatchError("partial record without end")); ASSERT_EQ("OK", MatchError("partial record without end"));
} }
@ -411,7 +411,7 @@ TEST(LogTest, UnexpectedFirstType) {
FixChecksum(0, 3); FixChecksum(0, 3);
ASSERT_EQ(BigString("bar", 100000), Read()); ASSERT_EQ(BigString("bar", 100000), Read());
ASSERT_EQ("EOF", Read()); ASSERT_EQ("EOF", Read());
ASSERT_EQ(3, DroppedBytes()); ASSERT_EQ(3U, DroppedBytes());
ASSERT_EQ("OK", MatchError("partial record without end")); ASSERT_EQ("OK", MatchError("partial record without end"));
} }

@ -61,9 +61,9 @@ TEST(SkipTest, InsertAndLookup) {
for (int i = 0; i < R; i++) { for (int i = 0; i < R; i++) {
if (list.Contains(i)) { if (list.Contains(i)) {
ASSERT_EQ(keys.count(i), 1); ASSERT_EQ(keys.count(i), 1U);
} else { } else {
ASSERT_EQ(keys.count(i), 0); ASSERT_EQ(keys.count(i), 0U);
} }
} }
@ -195,7 +195,7 @@ class ConcurrentTest {
} }
State() { State() {
for (int k = 0; k < K; k++) { for (unsigned int k = 0; k < K; k++) {
Set(k, 0); Set(k, 0);
} }
} }
@ -225,7 +225,7 @@ class ConcurrentTest {
void ReadStep(Random* rnd) { void ReadStep(Random* rnd) {
// Remember the initial committed state of the skiplist. // Remember the initial committed state of the skiplist.
State initial_state; State initial_state;
for (int k = 0; k < K; k++) { for (unsigned int k = 0; k < K; k++) {
initial_state.Set(k, current_.Get(k)); initial_state.Set(k, current_.Get(k));
} }
@ -249,8 +249,8 @@ class ConcurrentTest {
// Note that generation 0 is never inserted, so it is ok if // Note that generation 0 is never inserted, so it is ok if
// <*,0,*> is missing. // <*,0,*> is missing.
ASSERT_TRUE((gen(pos) == 0) || ASSERT_TRUE((gen(pos) == 0U) ||
(gen(pos) > initial_state.Get(key(pos))) (gen(pos) > (uint64_t)initial_state.Get(key(pos)))
) << "key: " << key(pos) ) << "key: " << key(pos)
<< "; gen: " << gen(pos) << "; gen: " << gen(pos)
<< "; initgen: " << "; initgen: "

@ -455,11 +455,16 @@ int Version::PickLevelForMemTableOutput(
} }
// Store in "*inputs" all files in "level" that overlap [begin,end] // Store in "*inputs" all files in "level" that overlap [begin,end]
// If hint_index is specified, then it points to a file in the
// overlapping range.
// The file_index returns a pointer to any file in an overlapping range.
void Version::GetOverlappingInputs( void Version::GetOverlappingInputs(
int level, int level,
const InternalKey* begin, const InternalKey* begin,
const InternalKey* end, const InternalKey* end,
std::vector<FileMetaData*>* inputs) { std::vector<FileMetaData*>* inputs,
int hint_index,
int* file_index) {
inputs->clear(); inputs->clear();
Slice user_begin, user_end; Slice user_begin, user_end;
if (begin != NULL) { if (begin != NULL) {
@ -470,7 +475,8 @@ void Version::GetOverlappingInputs(
} }
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,
hint_index, file_index);
return; return;
} }
for (size_t i = 0; i < files_[level].size(); ) { for (size_t i = 0; i < files_[level].size(); ) {
@ -495,6 +501,8 @@ void Version::GetOverlappingInputs(
inputs->clear(); inputs->clear();
i = 0; i = 0;
} }
} else if (file_index) {
*file_index = i;
} }
} }
} }
@ -508,14 +516,24 @@ void Version::GetOverlappingInputsBinarySearch(
int level, int level,
const Slice& user_begin, const Slice& user_begin,
const Slice& user_end, const Slice& user_end,
std::vector<FileMetaData*>* inputs) { std::vector<FileMetaData*>* inputs,
int hint_index,
int* file_index) {
assert(level > 0); assert(level > 0);
int min = 0; int min = 0;
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 = vset_->icmp_.user_comparator();
while (min <= max) {
// if the caller already knows the index of a file that has overlap,
// then we can skip the binary search.
if (hint_index != -1) {
mid = hint_index;
foundOverlap = true;
}
while (!foundOverlap && min <= max) {
mid = (min + max)/2; mid = (min + max)/2;
FileMetaData* f = files_[level][mid]; FileMetaData* f = files_[level][mid];
const Slice file_start = f->smallest.user_key(); const Slice file_start = f->smallest.user_key();
@ -534,6 +552,10 @@ void Version::GetOverlappingInputsBinarySearch(
if (!foundOverlap) { if (!foundOverlap) {
return; return;
} }
// returns the index where an overlap is found
if (file_index) {
*file_index = mid;
}
ExtendOverlappingInputs(level, user_begin, user_end, inputs, mid); ExtendOverlappingInputs(level, user_begin, user_end, inputs, mid);
} }
@ -548,13 +570,21 @@ void Version::ExtendOverlappingInputs(
std::vector<FileMetaData*>* inputs, std::vector<FileMetaData*>* inputs,
int midIndex) { int midIndex) {
// assert that the file at midIndex overlaps with the range
const Comparator* user_cmp = vset_->icmp_.user_comparator(); const Comparator* user_cmp = vset_->icmp_.user_comparator();
assert(midIndex < files_[level].size()); #ifndef NDEBUG
assert((user_cmp->Compare(files_[level][midIndex]->largest.user_key(), {
user_begin) >= 0) || // assert that the file at midIndex overlaps with the range
(user_cmp->Compare(files_[level][midIndex]->smallest.user_key(), assert(midIndex < files_[level].size());
user_end) <= 0)); FileMetaData* f = files_[level][midIndex];
const Slice fstart = f->smallest.user_key();
const Slice flimit = f->largest.user_key();
if (user_cmp->Compare(fstart, user_begin) >= 0) {
assert(user_cmp->Compare(fstart, user_end) <= 0);
} else {
assert(user_cmp->Compare(flimit, user_begin) >= 0);
}
}
#endif
// check backwards from 'mid' to lower indices // check backwards from 'mid' to lower indices
for (size_t i = midIndex; i < files_[level].size(); i--) { for (size_t i = midIndex; i < files_[level].size(); i--) {
@ -864,11 +894,11 @@ VersionSet::VersionSet(const std::string& dbname,
last_sequence_(0), last_sequence_(0),
log_number_(0), log_number_(0),
prev_log_number_(0), prev_log_number_(0),
num_levels_(options_->num_levels),
descriptor_file_(NULL), descriptor_file_(NULL),
descriptor_log_(NULL), descriptor_log_(NULL),
dummy_versions_(this), dummy_versions_(this),
current_(NULL), current_(NULL),
num_levels_(options_->num_levels),
compactions_in_progress_(options_->num_levels), compactions_in_progress_(options_->num_levels),
current_version_number_(0) { current_version_number_(0) {
compact_pointer_ = new std::string[options_->num_levels]; compact_pointer_ = new std::string[options_->num_levels];
@ -940,9 +970,8 @@ Status VersionSet::LogAndApply(VersionEdit* edit, port::Mutex* mu,
// process all requests in the queue // process all requests in the queue
ManifestWriter* last_writer = &w; ManifestWriter* last_writer = &w;
ManifestWriter* first = manifest_writers_.front();
assert(!manifest_writers_.empty()); assert(!manifest_writers_.empty());
assert(first == &w); assert(manifest_writers_.front() == &w);
std::deque<ManifestWriter*>::iterator iter = manifest_writers_.begin(); std::deque<ManifestWriter*>::iterator iter = manifest_writers_.begin();
for (; iter != manifest_writers_.end(); ++iter) { for (; iter != manifest_writers_.end(); ++iter) {
last_writer = *iter; last_writer = *iter;
@ -1014,7 +1043,7 @@ Status VersionSet::LogAndApply(VersionEdit* edit, port::Mutex* mu,
prev_log_number_ = edit->prev_log_number_; prev_log_number_ = edit->prev_log_number_;
} else { } else {
Log(options_->info_log, "Error in committing version %d", Log(options_->info_log, "Error in committing version %ld",
v->GetVersionNumber()); v->GetVersionNumber());
delete v; delete v;
if (!new_manifest_file.empty()) { if (!new_manifest_file.empty()) {
@ -1732,10 +1761,13 @@ 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
if (ParentFilesInCompaction(f, level)) { int parent_index = -1;
if (ParentFilesInCompaction(f, level, &parent_index)) {
continue; continue;
} }
c->inputs_[0].push_back(f); c->inputs_[0].push_back(f);
c->base_index_ = i;
c->parent_index_ = parent_index;
break; break;
} }
@ -1748,7 +1780,7 @@ Compaction* VersionSet::PickCompactionBySize(int level) {
Compaction* VersionSet::PickCompaction() { Compaction* VersionSet::PickCompaction() {
Compaction* c = NULL; Compaction* c = NULL;
int level; int level = -1;
// compute the compactions needed. It is better to do it here // compute the compactions needed. It is better to do it here
// and also in LogAndApply(), otherwise the values could be stale. // and also in LogAndApply(), otherwise the values could be stale.
@ -1795,7 +1827,8 @@ Compaction* VersionSet::PickCompaction() {
current_->GetOverlappingInputs(0, &smallest, &largest, &more); current_->GetOverlappingInputs(0, &smallest, &largest, &more);
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 && !ParentFilesInCompaction(f, level)) { if (!f->being_compacted &&
!ParentFilesInCompaction(f, level, &c->parent_index_)) {
c->inputs_[0].push_back(f); c->inputs_[0].push_back(f);
} }
} }
@ -1814,9 +1847,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::ParentFilesInCompaction(FileMetaData* f, int level,
int* parent_index) {
std::vector<FileMetaData*> inputs; std::vector<FileMetaData*> inputs;
current_->GetOverlappingInputs(level+1, &f->smallest, &f->largest, &inputs); current_->GetOverlappingInputs(level+1, &f->smallest, &f->largest,
&inputs, *parent_index, parent_index);
return FilesInCompaction(inputs); return FilesInCompaction(inputs);
} }
@ -1835,7 +1870,8 @@ void VersionSet::SetupOtherInputs(Compaction* c) {
InternalKey smallest, largest; InternalKey smallest, largest;
GetRange(c->inputs_[0], &smallest, &largest); GetRange(c->inputs_[0], &smallest, &largest);
current_->GetOverlappingInputs(level+1, &smallest, &largest, &c->inputs_[1]); current_->GetOverlappingInputs(level+1, &smallest, &largest, &c->inputs_[1],
c->parent_index_, &c->parent_index_);
// Get entire range covered by compaction // Get entire range covered by compaction
InternalKey all_start, all_limit; InternalKey all_start, all_limit;
@ -1845,7 +1881,8 @@ void VersionSet::SetupOtherInputs(Compaction* c) {
// changing the number of "level+1" files we pick up. // changing the number of "level+1" files we pick up.
if (!c->inputs_[1].empty()) { if (!c->inputs_[1].empty()) {
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_, NULL);
const int64_t inputs0_size = TotalFileSize(c->inputs_[0]); const int64_t inputs0_size = TotalFileSize(c->inputs_[0]);
const int64_t inputs1_size = TotalFileSize(c->inputs_[1]); const int64_t inputs1_size = TotalFileSize(c->inputs_[1]);
const int64_t expanded0_size = TotalFileSize(expanded0); const int64_t expanded0_size = TotalFileSize(expanded0);
@ -1857,7 +1894,8 @@ void VersionSet::SetupOtherInputs(Compaction* c) {
GetRange(expanded0, &new_start, &new_limit); GetRange(expanded0, &new_start, &new_limit);
std::vector<FileMetaData*> expanded1; std::vector<FileMetaData*> expanded1;
current_->GetOverlappingInputs(level+1, &new_start, &new_limit, current_->GetOverlappingInputs(level+1, &new_start, &new_limit,
&expanded1); &expanded1, c->parent_index_,
&c->parent_index_);
if (expanded1.size() == c->inputs_[1].size() && if (expanded1.size() == c->inputs_[1].size() &&
!FilesInCompaction(expanded1)) { !FilesInCompaction(expanded1)) {
Log(options_->info_log, Log(options_->info_log,
@ -1947,7 +1985,9 @@ Compaction::Compaction(int level, uint64_t target_file_size,
seek_compaction_(seek_compaction), seek_compaction_(seek_compaction),
grandparent_index_(0), grandparent_index_(0),
seen_key_(false), seen_key_(false),
overlapped_bytes_(0) { overlapped_bytes_(0),
base_index_(-1),
parent_index_(-1) {
edit_ = new VersionEdit(number_levels_); edit_ = new VersionEdit(number_levels_);
level_ptrs_ = new size_t[number_levels_]; level_ptrs_ = new size_t[number_levels_];
for (int i = 0; i < number_levels_; i++) { for (int i = 0; i < number_levels_; i++) {

@ -88,13 +88,17 @@ class Version {
int level, int level,
const InternalKey* begin, // NULL means before all keys const InternalKey* begin, // NULL means before all keys
const InternalKey* end, // NULL means after all keys const InternalKey* end, // NULL means after all keys
std::vector<FileMetaData*>* inputs); std::vector<FileMetaData*>* inputs,
int hint_index = -1, // index of overlap file
int* file_index = NULL); // return index of overlap file
void GetOverlappingInputsBinarySearch( void GetOverlappingInputsBinarySearch(
int level, int level,
const Slice& begin, // NULL means before all keys const Slice& begin, // NULL means before all keys
const Slice& end, // NULL means after all keys const Slice& end, // NULL means after all keys
std::vector<FileMetaData*>* inputs); std::vector<FileMetaData*>* inputs,
int hint_index, // index of overlap file
int* file_index); // return index of overlap file
void ExtendOverlappingInputs( void ExtendOverlappingInputs(
int level, int level,
@ -496,6 +500,8 @@ class Compaction {
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 int64_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 parent_index_; // index of some file with same range in files_[level_+1]
// State for implementing IsBaseLevelForKey // State for implementing IsBaseLevelForKey

@ -17,7 +17,7 @@ class FindFileTest {
FindFileTest() : disjoint_sorted_files_(true) { } FindFileTest() : disjoint_sorted_files_(true) { }
~FindFileTest() { ~FindFileTest() {
for (int i = 0; i < files_.size(); i++) { for (unsigned int i = 0; i < files_.size(); i++) {
delete files_[i]; delete files_[i];
} }
} }

@ -22,6 +22,7 @@ static std::string PrintContents(WriteBatch* b) {
Iterator* iter = mem->NewIterator(); Iterator* iter = mem->NewIterator();
for (iter->SeekToFirst(); iter->Valid(); iter->Next()) { for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {
ParsedInternalKey ikey; ParsedInternalKey ikey;
memset((void *)&ikey, 0, sizeof(ikey));
ASSERT_TRUE(ParseInternalKey(iter->key(), &ikey)); ASSERT_TRUE(ParseInternalKey(iter->key(), &ikey));
switch (ikey.type) { switch (ikey.type) {
case kTypeValue: case kTypeValue:
@ -66,7 +67,7 @@ TEST(WriteBatchTest, Multiple) {
batch.Delete(Slice("box")); batch.Delete(Slice("box"));
batch.Put(Slice("baz"), Slice("boo")); batch.Put(Slice("baz"), Slice("boo"));
WriteBatchInternal::SetSequence(&batch, 100); WriteBatchInternal::SetSequence(&batch, 100);
ASSERT_EQ(100, WriteBatchInternal::Sequence(&batch)); ASSERT_EQ(100U, WriteBatchInternal::Sequence(&batch));
ASSERT_EQ(3, WriteBatchInternal::Count(&batch)); ASSERT_EQ(3, WriteBatchInternal::Count(&batch));
ASSERT_EQ("Put(baz, boo)@102" ASSERT_EQ("Put(baz, boo)@102"
"Delete(box)@101" "Delete(box)@101"

@ -36,7 +36,7 @@ TEST(MemEnvTest, Basics) {
ASSERT_TRUE(!env_->FileExists("/dir/non_existent")); ASSERT_TRUE(!env_->FileExists("/dir/non_existent"));
ASSERT_TRUE(!env_->GetFileSize("/dir/non_existent", &file_size).ok()); ASSERT_TRUE(!env_->GetFileSize("/dir/non_existent", &file_size).ok());
ASSERT_OK(env_->GetChildren("/dir", &children)); ASSERT_OK(env_->GetChildren("/dir", &children));
ASSERT_EQ(0, children.size()); ASSERT_EQ(0U, children.size());
// Create a file. // Create a file.
ASSERT_OK(env_->NewWritableFile("/dir/f", &writable_file)); ASSERT_OK(env_->NewWritableFile("/dir/f", &writable_file));
@ -45,9 +45,9 @@ TEST(MemEnvTest, Basics) {
// Check that the file exists. // Check that the file exists.
ASSERT_TRUE(env_->FileExists("/dir/f")); ASSERT_TRUE(env_->FileExists("/dir/f"));
ASSERT_OK(env_->GetFileSize("/dir/f", &file_size)); ASSERT_OK(env_->GetFileSize("/dir/f", &file_size));
ASSERT_EQ(0, file_size); ASSERT_EQ(0U, file_size);
ASSERT_OK(env_->GetChildren("/dir", &children)); ASSERT_OK(env_->GetChildren("/dir", &children));
ASSERT_EQ(1, children.size()); ASSERT_EQ(1U, children.size());
ASSERT_EQ("f", children[0]); ASSERT_EQ("f", children[0]);
// Write to the file. // Write to the file.
@ -57,7 +57,7 @@ TEST(MemEnvTest, Basics) {
// Check for expected size. // Check for expected size.
ASSERT_OK(env_->GetFileSize("/dir/f", &file_size)); ASSERT_OK(env_->GetFileSize("/dir/f", &file_size));
ASSERT_EQ(3, file_size); ASSERT_EQ(3U, file_size);
// Check that renaming works. // Check that renaming works.
ASSERT_TRUE(!env_->RenameFile("/dir/non_existent", "/dir/g").ok()); ASSERT_TRUE(!env_->RenameFile("/dir/non_existent", "/dir/g").ok());
@ -65,7 +65,7 @@ TEST(MemEnvTest, Basics) {
ASSERT_TRUE(!env_->FileExists("/dir/f")); ASSERT_TRUE(!env_->FileExists("/dir/f"));
ASSERT_TRUE(env_->FileExists("/dir/g")); ASSERT_TRUE(env_->FileExists("/dir/g"));
ASSERT_OK(env_->GetFileSize("/dir/g", &file_size)); ASSERT_OK(env_->GetFileSize("/dir/g", &file_size));
ASSERT_EQ(3, file_size); ASSERT_EQ(3U, file_size);
// Check that opening non-existent file fails. // Check that opening non-existent file fails.
SequentialFile* seq_file; SequentialFile* seq_file;
@ -80,7 +80,7 @@ TEST(MemEnvTest, Basics) {
ASSERT_OK(env_->DeleteFile("/dir/g")); ASSERT_OK(env_->DeleteFile("/dir/g"));
ASSERT_TRUE(!env_->FileExists("/dir/g")); ASSERT_TRUE(!env_->FileExists("/dir/g"));
ASSERT_OK(env_->GetChildren("/dir", &children)); ASSERT_OK(env_->GetChildren("/dir", &children));
ASSERT_EQ(0, children.size()); ASSERT_EQ(0U, children.size());
ASSERT_OK(env_->DeleteDir("/dir")); ASSERT_OK(env_->DeleteDir("/dir"));
} }
@ -106,10 +106,10 @@ TEST(MemEnvTest, ReadWrite) {
ASSERT_OK(seq_file->Read(1000, &result, scratch)); // Read "world". ASSERT_OK(seq_file->Read(1000, &result, scratch)); // Read "world".
ASSERT_EQ(0, result.compare("world")); ASSERT_EQ(0, result.compare("world"));
ASSERT_OK(seq_file->Read(1000, &result, scratch)); // Try reading past EOF. ASSERT_OK(seq_file->Read(1000, &result, scratch)); // Try reading past EOF.
ASSERT_EQ(0, result.size()); ASSERT_EQ(0U, result.size());
ASSERT_OK(seq_file->Skip(100)); // Try to skip past end of file. ASSERT_OK(seq_file->Skip(100)); // Try to skip past end of file.
ASSERT_OK(seq_file->Read(1000, &result, scratch)); ASSERT_OK(seq_file->Read(1000, &result, scratch));
ASSERT_EQ(0, result.size()); ASSERT_EQ(0U, result.size());
delete seq_file; delete seq_file;
// Random reads. // Random reads.

@ -29,7 +29,7 @@ class TestHashFilter : public FilterPolicy {
virtual bool KeyMayMatch(const Slice& key, const Slice& filter) const { virtual bool KeyMayMatch(const Slice& key, const Slice& filter) const {
uint32_t h = Hash(key.data(), key.size(), 1); uint32_t h = Hash(key.data(), key.size(), 1);
for (int i = 0; i + 4 <= filter.size(); i += 4) { for (unsigned int i = 0; i + 4 <= filter.size(); i += 4) {
if (h == DecodeFixed32(filter.data() + i)) { if (h == DecodeFixed32(filter.data() + i)) {
return true; return true;
} }

@ -238,7 +238,6 @@ Status Table::InternalGet(const ReadOptions& options, const Slice& k,
!filter->KeyMayMatch(handle.offset(), k)) { !filter->KeyMayMatch(handle.offset(), k)) {
// Not found // Not found
} else { } else {
Slice handle = iiter->value();
bool didIO = false; bool didIO = false;
Iterator* block_iter = BlockReader(this, options, iiter->value(), Iterator* block_iter = BlockReader(this, options, iiter->value(),
&didIO); &didIO);

@ -75,7 +75,7 @@ static void Increment(const Comparator* cmp, std::string* key) {
} }
// An STL comparator that uses a Comparator // An STL comparator that uses a Comparator
namespace { namespace anon {
struct STLLessThan { struct STLLessThan {
const Comparator* cmp; const Comparator* cmp;
@ -134,13 +134,13 @@ class StringSource: public RandomAccessFile {
std::string contents_; std::string contents_;
}; };
typedef std::map<std::string, std::string, STLLessThan> KVMap; typedef std::map<std::string, std::string, anon::STLLessThan> KVMap;
// Helper class for tests to unify the interface between // Helper class for tests to unify the interface between
// BlockBuilder/TableBuilder and Block/Table. // BlockBuilder/TableBuilder and Block/Table.
class Constructor { class Constructor {
public: public:
explicit Constructor(const Comparator* cmp) : data_(STLLessThan(cmp)) { } explicit Constructor(const Comparator* cmp) : data_(anon::STLLessThan(cmp)) { }
virtual ~Constructor() { } virtual ~Constructor() { }
void Add(const std::string& key, const Slice& value) { void Add(const std::string& key, const Slice& value) {
@ -464,7 +464,7 @@ static std::vector<TestArgs> Generate_Arg_List()
for(int i =0; i < test_type_len; i++) for(int i =0; i < test_type_len; i++)
for (int j =0; j < reverse_compare_len; j++) for (int j =0; j < reverse_compare_len; j++)
for (int k =0; k < restart_interval_len; k++) for (int k =0; k < restart_interval_len; k++)
for (int n =0; n < compression_types.size(); n++) { for (unsigned int n =0; n < compression_types.size(); n++) {
TestArgs one_arg; TestArgs one_arg;
one_arg.type = test_type[i]; one_arg.type = test_type[i];
one_arg.reverse_compare = reverse_compare[j]; one_arg.reverse_compare = reverse_compare[j];
@ -690,7 +690,7 @@ class Harness {
// Test the empty key // Test the empty key
TEST(Harness, SimpleEmptyKey) { TEST(Harness, SimpleEmptyKey) {
std::vector<TestArgs> args = Generate_Arg_List(); std::vector<TestArgs> args = Generate_Arg_List();
for (int i = 0; i < args.size(); i++) { for (unsigned int i = 0; i < args.size(); i++) {
Init(args[i]); Init(args[i]);
Random rnd(test::RandomSeed() + 1); Random rnd(test::RandomSeed() + 1);
Add("", "v"); Add("", "v");
@ -700,7 +700,7 @@ TEST(Harness, SimpleEmptyKey) {
TEST(Harness, SimpleSingle) { TEST(Harness, SimpleSingle) {
std::vector<TestArgs> args = Generate_Arg_List(); std::vector<TestArgs> args = Generate_Arg_List();
for (int i = 0; i < args.size(); i++) { for (unsigned int i = 0; i < args.size(); i++) {
Init(args[i]); Init(args[i]);
Random rnd(test::RandomSeed() + 2); Random rnd(test::RandomSeed() + 2);
Add("abc", "v"); Add("abc", "v");
@ -710,7 +710,7 @@ TEST(Harness, SimpleSingle) {
TEST(Harness, SimpleMulti) { TEST(Harness, SimpleMulti) {
std::vector<TestArgs> args = Generate_Arg_List(); std::vector<TestArgs> args = Generate_Arg_List();
for (int i = 0; i < args.size(); i++) { for (unsigned int i = 0; i < args.size(); i++) {
Init(args[i]); Init(args[i]);
Random rnd(test::RandomSeed() + 3); Random rnd(test::RandomSeed() + 3);
Add("abc", "v"); Add("abc", "v");
@ -722,7 +722,7 @@ TEST(Harness, SimpleMulti) {
TEST(Harness, SimpleSpecialKey) { TEST(Harness, SimpleSpecialKey) {
std::vector<TestArgs> args = Generate_Arg_List(); std::vector<TestArgs> args = Generate_Arg_List();
for (int i = 0; i < args.size(); i++) { for (unsigned int i = 0; i < args.size(); i++) {
Init(args[i]); Init(args[i]);
Random rnd(test::RandomSeed() + 4); Random rnd(test::RandomSeed() + 4);
Add("\xff\xff", "v3"); Add("\xff\xff", "v3");
@ -732,7 +732,7 @@ TEST(Harness, SimpleSpecialKey) {
TEST(Harness, Randomized) { TEST(Harness, Randomized) {
std::vector<TestArgs> args = Generate_Arg_List(); std::vector<TestArgs> args = Generate_Arg_List();
for (int i = 0; i < args.size(); i++) { for (unsigned int i = 0; i < args.size(); i++) {
Init(args[i]); Init(args[i]);
Random rnd(test::RandomSeed() + 5); Random rnd(test::RandomSeed() + 5);
for (int num_entries = 0; num_entries < 2000; for (int num_entries = 0; num_entries < 2000;

@ -109,7 +109,7 @@ static int FLAGS_level0_stop_writes_trigger = 12;
static int FLAGS_level0_slowdown_writes_trigger = 8; static int FLAGS_level0_slowdown_writes_trigger = 8;
// Ratio of reads to writes (expressed as a percentage) // Ratio of reads to writes (expressed as a percentage)
static int FLAGS_readwritepercent = 10; static unsigned int FLAGS_readwritepercent = 10;
// Option to disable compation triggered by read. // Option to disable compation triggered by read.
static int FLAGS_disable_seek_compaction = false; static int FLAGS_disable_seek_compaction = false;
@ -225,7 +225,6 @@ class Stats {
double bytes_mb = bytes_ / 1048576.0; double bytes_mb = bytes_ / 1048576.0;
double rate = bytes_mb / elapsed; double rate = bytes_mb / elapsed;
double throughput = (double)done_/elapsed; double throughput = (double)done_/elapsed;
long percent_writes = (writes_ * 100) / done_;
fprintf(stdout, "%-12s: ", name); fprintf(stdout, "%-12s: ", name);
fprintf(stdout, "%.3f micros/op %ld ops/sec\n", fprintf(stdout, "%.3f micros/op %ld ops/sec\n",
@ -395,7 +394,7 @@ class StressTest {
db_(NULL) { db_(NULL) {
std::vector<std::string> files; std::vector<std::string> files;
FLAGS_env->GetChildren(FLAGS_db, &files); FLAGS_env->GetChildren(FLAGS_db, &files);
for (int i = 0; i < files.size(); i++) { for (unsigned int i = 0; i < files.size(); i++) {
if (Slice(files[i]).starts_with("heap-")) { if (Slice(files[i]).starts_with("heap-")) {
FLAGS_env->DeleteFile(std::string(FLAGS_db) + "/" + files[i]); FLAGS_env->DeleteFile(std::string(FLAGS_db) + "/" + files[i]);
} }
@ -445,12 +444,12 @@ class StressTest {
} }
} }
for (int i = 1; i < n; i++) { for (unsigned int i = 1; i < n; i++) {
threads[0]->stats.Merge(threads[i]->stats); threads[0]->stats.Merge(threads[i]->stats);
} }
threads[0]->stats.Report("Stress Test"); threads[0]->stats.Report("Stress Test");
for (int i = 0; i < n; i++) { for (unsigned int i = 0; i < n; i++) {
delete threads[i]; delete threads[i];
threads[i] = NULL; threads[i] = NULL;
} }
@ -588,7 +587,7 @@ class StressTest {
static void PrintKeyValue(uint32_t key, const char *value, size_t sz) { static void PrintKeyValue(uint32_t key, const char *value, size_t sz) {
if (!FLAGS_verbose) return; if (!FLAGS_verbose) return;
fprintf(stdout, "%u ==> (%u) ", key, sz); fprintf(stdout, "%u ==> (%u) ", key, (unsigned int)sz);
for (size_t i=0; i<sz; i++) { for (size_t i=0; i<sz; i++) {
fprintf(stdout, "%X", value[i]); fprintf(stdout, "%X", value[i]);
} }
@ -599,7 +598,6 @@ class StressTest {
size_t value_sz = ((rand % 3) + 1) * FLAGS_value_size_mult; size_t value_sz = ((rand % 3) + 1) * FLAGS_value_size_mult;
assert(value_sz <= max_sz && value_sz >= sizeof(uint32_t)); assert(value_sz <= max_sz && value_sz >= sizeof(uint32_t));
*((uint32_t*)v) = rand; *((uint32_t*)v) = rand;
char c = (char) rand;
for (size_t i=sizeof(uint32_t); i < value_sz; i++) { for (size_t i=sizeof(uint32_t); i < value_sz; i++) {
v[i] = (char)(rand ^ i); v[i] = (char)(rand ^ i);
} }
@ -610,13 +608,13 @@ class StressTest {
fprintf(stdout, "LevelDB version : %d.%d\n", fprintf(stdout, "LevelDB version : %d.%d\n",
kMajorVersion, kMinorVersion); kMajorVersion, kMinorVersion);
fprintf(stdout, "Number of threads : %d\n", FLAGS_threads); fprintf(stdout, "Number of threads : %d\n", FLAGS_threads);
fprintf(stdout, "Ops per thread : %ld\n", FLAGS_ops_per_thread); fprintf(stdout, "Ops per thread : %d\n", FLAGS_ops_per_thread);
fprintf(stdout, "Read percentage : %ld\n", FLAGS_readwritepercent); fprintf(stdout, "Read percentage : %d\n", FLAGS_readwritepercent);
fprintf(stdout, "Max key : %ld\n", FLAGS_max_key); fprintf(stdout, "Max key : %ld\n", FLAGS_max_key);
fprintf(stdout, "Num keys per lock : %ld\n", fprintf(stdout, "Num keys per lock : %d\n",
1 << FLAGS_log2_keys_per_lock); 1 << FLAGS_log2_keys_per_lock);
char* compression; char* compression = "";
switch (FLAGS_compression_type) { switch (FLAGS_compression_type) {
case leveldb::kNoCompression: case leveldb::kNoCompression:
compression = (char *)std::string("none").c_str(); compression = (char *)std::string("none").c_str();
@ -698,7 +696,6 @@ int main(int argc, char** argv) {
std::string default_db_path; std::string default_db_path;
for (int i = 1; i < argc; i++) { for (int i = 1; i < argc; i++) {
double d;
int n; int n;
uint32_t u; uint32_t u;
long l; long l;

@ -85,7 +85,7 @@ static void print_help() {
int main(int argc, char** argv) { int main(int argc, char** argv) {
const char* dir_or_file; const char* dir_or_file = NULL;
uint64_t read_num = -1; uint64_t read_num = -1;
std::string command; std::string command;

@ -40,7 +40,7 @@ TEST(ArenaTest, Simple) {
r = arena.Allocate(s); r = arena.Allocate(s);
} }
for (int b = 0; b < s; b++) { for (unsigned int b = 0; b < s; b++) {
// Fill the "i"th allocation with a known bit pattern // Fill the "i"th allocation with a known bit pattern
r[b] = i % 256; r[b] = i % 256;
} }
@ -51,12 +51,12 @@ TEST(ArenaTest, Simple) {
ASSERT_LE(arena.MemoryUsage(), bytes * 1.10); ASSERT_LE(arena.MemoryUsage(), bytes * 1.10);
} }
} }
for (int i = 0; i < allocated.size(); i++) { for (unsigned int i = 0; i < allocated.size(); i++) {
size_t num_bytes = allocated[i].first; size_t num_bytes = allocated[i].first;
const char* p = allocated[i].second; const char* p = allocated[i].second;
for (int b = 0; b < num_bytes; b++) { for (unsigned int b = 0; b < num_bytes; b++) {
// Check the "i"th allocation for the known bit pattern // Check the "i"th allocation for the known bit pattern
ASSERT_EQ(int(p[b]) & 0xff, i % 256); ASSERT_EQ(int(p[b]) & 0xff, (int)(i % 256));
} }
} }
} }

@ -33,8 +33,11 @@ class AutoSplitLogger : public Logger {
public: public:
AutoSplitLogger(Env* env, const std::string& dbname, AutoSplitLogger(Env* env, const std::string& dbname,
const std::string& db_log_dir, size_t log_max_size): const std::string& db_log_dir, size_t log_max_size):
env_(env), dbname_(dbname), db_log_dir_(db_log_dir), dbname_(dbname),
MAX_LOG_FILE_SIZE(log_max_size), status_(Status::OK()) { db_log_dir_(db_log_dir),
env_(env),
MAX_LOG_FILE_SIZE(log_max_size),
status_(Status::OK()) {
env->GetAbsolutePath(dbname, &db_absolute_path_); env->GetAbsolutePath(dbname, &db_absolute_path_);
log_fname_ = InfoLogFileName(dbname_, db_absolute_path_, db_log_dir_); log_fname_ = InfoLogFileName(dbname_, db_absolute_path_, db_log_dir_);
InitLogger(); InitLogger();
@ -67,7 +70,7 @@ class AutoSplitLogger : public Logger {
logger_ = NULL; logger_ = NULL;
} }
if (logger_->GetLogFileSize() == if (logger_->GetLogFileSize() ==
Logger::DO_NOT_SUPPORT_GET_LOG_FILE_SIZE) { (size_t)Logger::DO_NOT_SUPPORT_GET_LOG_FILE_SIZE) {
status_ = Status::NotSupported( status_ = Status::NotSupported(
"The underlying logger doesn't support GetLogFileSize()"); "The underlying logger doesn't support GetLogFileSize()");
} }

@ -58,7 +58,7 @@ class BloomFilterPolicy : public FilterPolicy {
dst->resize(init_size + bytes, 0); dst->resize(init_size + bytes, 0);
dst->push_back(static_cast<char>(k_)); // Remember # of probes in filter dst->push_back(static_cast<char>(k_)); // Remember # of probes in filter
char* array = &(*dst)[init_size]; char* array = &(*dst)[init_size];
for (size_t i = 0; i < n; i++) { for (size_t i = 0; i < (size_t)n; i++) {
// Use double-hashing to generate a sequence of hash values. // Use double-hashing to generate a sequence of hash values.
// See analysis in [Kirsch,Mitzenmacher 2006]. // See analysis in [Kirsch,Mitzenmacher 2006].
uint32_t h = hash_func_(keys[i]); uint32_t h = hash_func_(keys[i]);

@ -125,7 +125,7 @@ TEST(BloomTest, VaryingLengths) {
} }
Build(); Build();
ASSERT_LE(FilterSize(), (length * 10 / 8) + 40) << length; ASSERT_LE(FilterSize(), (size_t)((length * 10 / 8) + 40)) << length;
// All added keys must match // All added keys must match
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {

@ -116,7 +116,6 @@ class HandleTable {
LRUHandle* h = list_[i]; LRUHandle* h = list_[i];
while (h != NULL) { while (h != NULL) {
LRUHandle* next = h->next_hash; LRUHandle* next = h->next_hash;
Slice key = h->key();
uint32_t hash = h->hash; uint32_t hash = h->hash;
LRUHandle** ptr = &new_list[hash & (new_length - 1)]; LRUHandle** ptr = &new_list[hash & (new_length - 1)];
h->next_hash = *ptr; h->next_hash = *ptr;
@ -268,7 +267,6 @@ void LRUCache::Erase(const Slice& key, uint32_t hash) {
} }
static int kNumShardBits = 4; // default values, can be overridden static int kNumShardBits = 4; // default values, can be overridden
static int kNumShards = 1 << kNumShardBits;
class ShardedLRUCache : public Cache { class ShardedLRUCache : public Cache {
private: private:

@ -83,28 +83,28 @@ TEST(CacheTest, HitAndMiss) {
ASSERT_EQ(201, Lookup(200)); ASSERT_EQ(201, Lookup(200));
ASSERT_EQ(-1, Lookup(300)); ASSERT_EQ(-1, Lookup(300));
ASSERT_EQ(1, deleted_keys_.size()); ASSERT_EQ(1U, deleted_keys_.size());
ASSERT_EQ(100, deleted_keys_[0]); ASSERT_EQ(100, deleted_keys_[0]);
ASSERT_EQ(101, deleted_values_[0]); ASSERT_EQ(101, deleted_values_[0]);
} }
TEST(CacheTest, Erase) { TEST(CacheTest, Erase) {
Erase(200); Erase(200);
ASSERT_EQ(0, deleted_keys_.size()); ASSERT_EQ(0U, deleted_keys_.size());
Insert(100, 101); Insert(100, 101);
Insert(200, 201); Insert(200, 201);
Erase(100); Erase(100);
ASSERT_EQ(-1, Lookup(100)); ASSERT_EQ(-1, Lookup(100));
ASSERT_EQ(201, Lookup(200)); ASSERT_EQ(201, Lookup(200));
ASSERT_EQ(1, deleted_keys_.size()); ASSERT_EQ(1U, deleted_keys_.size());
ASSERT_EQ(100, deleted_keys_[0]); ASSERT_EQ(100, deleted_keys_[0]);
ASSERT_EQ(101, deleted_values_[0]); ASSERT_EQ(101, deleted_values_[0]);
Erase(100); Erase(100);
ASSERT_EQ(-1, Lookup(100)); ASSERT_EQ(-1, Lookup(100));
ASSERT_EQ(201, Lookup(200)); ASSERT_EQ(201, Lookup(200));
ASSERT_EQ(1, deleted_keys_.size()); ASSERT_EQ(1U, deleted_keys_.size());
} }
TEST(CacheTest, EntriesArePinned) { TEST(CacheTest, EntriesArePinned) {
@ -115,19 +115,19 @@ TEST(CacheTest, EntriesArePinned) {
Insert(100, 102); Insert(100, 102);
Cache::Handle* h2 = cache_->Lookup(EncodeKey(100)); Cache::Handle* h2 = cache_->Lookup(EncodeKey(100));
ASSERT_EQ(102, DecodeValue(cache_->Value(h2))); ASSERT_EQ(102, DecodeValue(cache_->Value(h2)));
ASSERT_EQ(0, deleted_keys_.size()); ASSERT_EQ(0U, deleted_keys_.size());
cache_->Release(h1); cache_->Release(h1);
ASSERT_EQ(1, deleted_keys_.size()); ASSERT_EQ(1U, deleted_keys_.size());
ASSERT_EQ(100, deleted_keys_[0]); ASSERT_EQ(100, deleted_keys_[0]);
ASSERT_EQ(101, deleted_values_[0]); ASSERT_EQ(101, deleted_values_[0]);
Erase(100); Erase(100);
ASSERT_EQ(-1, Lookup(100)); ASSERT_EQ(-1, Lookup(100));
ASSERT_EQ(1, deleted_keys_.size()); ASSERT_EQ(1U, deleted_keys_.size());
cache_->Release(h2); cache_->Release(h2);
ASSERT_EQ(2, deleted_keys_.size()); ASSERT_EQ(2U, deleted_keys_.size());
ASSERT_EQ(100, deleted_keys_[1]); ASSERT_EQ(100, deleted_keys_[1]);
ASSERT_EQ(102, deleted_values_[1]); ASSERT_EQ(102, deleted_values_[1]);
} }

@ -79,7 +79,7 @@ void PutVarint32(std::string* dst, uint32_t v) {
} }
char* EncodeVarint64(char* dst, uint64_t v) { char* EncodeVarint64(char* dst, uint64_t v) {
static const int B = 128; static const unsigned int B = 128;
unsigned char* ptr = reinterpret_cast<unsigned char*>(dst); unsigned char* ptr = reinterpret_cast<unsigned char*>(dst);
while (v >= B) { while (v >= B) {
*(ptr++) = (v & (B-1)) | B; *(ptr++) = (v & (B-1)) | B;

@ -55,7 +55,7 @@ TEST(Coding, Fixed64) {
TEST(Coding, EncodingOutput) { TEST(Coding, EncodingOutput) {
std::string dst; std::string dst;
PutFixed32(&dst, 0x04030201); PutFixed32(&dst, 0x04030201);
ASSERT_EQ(4, dst.size()); ASSERT_EQ(4U, dst.size());
ASSERT_EQ(0x01, static_cast<int>(dst[0])); ASSERT_EQ(0x01, static_cast<int>(dst[0]));
ASSERT_EQ(0x02, static_cast<int>(dst[1])); ASSERT_EQ(0x02, static_cast<int>(dst[1]));
ASSERT_EQ(0x03, static_cast<int>(dst[2])); ASSERT_EQ(0x03, static_cast<int>(dst[2]));
@ -63,7 +63,7 @@ TEST(Coding, EncodingOutput) {
dst.clear(); dst.clear();
PutFixed64(&dst, 0x0807060504030201ull); PutFixed64(&dst, 0x0807060504030201ull);
ASSERT_EQ(8, dst.size()); ASSERT_EQ(8U, dst.size());
ASSERT_EQ(0x01, static_cast<int>(dst[0])); ASSERT_EQ(0x01, static_cast<int>(dst[0]));
ASSERT_EQ(0x02, static_cast<int>(dst[1])); ASSERT_EQ(0x02, static_cast<int>(dst[1]));
ASSERT_EQ(0x03, static_cast<int>(dst[2])); ASSERT_EQ(0x03, static_cast<int>(dst[2]));
@ -112,13 +112,13 @@ TEST(Coding, Varint64) {
}; };
std::string s; std::string s;
for (int i = 0; i < values.size(); i++) { for (unsigned int i = 0; i < values.size(); i++) {
PutVarint64(&s, values[i]); PutVarint64(&s, values[i]);
} }
const char* p = s.data(); const char* p = s.data();
const char* limit = p + s.size(); const char* limit = p + s.size();
for (int i = 0; i < values.size(); i++) { for (unsigned int i = 0; i < values.size(); i++) {
ASSERT_TRUE(p < limit); ASSERT_TRUE(p < limit);
uint64_t actual; uint64_t actual;
const char* start = p; const char* start = p;
@ -143,7 +143,7 @@ TEST(Coding, Varint32Truncation) {
std::string s; std::string s;
PutVarint32(&s, large_value); PutVarint32(&s, large_value);
uint32_t result; uint32_t result;
for (int len = 0; len < s.size() - 1; len++) { for (unsigned int len = 0; len < s.size() - 1; len++) {
ASSERT_TRUE(GetVarint32Ptr(s.data(), s.data() + len, &result) == NULL); ASSERT_TRUE(GetVarint32Ptr(s.data(), s.data() + len, &result) == NULL);
} }
ASSERT_TRUE(GetVarint32Ptr(s.data(), s.data() + s.size(), &result) != NULL); ASSERT_TRUE(GetVarint32Ptr(s.data(), s.data() + s.size(), &result) != NULL);
@ -162,7 +162,7 @@ TEST(Coding, Varint64Truncation) {
std::string s; std::string s;
PutVarint64(&s, large_value); PutVarint64(&s, large_value);
uint64_t result; uint64_t result;
for (int len = 0; len < s.size() - 1; len++) { for (unsigned int len = 0; len < s.size() - 1; len++) {
ASSERT_TRUE(GetVarint64Ptr(s.data(), s.data() + len, &result) == NULL); ASSERT_TRUE(GetVarint64Ptr(s.data(), s.data() + len, &result) == NULL);
} }
ASSERT_TRUE(GetVarint64Ptr(s.data(), s.data() + s.size(), &result) != NULL); ASSERT_TRUE(GetVarint64Ptr(s.data(), s.data() + s.size(), &result) != NULL);

@ -15,20 +15,20 @@ TEST(CRC, StandardResults) {
char buf[32]; char buf[32];
memset(buf, 0, sizeof(buf)); memset(buf, 0, sizeof(buf));
ASSERT_EQ(0x8a9136aa, Value(buf, sizeof(buf))); ASSERT_EQ(0x8a9136aaU, Value(buf, sizeof(buf)));
memset(buf, 0xff, sizeof(buf)); memset(buf, 0xff, sizeof(buf));
ASSERT_EQ(0x62a8ab43, Value(buf, sizeof(buf))); ASSERT_EQ(0x62a8ab43U, Value(buf, sizeof(buf)));
for (int i = 0; i < 32; i++) { for (int i = 0; i < 32; i++) {
buf[i] = i; buf[i] = i;
} }
ASSERT_EQ(0x46dd794e, Value(buf, sizeof(buf))); ASSERT_EQ(0x46dd794eU, Value(buf, sizeof(buf)));
for (int i = 0; i < 32; i++) { for (int i = 0; i < 32; i++) {
buf[i] = 31 - i; buf[i] = 31 - i;
} }
ASSERT_EQ(0x113fdb5c, Value(buf, sizeof(buf))); ASSERT_EQ(0x113fdb5cU, Value(buf, sizeof(buf)));
unsigned char data[48] = { unsigned char data[48] = {
0x01, 0xc0, 0x00, 0x00, 0x01, 0xc0, 0x00, 0x00,

@ -61,7 +61,7 @@ TEST(EnvPosixTest, RunMany) {
Env::Default()->SleepForMicroseconds(kDelayMicros); Env::Default()->SleepForMicroseconds(kDelayMicros);
void* cur = last_id.Acquire_Load(); void* cur = last_id.Acquire_Load();
ASSERT_EQ(4, reinterpret_cast<uintptr_t>(cur)); ASSERT_EQ(4U, reinterpret_cast<uintptr_t>(cur));
} }
struct State { struct State {

@ -12,7 +12,7 @@ const char* LDBCommand::HEX_ARG = "--hex";
Compactor::Compactor(std::string& db_name, std::vector<std::string>& args) : Compactor::Compactor(std::string& db_name, std::vector<std::string>& args) :
LDBCommand(db_name, args), null_from_(true), null_to_(true), hex_(false) { LDBCommand(db_name, args), null_from_(true), null_to_(true), hex_(false) {
for (int i = 0; i < args.size(); i++) { for (unsigned int i = 0; i < args.size(); i++) {
std::string& arg = args.at(i); std::string& arg = args.at(i);
if (arg.find(FROM_ARG) == 0) { if (arg.find(FROM_ARG) == 0) {
null_from_ = false; null_from_ = false;
@ -68,10 +68,15 @@ const char* DBDumper::STATS_ARG = "--stats";
const char* DBDumper::HEX_OUTPUT_ARG = "--output_hex"; const char* DBDumper::HEX_OUTPUT_ARG = "--output_hex";
DBDumper::DBDumper(std::string& db_name, std::vector<std::string>& args) : DBDumper::DBDumper(std::string& db_name, std::vector<std::string>& args) :
LDBCommand(db_name, args), null_from_(true), null_to_(true), hex_(false), LDBCommand(db_name, args),
count_only_(false), print_stats_(false), max_keys_(-1), null_from_(true),
hex_output_(false) { null_to_(true),
for (int i = 0; i < args.size(); i++) { max_keys_(-1),
count_only_(false),
print_stats_(false),
hex_(false),
hex_output_(false) {
for (unsigned int i = 0; i < args.size(); i++) {
std::string& arg = args.at(i); std::string& arg = args.at(i);
if (arg.find(FROM_ARG) == 0) { if (arg.find(FROM_ARG) == 0) {
null_from_ = false; null_from_ = false;
@ -154,12 +159,12 @@ void DBDumper::DoCommand() {
if (!count_only_) { if (!count_only_) {
if (hex_output_) { if (hex_output_) {
std::string str = iter->key().ToString(); std::string str = iter->key().ToString();
for (int i = 0; i < str.length(); ++i) { for (unsigned int i = 0; i < str.length(); ++i) {
fprintf(stdout, "%X", str[i]); fprintf(stdout, "%X", str[i]);
} }
fprintf(stdout, " ==> "); fprintf(stdout, " ==> ");
str = iter->value().ToString(); str = iter->value().ToString();
for (int i = 0; i < str.length(); ++i) { for (unsigned int i = 0; i < str.length(); ++i) {
fprintf(stdout, "%X", str[i]); fprintf(stdout, "%X", str[i]);
} }
fprintf(stdout, "\n"); fprintf(stdout, "\n");
@ -183,7 +188,7 @@ ReduceDBLevels::ReduceDBLevels(std::string& db_name,
: LDBCommand(db_name, args), : LDBCommand(db_name, args),
new_levels_(-1), new_levels_(-1),
print_old_levels_(false) { print_old_levels_(false) {
for (int i = 0; i < args.size(); i++) { for (unsigned int i = 0; i < args.size(); i++) {
std::string& arg = args.at(i); std::string& arg = args.at(i);
if (arg.find(NEW_LEVLES_ARG) == 0) { if (arg.find(NEW_LEVLES_ARG) == 0) {
new_levels_ = atoi(arg.substr(strlen(NEW_LEVLES_ARG)).c_str()); new_levels_ = atoi(arg.substr(strlen(NEW_LEVLES_ARG)).c_str());

@ -143,7 +143,7 @@ public:
static std::string HexToString(const std::string& str) { static std::string HexToString(const std::string& str) {
std::string parsed; std::string parsed;
for (int i = 0; i < str.length();) { for (unsigned int i = 0; i < str.length();) {
int c; int c;
sscanf(str.c_str() + i, "%2X", &c); sscanf(str.c_str() + i, "%2X", &c);
parsed.push_back(c); parsed.push_back(c);

@ -61,7 +61,7 @@ bool ConsumeDecimalNumber(Slice* in, uint64_t* val) {
char c = (*in)[0]; char c = (*in)[0];
if (c >= '0' && c <= '9') { if (c >= '0' && c <= '9') {
++digits; ++digits;
const int delta = (c - '0'); const unsigned int delta = (c - '0');
static const uint64_t kMaxUint64 = ~static_cast<uint64_t>(0); static const uint64_t kMaxUint64 = ~static_cast<uint64_t>(0);
if (v > kMaxUint64/10 || if (v > kMaxUint64/10 ||
(v == kMaxUint64/10 && delta > kMaxUint64%10)) { (v == kMaxUint64/10 && delta > kMaxUint64%10)) {

@ -44,12 +44,12 @@ Options::Options()
db_stats_log_interval(1800), db_stats_log_interval(1800),
db_log_dir(""), db_log_dir(""),
disable_seek_compaction(false), disable_seek_compaction(false),
no_block_cache(false), delete_obsolete_files_period_micros(0),
table_cache_numshardbits(4),
max_background_compactions(1), max_background_compactions(1),
max_log_file_size(0), max_log_file_size(0),
delete_obsolete_files_period_micros(0),
rate_limit(0.0), rate_limit(0.0),
no_block_cache(false),
table_cache_numshardbits(4),
CompactionFilter(NULL) { CompactionFilter(NULL) {
} }
@ -64,7 +64,7 @@ Options::Dump(
Log(log," Options.env: %p", env); Log(log," Options.env: %p", env);
Log(log," Options.info_log: %p", info_log); Log(log," Options.info_log: %p", info_log);
Log(log," Options.write_buffer_size: %zd", write_buffer_size); Log(log," Options.write_buffer_size: %zd", write_buffer_size);
Log(log," Options.max_write_buffer_number: %zd", max_write_buffer_number); Log(log," Options.max_write_buffer_number: %d", max_write_buffer_number);
Log(log," Options.max_open_files: %d", max_open_files); Log(log," Options.max_open_files: %d", max_open_files);
Log(log," Options.block_cache: %p", block_cache); Log(log," Options.block_cache: %p", block_cache);
if (block_cache) { if (block_cache) {
@ -74,7 +74,7 @@ Options::Dump(
Log(log," Options.block_size: %zd", block_size); Log(log," Options.block_size: %zd", block_size);
Log(log," Options.block_restart_interval: %d", block_restart_interval); Log(log," Options.block_restart_interval: %d", block_restart_interval);
if (compression_per_level != NULL) { if (compression_per_level != NULL) {
for (unsigned int i = 0; i < num_levels; i++){ for (int i = 0; i < num_levels; i++){
Log(log," Options.compression[%d]: %d", Log(log," Options.compression[%d]: %d",
i, compression_per_level[i]); i, compression_per_level[i]);
} }
@ -86,8 +86,8 @@ Options::Dump(
Log(log," Options.num_levels: %d", num_levels); Log(log," Options.num_levels: %d", num_levels);
Log(log," Options.disableDataSync: %d", disableDataSync); Log(log," Options.disableDataSync: %d", disableDataSync);
Log(log," Options.use_fsync: %d", use_fsync); Log(log," Options.use_fsync: %d", use_fsync);
Log(log," Options.max_log_file_size: %d", max_log_file_size); Log(log," Options.max_log_file_size: %ld", max_log_file_size);
Log(log," Options.db_stats_log_interval: %d", Log(log," Options.db_stats_log_interval: %d",
db_stats_log_interval); db_stats_log_interval);
Log(log," Options.compression_opts.window_bits: %d", Log(log," Options.compression_opts.window_bits: %d",
compression_opts.window_bits); compression_opts.window_bits);

@ -38,7 +38,7 @@ int RunAllTests() {
int num = 0; int num = 0;
if (tests != NULL) { if (tests != NULL) {
for (int i = 0; i < tests->size(); i++) { for (unsigned int i = 0; i < tests->size(); i++) {
const Test& t = (*tests)[i]; const Test& t = (*tests)[i];
if (matcher != NULL) { if (matcher != NULL) {
std::string name = t.base; std::string name = t.base;

@ -40,7 +40,7 @@ extern Slice CompressibleString(Random* rnd, double compressed_fraction,
// Duplicate the random data until we have filled "len" bytes // Duplicate the random data until we have filled "len" bytes
dst->clear(); dst->clear();
while (dst->size() < len) { while (dst->size() < (unsigned int)len) {
dst->append(raw_data); dst->append(raw_data);
} }
dst->resize(len); dst->resize(len);

Loading…
Cancel
Save