]> git-server-git.apps.pok.os.sepia.ceph.com Git - rocksdb.git/commitdiff
Fix index seeking in BlockTableReader::PrefixMayMatch.
authorPeter Mattis <petermattis@gmail.com>
Wed, 6 Jan 2016 19:46:32 +0000 (14:46 -0500)
committerIslam AbdelRahman <tec@fb.com>
Wed, 27 Jan 2016 02:44:47 +0000 (18:44 -0800)
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.

table/block_based_table_reader.cc
table/table_test.cc

index ad383726a83171be60fa52cf0fd4f36c3c13d9e5..0c433616188b7141910e6770e86e8170b5f75440 100644 (file)
@@ -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;
index 58607bbb2c4360b0baa23567e6e77c1123ef15e3..8f1380e0ea5a412de3ed1178b5125c614a20eba0 100644 (file)
@@ -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);