Merge branch 'master' into columnfamilies
Conflicts: db/version_set.cc tools/db_stress.cc
This commit is contained in:
commit
e0c1211555
2
LICENSE
2
LICENSE
@ -2,7 +2,7 @@ BSD License
|
||||
|
||||
For rocksdb software
|
||||
|
||||
Copyright (c) 2013, Facebook, Inc.
|
||||
Copyright (c) 2014, Facebook, Inc.
|
||||
All rights reserved.
|
||||
---------------------------------------------------------------------
|
||||
|
||||
|
2
Makefile
2
Makefile
@ -36,7 +36,7 @@ else
|
||||
PLATFORM_CCFLAGS += $(JEMALLOC_INCLUDE) -DHAVE_JEMALLOC
|
||||
endif
|
||||
|
||||
WARNING_FLAGS = -Wall -Werror
|
||||
WARNING_FLAGS = -Wall -Werror -Wno-sign-compare
|
||||
CFLAGS += -g $(WARNING_FLAGS) -I. -I./include $(PLATFORM_CCFLAGS) $(OPT)
|
||||
CXXFLAGS += -g $(WARNING_FLAGS) -I. -I./include $(PLATFORM_CXXFLAGS) $(OPT) -Woverloaded-virtual
|
||||
|
||||
|
@ -379,10 +379,10 @@ void DBIter::FindPrevUserEntry() {
|
||||
uint64_t num_skipped = 0;
|
||||
|
||||
ValueType value_type = kTypeDeletion;
|
||||
bool saved_key_valid = true;
|
||||
if (iter_->Valid()) {
|
||||
do {
|
||||
ParsedInternalKey ikey;
|
||||
bool saved_key_cleared = false;
|
||||
if (ParseKey(&ikey) && ikey.sequence <= sequence_) {
|
||||
if ((value_type != kTypeDeletion) &&
|
||||
user_comparator_->Compare(ikey.user_key, saved_key_) < 0) {
|
||||
@ -393,7 +393,7 @@ void DBIter::FindPrevUserEntry() {
|
||||
if (value_type == kTypeDeletion) {
|
||||
saved_key_.clear();
|
||||
ClearSavedValue();
|
||||
saved_key_cleared = true;
|
||||
saved_key_valid = false;
|
||||
} else {
|
||||
Slice raw_value = iter_->value();
|
||||
if (saved_value_.capacity() > raw_value.size() + 1048576) {
|
||||
@ -403,13 +403,17 @@ void DBIter::FindPrevUserEntry() {
|
||||
SaveKey(ExtractUserKey(iter_->key()), &saved_key_);
|
||||
saved_value_.assign(raw_value.data(), raw_value.size());
|
||||
}
|
||||
} else {
|
||||
// In the case of ikey.sequence > sequence_, we might have already
|
||||
// iterated to a different user key.
|
||||
saved_key_valid = false;
|
||||
}
|
||||
num_skipped++;
|
||||
// If we have sequentially iterated via numerous keys and still not
|
||||
// found the prev user-key, then it is better to seek so that we can
|
||||
// avoid too many key comparisons. We seek to the first occurence of
|
||||
// our current key by looking for max sequence number.
|
||||
if (!saved_key_cleared && num_skipped > max_skip_) {
|
||||
if (saved_key_valid && num_skipped > max_skip_) {
|
||||
num_skipped = 0;
|
||||
std::string last_key;
|
||||
AppendInternalKey(&last_key,
|
||||
|
@ -1504,6 +1504,75 @@ TEST(DBTest, IterSeekBeforePrev) {
|
||||
delete iter;
|
||||
}
|
||||
|
||||
TEST(DBTest, IterNextWithNewerSeq) {
|
||||
ASSERT_OK(Put("0", "0"));
|
||||
dbfull()->Flush(FlushOptions());
|
||||
ASSERT_OK(Put("a", "b"));
|
||||
ASSERT_OK(Put("c", "d"));
|
||||
ASSERT_OK(Put("d", "e"));
|
||||
auto iter = db_->NewIterator(ReadOptions());
|
||||
|
||||
// Create a key that needs to be skipped for Seq too new
|
||||
for (uint64_t i = 0; i < last_options_.max_sequential_skip_in_iterations + 1;
|
||||
i++) {
|
||||
ASSERT_OK(Put("b", "f"));
|
||||
}
|
||||
|
||||
iter->Seek(Slice("a"));
|
||||
ASSERT_EQ(IterStatus(iter), "a->b");
|
||||
iter->Next();
|
||||
ASSERT_EQ(IterStatus(iter), "c->d");
|
||||
delete iter;
|
||||
}
|
||||
|
||||
TEST(DBTest, IterPrevWithNewerSeq) {
|
||||
ASSERT_OK(Put("0", "0"));
|
||||
dbfull()->Flush(FlushOptions());
|
||||
ASSERT_OK(Put("a", "b"));
|
||||
ASSERT_OK(Put("c", "d"));
|
||||
ASSERT_OK(Put("d", "e"));
|
||||
auto iter = db_->NewIterator(ReadOptions());
|
||||
|
||||
// Create a key that needs to be skipped for Seq too new
|
||||
for (uint64_t i = 0; i < last_options_.max_sequential_skip_in_iterations + 1;
|
||||
i++) {
|
||||
ASSERT_OK(Put("b", "f"));
|
||||
}
|
||||
|
||||
iter->Seek(Slice("d"));
|
||||
ASSERT_EQ(IterStatus(iter), "d->e");
|
||||
iter->Prev();
|
||||
ASSERT_EQ(IterStatus(iter), "c->d");
|
||||
iter->Prev();
|
||||
ASSERT_EQ(IterStatus(iter), "a->b");
|
||||
|
||||
iter->Prev();
|
||||
delete iter;
|
||||
}
|
||||
|
||||
TEST(DBTest, IterPrevWithNewerSeq2) {
|
||||
ASSERT_OK(Put("0", "0"));
|
||||
dbfull()->Flush(FlushOptions());
|
||||
ASSERT_OK(Put("a", "b"));
|
||||
ASSERT_OK(Put("c", "d"));
|
||||
ASSERT_OK(Put("d", "e"));
|
||||
auto iter = db_->NewIterator(ReadOptions());
|
||||
iter->Seek(Slice("c"));
|
||||
ASSERT_EQ(IterStatus(iter), "c->d");
|
||||
|
||||
// Create a key that needs to be skipped for Seq too new
|
||||
for (uint64_t i = 0; i < last_options_.max_sequential_skip_in_iterations + 1;
|
||||
i++) {
|
||||
ASSERT_OK(Put("b", "f"));
|
||||
}
|
||||
|
||||
iter->Prev();
|
||||
ASSERT_EQ(IterStatus(iter), "a->b");
|
||||
|
||||
iter->Prev();
|
||||
delete iter;
|
||||
}
|
||||
|
||||
TEST(DBTest, IterEmpty) {
|
||||
do {
|
||||
CreateAndReopenWithCF({"pikachu"});
|
||||
|
@ -451,7 +451,7 @@ TEST(LogTest, TruncatedTrailingRecordIsIgnored) {
|
||||
ShrinkSize(4); // Drop all payload as well as a header byte
|
||||
ASSERT_EQ("EOF", Read());
|
||||
// Truncated last record is ignored, not treated as an error
|
||||
ASSERT_EQ(0, DroppedBytes());
|
||||
ASSERT_EQ(0U, DroppedBytes());
|
||||
ASSERT_EQ("", ReportMessage());
|
||||
}
|
||||
|
||||
@ -470,7 +470,7 @@ TEST(LogTest, BadLengthAtEndIsIgnored) {
|
||||
Write("foo");
|
||||
ShrinkSize(1);
|
||||
ASSERT_EQ("EOF", Read());
|
||||
ASSERT_EQ(0, DroppedBytes());
|
||||
ASSERT_EQ(0U, DroppedBytes());
|
||||
ASSERT_EQ("", ReportMessage());
|
||||
}
|
||||
|
||||
@ -528,7 +528,7 @@ TEST(LogTest, MissingLastIsIgnored) {
|
||||
ShrinkSize(14);
|
||||
ASSERT_EQ("EOF", Read());
|
||||
ASSERT_EQ("", ReportMessage());
|
||||
ASSERT_EQ(0, DroppedBytes());
|
||||
ASSERT_EQ(0U, DroppedBytes());
|
||||
}
|
||||
|
||||
TEST(LogTest, PartialLastIsIgnored) {
|
||||
@ -537,7 +537,7 @@ TEST(LogTest, PartialLastIsIgnored) {
|
||||
ShrinkSize(1);
|
||||
ASSERT_EQ("EOF", Read());
|
||||
ASSERT_EQ("", ReportMessage());
|
||||
ASSERT_EQ(0, DroppedBytes());
|
||||
ASSERT_EQ(0U, DroppedBytes());
|
||||
}
|
||||
|
||||
TEST(LogTest, ErrorJoinsRecords) {
|
||||
|
@ -972,10 +972,10 @@ class StressTest {
|
||||
prefixes[i].resize(FLAGS_prefix_size);
|
||||
prefix_slices[i] = Slice(prefixes[i]);
|
||||
readoptionscopy[i] = readoptions;
|
||||
readoptionscopy[i].prefix = &prefix_slices[i];
|
||||
readoptionscopy[i].prefix_seek = true;
|
||||
readoptionscopy[i].snapshot = snapshot;
|
||||
iters[i] = db_->NewIterator(readoptionscopy[i], column_family);
|
||||
iters[i]->SeekToFirst();
|
||||
iters[i]->Seek(prefix_slices[i]);
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
@ -1157,11 +1157,11 @@ class StressTest {
|
||||
// prefix
|
||||
if (!FLAGS_test_batches_snapshots) {
|
||||
Slice prefix = Slice(key.data(), FLAGS_prefix_size);
|
||||
read_opts.prefix = &prefix;
|
||||
read_opts.prefix_seek = true;
|
||||
Iterator* iter = db_->NewIterator(read_opts, column_family);
|
||||
int64_t count = 0;
|
||||
for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {
|
||||
assert(iter->key().starts_with(prefix));
|
||||
for (iter->Seek(prefix);
|
||||
iter->Valid() && iter->key().starts_with(prefix); iter->Next()) {
|
||||
++count;
|
||||
}
|
||||
assert(count <=
|
||||
@ -1175,7 +1175,6 @@ class StressTest {
|
||||
} else {
|
||||
MultiPrefixScan(thread, read_opts, column_family, key);
|
||||
}
|
||||
read_opts.prefix = nullptr;
|
||||
} else if (prefixBound <= prob_op && prob_op < writeBound) {
|
||||
// OPERATION write
|
||||
uint32_t value_base = thread->rand.Next();
|
||||
|
@ -172,8 +172,8 @@ TEST(EnvPosixTest, TwoPools) {
|
||||
env_->SetBackgroundThreads(kLowPoolSize);
|
||||
env_->SetBackgroundThreads(kHighPoolSize, Env::Priority::HIGH);
|
||||
|
||||
ASSERT_EQ(0, env_->GetThreadPoolQueueLen(Env::Priority::LOW));
|
||||
ASSERT_EQ(0, env_->GetThreadPoolQueueLen(Env::Priority::HIGH));
|
||||
ASSERT_EQ(0U, env_->GetThreadPoolQueueLen(Env::Priority::LOW));
|
||||
ASSERT_EQ(0U, env_->GetThreadPoolQueueLen(Env::Priority::HIGH));
|
||||
|
||||
// schedule same number of jobs in each pool
|
||||
for (int i = 0; i < kJobs; i++) {
|
||||
@ -182,10 +182,11 @@ TEST(EnvPosixTest, TwoPools) {
|
||||
}
|
||||
// Wait a short while for the jobs to be dispatched.
|
||||
Env::Default()->SleepForMicroseconds(kDelayMicros);
|
||||
ASSERT_EQ(kJobs - kLowPoolSize, env_->GetThreadPoolQueueLen());
|
||||
ASSERT_EQ(kJobs - kLowPoolSize,
|
||||
ASSERT_EQ((unsigned int)(kJobs - kLowPoolSize),
|
||||
env_->GetThreadPoolQueueLen());
|
||||
ASSERT_EQ((unsigned int)(kJobs - kLowPoolSize),
|
||||
env_->GetThreadPoolQueueLen(Env::Priority::LOW));
|
||||
ASSERT_EQ(kJobs - kHighPoolSize,
|
||||
ASSERT_EQ((unsigned int)(kJobs - kHighPoolSize),
|
||||
env_->GetThreadPoolQueueLen(Env::Priority::HIGH));
|
||||
|
||||
// wait for all jobs to finish
|
||||
@ -194,8 +195,8 @@ TEST(EnvPosixTest, TwoPools) {
|
||||
env_->SleepForMicroseconds(kDelayMicros);
|
||||
}
|
||||
|
||||
ASSERT_EQ(0, env_->GetThreadPoolQueueLen(Env::Priority::LOW));
|
||||
ASSERT_EQ(0, env_->GetThreadPoolQueueLen(Env::Priority::HIGH));
|
||||
ASSERT_EQ(0U, env_->GetThreadPoolQueueLen(Env::Priority::LOW));
|
||||
ASSERT_EQ(0U, env_->GetThreadPoolQueueLen(Env::Priority::HIGH));
|
||||
}
|
||||
|
||||
bool IsSingleVarint(const std::string& s) {
|
||||
@ -296,18 +297,18 @@ TEST(EnvPosixTest, AllocateTest) {
|
||||
|
||||
struct stat f_stat;
|
||||
stat(fname.c_str(), &f_stat);
|
||||
ASSERT_EQ(data.size(), f_stat.st_size);
|
||||
ASSERT_EQ((unsigned int)data.size(), f_stat.st_size);
|
||||
// verify that blocks are preallocated
|
||||
ASSERT_EQ(kPreallocateSize / kBlockSize, f_stat.st_blocks);
|
||||
ASSERT_EQ((unsigned int)(kPreallocateSize / kBlockSize), f_stat.st_blocks);
|
||||
|
||||
// close the file, should deallocate the blocks
|
||||
wfile.reset();
|
||||
|
||||
stat(fname.c_str(), &f_stat);
|
||||
ASSERT_EQ(data.size(), f_stat.st_size);
|
||||
ASSERT_EQ((unsigned int)data.size(), f_stat.st_size);
|
||||
// verify that preallocated blocks were deallocated on file close
|
||||
size_t data_blocks_pages = ((data.size() + kPageSize - 1) / kPageSize);
|
||||
ASSERT_EQ(data_blocks_pages * kPageSize / kBlockSize, f_stat.st_blocks);
|
||||
ASSERT_EQ((unsigned int)(data_blocks_pages * kPageSize / kBlockSize), f_stat.st_blocks);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user