Fix wrong ExtractUserKey usage in BlockBasedTableBuilder::EnterUnbuff… (#6100)
Summary: BlockBasedTableBuilder uses ExtractUserKey in EnterUnbuffered. This would cause index filter building error, since user-provided timestamp is supported by ExtractUserKeyAndStripTimestamp, and it's used in Add. This commit changes ExtractUserKey to ExtractUserKeyAndStripTimestamp. A test case is also added by modifying DBBasicTestWithTimestampWithParam_ PutAndGet test in db_basic_test to cover ExtractUserKeyAndStripTimestamp usage in both kBuffered and kUnbuffered state of BlockBasedTableBuilder. Before the ExtractUserKeyAndStripTimstamp fix: ``` $ ./db_basic_test --gtest_filter="*PutAndGet*" Note: Google Test filter = *PutAndGet* [==========] Running 2 tests from 1 test case. [----------] Global test environment set-up. [----------] 2 tests from Timestamp/DBBasicTestWithTimestampWithParam [ RUN ] Timestamp/DBBasicTestWithTimestampWithParam.PutAndGet/0 db/db_basic_test.cc:2109: Failure db_->Get(ropts, cfh, "key" + std::to_string(j), &value) NotFound: db/db_basic_test.cc:2109: Failure db_->Get(ropts, cfh, "key" + std::to_string(j), &value) NotFound: db/db_basic_test.cc:2109: Failure db_->Get(ropts, cfh, "key" + std::to_string(j), &value) NotFound: db/db_basic_test.cc:2109: Failure db_->Get(ropts, cfh, "key" + std::to_string(j), &value) NotFound: db/db_basic_test.cc:2109: Failure db_->Get(ropts, cfh, "key" + std::to_string(j), &value) NotFound: [ FAILED ] Timestamp/DBBasicTestWithTimestampWithParam.PutAndGet/0, where GetParam() = false (1177 ms) [ RUN ] Timestamp/DBBasicTestWithTimestampWithParam.PutAndGet/1 [ OK ] Timestamp/DBBasicTestWithTimestampWithParam.PutAndGet/1 (1056 ms) [----------] 2 tests from Timestamp/DBBasicTestWithTimestampWithParam (2233 ms total) [----------] Global test environment tear-down [==========] 2 tests from 1 test case ran. (2233 ms total) [ PASSED ] 1 test. [ FAILED ] 1 test, listed below: [ FAILED ] Timestamp/DBBasicTestWithTimestampWithParam.PutAndGet/0, where GetParam() = false 1 FAILED TEST ``` After the ExtractUserKeyAndStripTimstamp fix: ``` $ ./db_basic_test --gtest_filter="*PutAndGet*" Note: Google Test filter = *PutAndGet* [==========] Running 2 tests from 1 test case. [----------] Global test environment set-up. [----------] 2 tests from Timestamp/DBBasicTestWithTimestampWithParam [ RUN ] Timestamp/DBBasicTestWithTimestampWithParam.PutAndGet/0 [ OK ] Timestamp/DBBasicTestWithTimestampWithParam.PutAndGet/0 (1417 ms) [ RUN ] Timestamp/DBBasicTestWithTimestampWithParam.PutAndGet/1 [ OK ] Timestamp/DBBasicTestWithTimestampWithParam.PutAndGet/1 (1041 ms) [----------] 2 tests from Timestamp/DBBasicTestWithTimestampWithParam (2458 ms total) [----------] Global test environment tear-down [==========] 2 tests from 1 test case ran. (2458 ms total) [ PASSED ] 2 tests. ``` Pull Request resolved: https://github.com/facebook/rocksdb/pull/6100 Differential Revision: D18769654 Pulled By: riversand963 fbshipit-source-id: 76c2cf2c9a5e0d85db95d98e812e6af0c2a15c6b
This commit is contained in:
parent
d1ae2c3faf
commit
7e2f831924
@ -2045,48 +2045,77 @@ TEST_P(DBBasicTestWithTimestampWithParam, PutAndGet) {
|
|||||||
10 /*bits_per_key*/, false /*use_block_based_builder*/));
|
10 /*bits_per_key*/, false /*use_block_based_builder*/));
|
||||||
bbto.whole_key_filtering = true;
|
bbto.whole_key_filtering = true;
|
||||||
options.table_factory.reset(NewBlockBasedTableFactory(bbto));
|
options.table_factory.reset(NewBlockBasedTableFactory(bbto));
|
||||||
DestroyAndReopen(options);
|
|
||||||
CreateAndReopenWithCF({"pikachu"}, options);
|
|
||||||
size_t num_cfs = handles_.size();
|
|
||||||
ASSERT_EQ(2, num_cfs);
|
|
||||||
std::vector<std::string> write_ts_strs(kNumTimestamps);
|
|
||||||
std::vector<std::string> read_ts_strs(kNumTimestamps);
|
|
||||||
std::vector<Slice> write_ts_list;
|
|
||||||
std::vector<Slice> read_ts_list;
|
|
||||||
|
|
||||||
for (size_t i = 0; i != kNumTimestamps; ++i) {
|
std::vector<CompressionType> compression_types;
|
||||||
write_ts_list.emplace_back(EncodeTimestamp(i * 2, 0, &write_ts_strs[i]));
|
compression_types.push_back(kNoCompression);
|
||||||
read_ts_list.emplace_back(EncodeTimestamp(1 + i * 2, 0, &read_ts_strs[i]));
|
if (Zlib_Supported()) {
|
||||||
const Slice& write_ts = write_ts_list.back();
|
compression_types.push_back(kZlibCompression);
|
||||||
WriteOptions wopts;
|
|
||||||
wopts.timestamp = &write_ts;
|
|
||||||
for (int cf = 0; cf != static_cast<int>(num_cfs); ++cf) {
|
|
||||||
for (size_t j = 0; j != (kNumKeysPerFile - 1) / kNumTimestamps; ++j) {
|
|
||||||
ASSERT_OK(Put(cf, "key" + std::to_string(j),
|
|
||||||
"value_" + std::to_string(j) + "_" + std::to_string(i),
|
|
||||||
wopts));
|
|
||||||
}
|
|
||||||
if (!memtable_only) {
|
|
||||||
ASSERT_OK(Flush(cf));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
const auto& verify_db_func = [&]() {
|
#if LZ4_VERSION_NUMBER >= 10400 // r124+
|
||||||
for (size_t i = 0; i != kNumTimestamps; ++i) {
|
compression_types.push_back(kLZ4Compression);
|
||||||
ReadOptions ropts;
|
compression_types.push_back(kLZ4HCCompression);
|
||||||
ropts.timestamp = &read_ts_list[i];
|
#endif // LZ4_VERSION_NUMBER >= 10400
|
||||||
for (int cf = 0; cf != static_cast<int>(num_cfs); ++cf) {
|
if (ZSTD_Supported()) {
|
||||||
ColumnFamilyHandle* cfh = handles_[cf];
|
compression_types.push_back(kZSTD);
|
||||||
for (size_t j = 0; j != (kNumKeysPerFile - 1) / kNumTimestamps; ++j) {
|
}
|
||||||
std::string value;
|
|
||||||
ASSERT_OK(db_->Get(ropts, cfh, "key" + std::to_string(j), &value));
|
// Switch compression dictionary on/off to check key extraction
|
||||||
ASSERT_EQ("value_" + std::to_string(j) + "_" + std::to_string(i),
|
// correctness in kBuffered state
|
||||||
value);
|
std::vector<uint32_t> max_dict_bytes_list = {0, 1 << 14}; // 0 or 16KB
|
||||||
|
|
||||||
|
for (auto compression_type : compression_types) {
|
||||||
|
for (uint32_t max_dict_bytes : max_dict_bytes_list) {
|
||||||
|
options.compression = compression_type;
|
||||||
|
options.compression_opts.max_dict_bytes = max_dict_bytes;
|
||||||
|
if (compression_type == kZSTD) {
|
||||||
|
options.compression_opts.zstd_max_train_bytes = max_dict_bytes;
|
||||||
|
}
|
||||||
|
options.target_file_size_base = 1 << 26; // 64MB
|
||||||
|
|
||||||
|
DestroyAndReopen(options);
|
||||||
|
CreateAndReopenWithCF({"pikachu"}, options);
|
||||||
|
size_t num_cfs = handles_.size();
|
||||||
|
ASSERT_EQ(2, num_cfs);
|
||||||
|
std::vector<std::string> write_ts_strs(kNumTimestamps);
|
||||||
|
std::vector<std::string> read_ts_strs(kNumTimestamps);
|
||||||
|
std::vector<Slice> write_ts_list;
|
||||||
|
std::vector<Slice> read_ts_list;
|
||||||
|
|
||||||
|
for (size_t i = 0; i != kNumTimestamps; ++i) {
|
||||||
|
write_ts_list.emplace_back(EncodeTimestamp(i * 2, 0, &write_ts_strs[i]));
|
||||||
|
read_ts_list.emplace_back(EncodeTimestamp(1 + i * 2, 0, &read_ts_strs[i]));
|
||||||
|
const Slice& write_ts = write_ts_list.back();
|
||||||
|
WriteOptions wopts;
|
||||||
|
wopts.timestamp = &write_ts;
|
||||||
|
for (int cf = 0; cf != static_cast<int>(num_cfs); ++cf) {
|
||||||
|
for (size_t j = 0; j != (kNumKeysPerFile - 1) / kNumTimestamps; ++j) {
|
||||||
|
ASSERT_OK(Put(cf, "key" + std::to_string(j),
|
||||||
|
"value_" + std::to_string(j) + "_" + std::to_string(i),
|
||||||
|
wopts));
|
||||||
|
}
|
||||||
|
if (!memtable_only) {
|
||||||
|
ASSERT_OK(Flush(cf));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const auto& verify_db_func = [&]() {
|
||||||
|
for (size_t i = 0; i != kNumTimestamps; ++i) {
|
||||||
|
ReadOptions ropts;
|
||||||
|
ropts.timestamp = &read_ts_list[i];
|
||||||
|
for (int cf = 0; cf != static_cast<int>(num_cfs); ++cf) {
|
||||||
|
ColumnFamilyHandle* cfh = handles_[cf];
|
||||||
|
for (size_t j = 0; j != (kNumKeysPerFile - 1) / kNumTimestamps; ++j) {
|
||||||
|
std::string value;
|
||||||
|
ASSERT_OK(db_->Get(ropts, cfh, "key" + std::to_string(j), &value));
|
||||||
|
ASSERT_EQ("value_" + std::to_string(j) + "_" + std::to_string(i),
|
||||||
|
value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
verify_db_func();
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
verify_db_func();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(Timestamp, DBBasicTestWithTimestampWithParam,
|
INSTANTIATE_TEST_CASE_P(Timestamp, DBBasicTestWithTimestampWithParam,
|
||||||
|
@ -1108,7 +1108,8 @@ void BlockBasedTableBuilder::EnterUnbuffered() {
|
|||||||
|
|
||||||
for (const auto& key : keys) {
|
for (const auto& key : keys) {
|
||||||
if (r->filter_builder != nullptr) {
|
if (r->filter_builder != nullptr) {
|
||||||
r->filter_builder->Add(ExtractUserKey(key));
|
size_t ts_sz = r->internal_comparator.user_comparator()->timestamp_size();
|
||||||
|
r->filter_builder->Add(ExtractUserKeyAndStripTimestamp(key, ts_sz));
|
||||||
}
|
}
|
||||||
r->index_builder->OnKeyAdded(key);
|
r->index_builder->OnKeyAdded(key);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user