From: Peter Mattis Date: Wed, 6 Jan 2016 19:46:32 +0000 (-0500) Subject: Fix index seeking in BlockTableReader::PrefixMayMatch. X-Git-Tag: rocksdb-4.3~4 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=2d8fa53ffb7e78466eb82c7344a3a58b40f30de1;p=rocksdb.git 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. --- diff --git a/table/block_based_table_reader.cc b/table/block_based_table_reader.cc index ad383726a..0c4336161 100644 --- a/table/block_based_table_reader.cc +++ b/table/block_based_table_reader.cc @@ -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; diff --git a/table/table_test.cc b/table/table_test.cc index 58607bbb2..8f1380e0e 100644 --- a/table/table_test.cc +++ b/table/table_test.cc @@ -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 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 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);