Fix index seeking in BlockTableReader::PrefixMayMatch.
PrefixMayMatch previously seeked in the prefix index using an internal key with a sequence number of 0. This would cause the prefix index seek to fall off the end if the last key in the index had a user-key greater than or equal to the key being looked for. Falling off the end of the index in turn results in PrefixMayMatch returning false if the index is in memory.
This commit is contained in:
parent
eb965e1bc3
commit
2d8fa53ffb
@ -1119,7 +1119,7 @@ bool BlockBasedTable::PrefixMayMatch(const Slice& internal_key) {
|
||||
assert(rep_->ioptions.prefix_extractor != nullptr);
|
||||
auto prefix = rep_->ioptions.prefix_extractor->Transform(
|
||||
ExtractUserKey(internal_key));
|
||||
InternalKey internal_key_prefix(prefix, 0, kTypeValue);
|
||||
InternalKey internal_key_prefix(prefix, kMaxSequenceNumber, kTypeValue);
|
||||
auto internal_prefix = internal_key_prefix.Encode();
|
||||
|
||||
bool may_match = true;
|
||||
|
@ -1242,6 +1242,40 @@ TEST_F(BlockBasedTableTest, TotalOrderSeekOnHashIndex) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(BlockBasedTableTest, NoopTransformSeek) {
|
||||
BlockBasedTableOptions table_options;
|
||||
table_options.filter_policy.reset(NewBloomFilterPolicy(10));
|
||||
|
||||
Options options;
|
||||
options.comparator = BytewiseComparator();
|
||||
options.table_factory.reset(new BlockBasedTableFactory(table_options));
|
||||
options.prefix_extractor.reset(NewNoopTransform());
|
||||
|
||||
TableConstructor c(options.comparator);
|
||||
// To tickle the PrefixMayMatch bug it is important that the
|
||||
// user-key is a single byte so that the index key exactly matches
|
||||
// the user-key.
|
||||
InternalKey key("a", 1, kTypeValue);
|
||||
c.Add(key.Encode().ToString(), "b");
|
||||
std::vector<std::string> keys;
|
||||
stl_wrappers::KVMap kvmap;
|
||||
const ImmutableCFOptions ioptions(options);
|
||||
c.Finish(options, ioptions, table_options,
|
||||
InternalKeyComparator(options.comparator), &keys, &kvmap);
|
||||
|
||||
auto* reader = c.GetTableReader();
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
ReadOptions ro;
|
||||
ro.total_order_seek = (i == 0);
|
||||
std::unique_ptr<InternalIterator> iter(reader->NewIterator(ro));
|
||||
|
||||
iter->Seek(key.Encode());
|
||||
ASSERT_OK(iter->status());
|
||||
ASSERT_TRUE(iter->Valid());
|
||||
ASSERT_EQ("a", ExtractUserKey(iter->key()).ToString());
|
||||
}
|
||||
}
|
||||
|
||||
static std::string RandomString(Random* rnd, int len) {
|
||||
std::string r;
|
||||
test::RandomString(rnd, len, &r);
|
||||
|
Loading…
Reference in New Issue
Block a user