db_stress to cover upper bound in iterators (#4162)

Summary:
db_stress doesn't cover upper or lower bound in iterators. Try to cover it by randomly assigning a random one. Also in prefix scan tests, with 50% of the chance, set next prefix as the upper bound.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/4162

Differential Revision: D8953507

Pulled By: siying

fbshipit-source-id: f0f04e9cb6c07cbebbb82b892ca23e0daeea708b
main
Siying Dong 6 years ago committed by Facebook Github Bot
parent f95a5b2464
commit 4b0a43574a
  1. 5
      tools/db_crashtest.py
  2. 61
      tools/db_stress.cc

@ -103,9 +103,8 @@ simple_default_params = {
"max_background_compactions": 1, "max_background_compactions": 1,
"max_bytes_for_level_base": 67108864, "max_bytes_for_level_base": 67108864,
"memtablerep": "skip_list", "memtablerep": "skip_list",
"prefix_size": 0, "prefixpercent": 25,
"prefixpercent": 0, "readpercent": 25,
"readpercent": 50,
"target_file_size_base": 16777216, "target_file_size_base": 16777216,
"target_file_size_multiplier": 1, "target_file_size_multiplier": 1,
"test_batches_snapshots": 0, "test_batches_snapshots": 0,

@ -579,6 +579,23 @@ enum RepFactory StringToRepFactory(const char* ctype) {
fprintf(stdout, "Cannot parse memreptable %s\n", ctype); fprintf(stdout, "Cannot parse memreptable %s\n", ctype);
return kSkipList; return kSkipList;
} }
bool GetNextPrefix(const rocksdb::Slice& src, std::string* v) {
std::string ret = src.ToString();
for (int i = static_cast<int>(ret.size()) - 1; i >= 0; i--) {
if (ret[i] != static_cast<char>(255)) {
ret[i] = ret[i] + 1;
break;
} else if (i != 0) {
ret[i] = 0;
} else {
// all FF. No next prefix
return false;
}
}
*v = ret;
return true;
}
} // namespace } // namespace
static enum RepFactory FLAGS_rep_factory; static enum RepFactory FLAGS_rep_factory;
@ -2022,6 +2039,30 @@ class StressTest {
const Snapshot* snapshot = db_->GetSnapshot(); const Snapshot* snapshot = db_->GetSnapshot();
ReadOptions readoptionscopy = read_opts; ReadOptions readoptionscopy = read_opts;
readoptionscopy.snapshot = snapshot; readoptionscopy.snapshot = snapshot;
std::string upper_bound_str;
Slice upper_bound;
if (thread->rand.OneIn(16)) {
// in 1/16 chance, set a iterator upper bound
int64_t rand_upper_key = GenerateOneKey(thread, FLAGS_ops_per_thread);
upper_bound_str = Key(rand_upper_key);
upper_bound = Slice(upper_bound_str);
// uppder_bound can be smaller than seek key, but the query itself
// should not crash either.
readoptionscopy.iterate_upper_bound = &upper_bound;
}
std::string lower_bound_str;
Slice lower_bound;
if (thread->rand.OneIn(16)) {
// in 1/16 chance, set a iterator lower bound
int64_t rand_lower_key = GenerateOneKey(thread, FLAGS_ops_per_thread);
lower_bound_str = Key(rand_lower_key);
lower_bound = Slice(lower_bound_str);
// uppder_bound can be smaller than seek key, but the query itself
// should not crash either.
readoptionscopy.iterate_lower_bound = &lower_bound;
}
auto cfh = column_families_[rand_column_families[0]]; auto cfh = column_families_[rand_column_families[0]];
std::unique_ptr<Iterator> iter(db_->NewIterator(readoptionscopy, cfh)); std::unique_ptr<Iterator> iter(db_->NewIterator(readoptionscopy, cfh));
@ -2564,7 +2605,17 @@ class NonBatchedOpsStressTest : public StressTest {
std::string key_str = Key(rand_keys[0]); std::string key_str = Key(rand_keys[0]);
Slice key = key_str; Slice key = key_str;
Slice prefix = Slice(key.data(), FLAGS_prefix_size); Slice prefix = Slice(key.data(), FLAGS_prefix_size);
Iterator* iter = db_->NewIterator(read_opts, cfh);
std::string upper_bound;
Slice ub_slice;
ReadOptions ro_copy = read_opts;
if (thread->rand.OneIn(2) && GetNextPrefix(prefix, &upper_bound)) {
// For half of the time, set the upper bound to the next prefix
ub_slice = Slice(upper_bound);
ro_copy.iterate_upper_bound = &ub_slice;
}
Iterator* iter = db_->NewIterator(ro_copy, cfh);
int64_t count = 0; int64_t count = 0;
for (iter->Seek(prefix); for (iter->Seek(prefix);
iter->Valid() && iter->key().starts_with(prefix); iter->Next()) { iter->Valid() && iter->key().starts_with(prefix); iter->Next()) {
@ -3085,6 +3136,8 @@ class BatchedOpsStressTest : public StressTest {
ReadOptions readoptionscopy[10]; ReadOptions readoptionscopy[10];
const Snapshot* snapshot = db_->GetSnapshot(); const Snapshot* snapshot = db_->GetSnapshot();
Iterator* iters[10]; Iterator* iters[10];
std::string upper_bounds[10];
Slice ub_slices[10];
Status s = Status::OK(); Status s = Status::OK();
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
prefixes[i] += key.ToString(); prefixes[i] += key.ToString();
@ -3092,6 +3145,12 @@ class BatchedOpsStressTest : public StressTest {
prefix_slices[i] = Slice(prefixes[i]); prefix_slices[i] = Slice(prefixes[i]);
readoptionscopy[i] = readoptions; readoptionscopy[i] = readoptions;
readoptionscopy[i].snapshot = snapshot; readoptionscopy[i].snapshot = snapshot;
if (thread->rand.OneIn(2) &&
GetNextPrefix(prefix_slices[i], &(upper_bounds[i]))) {
// For half of the time, set the upper bound to the next prefix
ub_slices[i] = Slice(upper_bounds[i]);
readoptionscopy[i].iterate_upper_bound = &(ub_slices[i]);
}
iters[i] = db_->NewIterator(readoptionscopy[i], cfh); iters[i] = db_->NewIterator(readoptionscopy[i], cfh);
iters[i]->Seek(prefix_slices[i]); iters[i]->Seek(prefix_slices[i]);
} }

Loading…
Cancel
Save