diff --git a/HISTORY.md b/HISTORY.md index 831d3ccb1..ca65e8c18 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -9,6 +9,7 @@ * Column family support ### Public API changes +* Deprecated ReadOptions.prefix and ReadOptions.prefix_seek. Seek() defaults to prefix-based seek when Options.prefix_extractor is supplied. More detail is documented in https://github.com/facebook/rocksdb/wiki/Prefix-Seek-API-Changes ## 2.8.0 (04/04/2014) diff --git a/db/c.cc b/db/c.cc index e3a0a29a0..915a3e80e 100644 --- a/db/c.cc +++ b/db/c.cc @@ -1230,23 +1230,12 @@ void rocksdb_readoptions_set_fill_cache( opt->rep.fill_cache = v; } -void rocksdb_readoptions_set_prefix_seek( - rocksdb_readoptions_t* opt, unsigned char v) { - opt->rep.prefix_seek = v; -} - void rocksdb_readoptions_set_snapshot( rocksdb_readoptions_t* opt, const rocksdb_snapshot_t* snap) { opt->rep.snapshot = (snap ? snap->rep : nullptr); } -void rocksdb_readoptions_set_prefix( - rocksdb_readoptions_t* opt, const char* key, size_t keylen) { - Slice prefix = Slice(key, keylen); - opt->rep.prefix = &prefix; -} - void rocksdb_readoptions_set_read_tier( rocksdb_readoptions_t* opt, int v) { opt->rep.read_tier = static_cast(v); diff --git a/db/c_test.c b/db/c_test.c index cd9299bec..8ebce9085 100644 --- a/db/c_test.c +++ b/db/c_test.c @@ -461,8 +461,6 @@ int main(int argc, char** argv) { rocksdb_put(db, woptions, "bar3", 4, "bar", 3, &err); CheckNoError(err); - rocksdb_readoptions_set_prefix_seek(roptions, 1); - rocksdb_iterator_t* iter = rocksdb_create_iterator(db, roptions); CheckCondition(!rocksdb_iter_valid(iter)); diff --git a/db/db_bench.cc b/db/db_bench.cc index 2b52032ca..345821596 100644 --- a/db/db_bench.cc +++ b/db/db_bench.cc @@ -1944,7 +1944,6 @@ class Benchmark { void IteratorCreation(ThreadState* thread) { Duration duration(FLAGS_duration, reads_); ReadOptions options(FLAGS_verify_checksum, true); - options.prefix_seek = (FLAGS_prefix_size > 0); while (!duration.Done(1)) { DB* db = SelectDB(thread); Iterator* iter = db->NewIterator(options); @@ -1966,7 +1965,6 @@ class Benchmark { int64_t found = 0; ReadOptions options(FLAGS_verify_checksum, true); options.tailing = FLAGS_use_tailing_iterator; - options.prefix_seek = (FLAGS_prefix_size > 0); Iterator* single_iter = nullptr; std::vector multi_iters; diff --git a/db/db_impl.cc b/db/db_impl.cc index 2dd1455ff..3aa2a2256 100644 --- a/db/db_impl.cc +++ b/db/db_impl.cc @@ -33,7 +33,6 @@ #include "db/memtable_list.h" #include "db/merge_context.h" #include "db/merge_helper.h" -#include "db/prefix_filter_iterator.h" #include "db/table_cache.h" #include "db/table_properties_collector.h" #include "db/tailing_iter.h" @@ -1339,7 +1338,7 @@ Status DBImpl::WriteLevel0TableForRecovery(ColumnFamilyData* cfd, MemTable* mem, FileMetaData meta; meta.number = versions_->NewFileNumber(); pending_outputs_.insert(meta.number); - Iterator* iter = mem->NewIterator(); + Iterator* iter = mem->NewIterator(ReadOptions(), true); const SequenceNumber newest_snapshot = snapshots_.GetNewest(); const SequenceNumber earliest_seqno_in_memtable = mem->GetFirstSequenceNumber(); @@ -1405,7 +1404,7 @@ Status DBImpl::WriteLevel0Table(ColumnFamilyData* cfd, for (MemTable* m : mems) { Log(options_.info_log, "[%s] Flushing memtable with next log file: %lu\n", cfd->GetName().c_str(), (unsigned long)m->GetNextLogNumber()); - memtables.push_back(m->NewIterator()); + memtables.push_back(m->NewIterator(ReadOptions(), true)); } Iterator* iter = NewMergingIterator(&cfd->internal_comparator(), &memtables[0], memtables.size()); @@ -3494,12 +3493,6 @@ Iterator* DBImpl::NewIterator(const ReadOptions& options, cfd->user_comparator(), iter, snapshot); } - if (options.prefix) { - // use extra wrapper to exclude any keys from the results which - // don't begin with the prefix - iter = new PrefixFilterIterator(iter, *options.prefix, - cfd->options()->prefix_extractor.get()); - } return iter; } @@ -3507,12 +3500,6 @@ Status DBImpl::NewIterators( const ReadOptions& options, const std::vector& column_families, std::vector* iterators) { - - if (options.prefix) { - return Status::NotSupported( - "NewIterators doesn't support ReadOptions::prefix"); - } - iterators->clear(); iterators->reserve(column_families.size()); SequenceNumber latest_snapshot = 0; diff --git a/db/db_impl_debug.cc b/db/db_impl_debug.cc index 346692beb..3dcde6c40 100644 --- a/db/db_impl_debug.cc +++ b/db/db_impl_debug.cc @@ -33,7 +33,6 @@ Iterator* DBImpl::TEST_NewInternalIterator(ColumnFamilyHandle* column_family) { SuperVersion* super_version = cfd->GetSuperVersion()->Ref(); mutex_.Unlock(); ReadOptions roptions; - roptions.prefix_seek = true; return NewInternalIterator(roptions, cfd, super_version); } diff --git a/db/db_test.cc b/db/db_test.cc index 5a84484fc..474ce4668 100644 --- a/db/db_test.cc +++ b/db/db_test.cc @@ -306,7 +306,8 @@ class DBTest { kSkipUniversalCompaction = 2, kSkipMergePut = 4, kSkipPlainTable = 8, - kSkipHashIndex = 16 + kSkipHashIndex = 16, + kSkipNoSeekToLast = 32 }; DBTest() : option_config_(kDefault), @@ -341,6 +342,11 @@ class DBTest { if ((skip_mask & kSkipMergePut) && option_config_ == kMergePut) { continue; } + if ((skip_mask & kSkipNoSeekToLast) && + (option_config_ == kHashLinkList || + option_config_ == kHashSkipList)) {; + continue; + } if ((skip_mask & kSkipPlainTable) && (option_config_ == kPlainTableAllBytesPrefix || option_config_ == kPlainTableFirstBytePrefix)) { @@ -862,10 +868,11 @@ class DBTest { void VerifyIterLast(std::string expected_key, int cf = 0) { Iterator* iter; + ReadOptions ro; if (cf == 0) { - iter = db_->NewIterator(ReadOptions()); + iter = db_->NewIterator(ro); } else { - iter = db_->NewIterator(ReadOptions(), handles_[cf]); + iter = db_->NewIterator(ro, handles_[cf]); } iter->SeekToLast(); ASSERT_EQ(IterStatus(iter), expected_key); @@ -1463,7 +1470,7 @@ TEST(DBTest, NonBlockingIteration) { // This test verifies block cache behaviors, which is not used by plain // table format. - } while (ChangeOptions(kSkipPlainTable)); + } while (ChangeOptions(kSkipPlainTable | kSkipNoSeekToLast)); } // A delete is skipped for key if KeyMayExist(key) returns False @@ -1907,19 +1914,23 @@ TEST(DBTest, IterSmallAndLargeMix) { TEST(DBTest, IterMultiWithDelete) { do { CreateAndReopenWithCF({"pikachu"}); - ASSERT_OK(Put(1, "a", "va")); - ASSERT_OK(Put(1, "b", "vb")); - ASSERT_OK(Put(1, "c", "vc")); - ASSERT_OK(Delete(1, "b")); - ASSERT_EQ("NOT_FOUND", Get(1, "b")); + ASSERT_OK(Put(1, "ka", "va")); + ASSERT_OK(Put(1, "kb", "vb")); + ASSERT_OK(Put(1, "kc", "vc")); + ASSERT_OK(Delete(1, "kb")); + ASSERT_EQ("NOT_FOUND", Get(1, "kb")); Iterator* iter = db_->NewIterator(ReadOptions(), handles_[1]); - iter->Seek("c"); - ASSERT_EQ(IterStatus(iter), "c->vc"); + iter->Seek("kc"); + ASSERT_EQ(IterStatus(iter), "kc->vc"); if (!CurrentOptions().merge_operator) { // TODO: merge operator does not support backward iteration yet - iter->Prev(); - ASSERT_EQ(IterStatus(iter), "a->va"); + if (kPlainTableAllBytesPrefix != option_config_&& + kBlockBasedTableWithWholeKeyHashIndex != option_config_ && + kHashLinkList != option_config_) { + iter->Prev(); + ASSERT_EQ(IterStatus(iter), "ka->va"); + } } delete iter; } while (ChangeOptions()); @@ -1952,7 +1963,7 @@ TEST(DBTest, IterPrevMaxSkip) { ASSERT_OK(Delete(1, "key1")); VerifyIterLast("(invalid)", 1); - } while (ChangeOptions(kSkipMergePut)); + } while (ChangeOptions(kSkipMergePut | kSkipNoSeekToLast)); } TEST(DBTest, IterWithSnapshot) { @@ -1977,15 +1988,19 @@ TEST(DBTest, IterWithSnapshot) { ASSERT_EQ(IterStatus(iter), "key5->val5"); if (!CurrentOptions().merge_operator) { // TODO: merge operator does not support backward iteration yet - iter->Prev(); - ASSERT_EQ(IterStatus(iter), "key4->val4"); - iter->Prev(); - ASSERT_EQ(IterStatus(iter), "key3->val3"); + if (kPlainTableAllBytesPrefix != option_config_&& + kBlockBasedTableWithWholeKeyHashIndex != option_config_ && + kHashLinkList != option_config_) { + iter->Prev(); + ASSERT_EQ(IterStatus(iter), "key4->val4"); + iter->Prev(); + ASSERT_EQ(IterStatus(iter), "key3->val3"); - iter->Next(); - ASSERT_EQ(IterStatus(iter), "key4->val4"); - iter->Next(); - ASSERT_EQ(IterStatus(iter), "key5->val5"); + iter->Next(); + ASSERT_EQ(IterStatus(iter), "key4->val4"); + iter->Next(); + ASSERT_EQ(IterStatus(iter), "key5->val5"); + } iter->Next(); ASSERT_TRUE(!iter->Valid()); } @@ -5944,7 +5959,7 @@ TEST(DBTest, GroupCommitTest) { ASSERT_TRUE(!itr->Valid()); delete itr; - } while (ChangeOptions()); + } while (ChangeOptions(kSkipNoSeekToLast)); } namespace { @@ -6313,7 +6328,7 @@ TEST(DBTest, Randomized) { } if (model_snap != nullptr) model.ReleaseSnapshot(model_snap); if (db_snap != nullptr) db_->ReleaseSnapshot(db_snap); - } while (ChangeOptions(kSkipDeletesFilterFirst)); + } while (ChangeOptions(kSkipDeletesFilterFirst | kSkipNoSeekToLast)); } TEST(DBTest, MultiGetSimple) { @@ -6429,7 +6444,6 @@ void PrefixScanInit(DBTest *dbtest) { } // namespace TEST(DBTest, PrefixScan) { - ReadOptions ro = ReadOptions(); int count; Slice prefix; Slice key; @@ -6450,45 +6464,9 @@ TEST(DBTest, PrefixScan) { options.max_background_compactions = 2; options.create_if_missing = true; options.disable_seek_compaction = true; - // Tricky: options.prefix_extractor will be released by - // NewHashSkipListRepFactory after use. options.memtable_factory.reset(NewHashSkipListRepFactory()); - // prefix specified, with blooms: 2 RAND I/Os - // SeekToFirst - DestroyAndReopen(&options); - PrefixScanInit(this); - count = 0; - env_->random_read_counter_.Reset(); - ro.prefix = &prefix; - iter = db_->NewIterator(ro); - for (iter->SeekToFirst(); iter->Valid(); iter->Next()) { - assert(iter->key().starts_with(prefix)); - count++; - } - ASSERT_OK(iter->status()); - delete iter; - ASSERT_EQ(count, 2); - ASSERT_EQ(env_->random_read_counter_.Read(), 2); - - // prefix specified, with blooms: 2 RAND I/Os - // Seek - DestroyAndReopen(&options); - PrefixScanInit(this); - count = 0; - env_->random_read_counter_.Reset(); - ro.prefix = &prefix; - iter = db_->NewIterator(ro); - for (iter->Seek(key); iter->Valid(); iter->Next()) { - assert(iter->key().starts_with(prefix)); - count++; - } - ASSERT_OK(iter->status()); - delete iter; - ASSERT_EQ(count, 2); - ASSERT_EQ(env_->random_read_counter_.Read(), 2); - - // no prefix specified: 11 RAND I/Os + // 11 RAND I/Os DestroyAndReopen(&options); PrefixScanInit(this); count = 0; @@ -6652,7 +6630,6 @@ TEST(DBTest, TailingIteratorDeletes) { TEST(DBTest, TailingIteratorPrefixSeek) { ReadOptions read_options; read_options.tailing = true; - read_options.prefix_seek = true; Options options = CurrentOptions(); options.env = env_; diff --git a/db/memtable.cc b/db/memtable.cc index 572aac049..b13b9f294 100644 --- a/db/memtable.cc +++ b/db/memtable.cc @@ -159,13 +159,12 @@ const char* EncodeKey(std::string* scratch, const Slice& target) { class MemTableIterator: public Iterator { public: - MemTableIterator(const MemTable& mem, const ReadOptions& options) + MemTableIterator(const MemTable& mem, const ReadOptions& options, + bool enforce_total_order) : bloom_(nullptr), prefix_extractor_(mem.prefix_extractor_), valid_(false) { - if (options.prefix) { - iter_.reset(mem.table_->GetPrefixIterator(*options.prefix)); - } else if (options.prefix_seek) { + if (prefix_extractor_ != nullptr && !enforce_total_order) { bloom_ = mem.prefix_bloom_.get(); iter_.reset(mem.table_->GetDynamicPrefixIterator()); } else { @@ -224,8 +223,9 @@ class MemTableIterator: public Iterator { void operator=(const MemTableIterator&); }; -Iterator* MemTable::NewIterator(const ReadOptions& options) { - return new MemTableIterator(*this, options); +Iterator* MemTable::NewIterator(const ReadOptions& options, + bool enforce_total_order) { + return new MemTableIterator(*this, options, enforce_total_order); } port::RWMutex* MemTable::GetLock(const Slice& key) { diff --git a/db/memtable.h b/db/memtable.h index b0d5d7d51..a4700f731 100644 --- a/db/memtable.h +++ b/db/memtable.h @@ -75,14 +75,10 @@ class MemTable { // iterator are internal keys encoded by AppendInternalKey in the // db/dbformat.{h,cc} module. // - // If options.prefix is supplied, it is passed to the underlying MemTableRep - // as a hint that the iterator only need to support access to keys with that - // specific prefix. - // If options.prefix is not supplied and options.prefix_seek is set, the - // iterator is not bound to a specific prefix. However, the semantics of - // Seek is changed - the result might only include keys with the same prefix - // as the seek-key. - Iterator* NewIterator(const ReadOptions& options = ReadOptions()); + // By default, it returns an iterator for prefix seek if prefix_extractor + // is configured in Options. + Iterator* NewIterator(const ReadOptions& options, + bool enforce_total_order = false); // Add an entry into memtable that maps key to value at the // specified sequence number and with the specified type. diff --git a/db/plain_table_db_test.cc b/db/plain_table_db_test.cc index 18b47e1a8..4cff95952 100644 --- a/db/plain_table_db_test.cc +++ b/db/plain_table_db_test.cc @@ -47,7 +47,6 @@ class PlainTableDBTest { public: PlainTableDBTest() : env_(Env::Default()) { - ro_.prefix_seek = true; dbname_ = test::TmpDir() + "/plain_table_db_test"; ASSERT_OK(DestroyDB(dbname_, Options())); db_ = nullptr; @@ -59,8 +58,6 @@ class PlainTableDBTest { ASSERT_OK(DestroyDB(dbname_, Options())); } - ReadOptions ro_; - // Return the current option configuration. Options CurrentOptions() { Options options; @@ -123,7 +120,7 @@ class PlainTableDBTest { } std::string Get(const std::string& k, const Snapshot* snapshot = nullptr) { - ReadOptions options = ro_; + ReadOptions options; options.snapshot = snapshot; std::string result; Status s = db_->Get(options, k, &result); @@ -369,7 +366,7 @@ TEST(PlainTableDBTest, Iterator) { dbfull()->TEST_FlushMemTable(); ASSERT_EQ("v1", Get("1000000000foo001")); ASSERT_EQ("v__3", Get("1000000000foo003")); - Iterator* iter = dbfull()->NewIterator(ro_); + Iterator* iter = dbfull()->NewIterator(ReadOptions()); iter->Seek("1000000000foo000"); ASSERT_TRUE(iter->Valid()); ASSERT_EQ("1000000000foo001", iter->key().ToString()); @@ -471,7 +468,7 @@ TEST(PlainTableDBTest, IteratorLargeKeys) { dbfull()->TEST_FlushMemTable(); - Iterator* iter = dbfull()->NewIterator(ro_); + Iterator* iter = dbfull()->NewIterator(ReadOptions()); iter->Seek(key_list[0]); for (size_t i = 0; i < 7; i++) { @@ -535,7 +532,7 @@ TEST(PlainTableDBTest, IteratorReverseSuffixComparator) { dbfull()->TEST_FlushMemTable(); ASSERT_EQ("v1", Get("1000000000foo001")); ASSERT_EQ("v__3", Get("1000000000foo003")); - Iterator* iter = dbfull()->NewIterator(ro_); + Iterator* iter = dbfull()->NewIterator(ReadOptions()); iter->Seek("1000000000foo009"); ASSERT_TRUE(iter->Valid()); ASSERT_EQ("1000000000foo008", iter->key().ToString()); @@ -766,7 +763,7 @@ TEST(PlainTableDBTest, NonExistingKeyToNonEmptyBucket) { ASSERT_EQ("NOT_FOUND", Get("8000000000000bar")); ASSERT_EQ("NOT_FOUND", Get("1000000000000bar")); - Iterator* iter = dbfull()->NewIterator(ro_); + Iterator* iter = dbfull()->NewIterator(ReadOptions()); iter->Seek("5000000000000bar"); ASSERT_TRUE(iter->Valid()); diff --git a/db/prefix_filter_iterator.h b/db/prefix_filter_iterator.h deleted file mode 100644 index e868c7a54..000000000 --- a/db/prefix_filter_iterator.h +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright (c) 2013, Facebook, Inc. All rights reserved. -// This source code is licensed under the BSD-style license found in the -// LICENSE file in the root directory of this source tree. An additional grant -// of patent rights can be found in the PATENTS file in the same directory. -// -// Wrap an underlying iterator, but exclude any results not starting -// with a given prefix. Seeking to keys not beginning with the prefix -// is invalid, and SeekToLast is not implemented (that would be -// non-trivial), but otherwise this iterator will behave just like the -// underlying iterator would if there happened to be no non-matching -// keys in the dataset. - -#pragma once -#include "rocksdb/iterator.h" -#include "rocksdb/slice.h" -#include "rocksdb/slice_transform.h" - -namespace rocksdb { - -class PrefixFilterIterator : public Iterator { - private: - Iterator* iter_; - const Slice &prefix_; - const SliceTransform *prefix_extractor_; - Status status_; - - public: - PrefixFilterIterator(Iterator* iter, - const Slice &prefix, - const SliceTransform* prefix_extractor) - : iter_(iter), prefix_(prefix), - prefix_extractor_(prefix_extractor), - status_(Status::OK()) { - if (prefix_extractor == nullptr) { - status_ = Status::InvalidArgument("A prefix filter may not be used " - "unless a function is also defined " - "for extracting prefixes"); - } else if (!prefix_extractor_->InRange(prefix)) { - status_ = Status::InvalidArgument("Must provide a slice for prefix which" - "is a prefix for some key"); - } - } - ~PrefixFilterIterator() { - delete iter_; - } - Slice key() const { return iter_->key(); } - Slice value() const { return iter_->value(); } - Status status() const { - if (!status_.ok()) { - return status_; - } - return iter_->status(); - } - void Next() { iter_->Next(); } - void Prev() { iter_->Prev(); } - void Seek(const Slice& k) { - if (prefix_extractor_->Transform(k) == prefix_) { - iter_->Seek(k); - } else { - status_ = Status::InvalidArgument("Seek must begin with target prefix"); - } - } - void SeekToFirst() { - Seek(prefix_); - } - void SeekToLast() { - status_ = Status::NotSupported("SeekToLast is incompatible with prefixes"); - } - bool Valid() const { - return (status_.ok() && iter_->Valid() && - prefix_extractor_->Transform(iter_->key()) == prefix_); - } -}; - -} // namespace rocksdb diff --git a/db/prefix_test.cc b/db/prefix_test.cc index c73cf00a6..18036bb93 100644 --- a/db/prefix_test.cc +++ b/db/prefix_test.cc @@ -17,7 +17,6 @@ #include "util/stop_watch.h" #include "util/testharness.h" -DEFINE_bool(use_prefix_hash_memtable, true, ""); DEFINE_bool(trigger_deadlock, false, "issue delete in range scan to trigger PrefixHashMap deadlock"); DEFINE_uint64(bucket_count, 100000, "number of buckets"); @@ -208,7 +207,6 @@ TEST(PrefixTest, TestResult) { auto db = OpenDb(); WriteOptions write_options; ReadOptions read_options; - read_options.prefix_seek = true; // 1. Insert one row. Slice v16("v16"); @@ -371,43 +369,6 @@ TEST(PrefixTest, TestResult) { } } -TEST(PrefixTest, FullIterator) { - while (NextOptions(1000000)) { - DestroyDB(kDbName, Options()); - auto db = OpenDb(); - WriteOptions write_options; - - std::vector prefixes; - for (uint64_t i = 0; i < 100; ++i) { - prefixes.push_back(i); - } - std::random_shuffle(prefixes.begin(), prefixes.end()); - - for (auto prefix : prefixes) { - for (uint64_t i = 0; i < 200; ++i) { - TestKey test_key(prefix, i); - Slice key = TestKeyToSlice(test_key); - ASSERT_OK(db->Put(write_options, key, Slice("0"))); - } - } - - auto func = [](void* db_void) { - auto db = reinterpret_cast(db_void); - std::unique_ptr iter(db->NewIterator(ReadOptions())); - iter->SeekToFirst(); - for (int i = 0; i < 3; ++i) { - iter->Next(); - } - }; - - auto env = Env::Default(); - for (int i = 0; i < 16; ++i) { - env->StartThread(func, reinterpret_cast(db.get())); - } - env->WaitForJoin(); - } -} - TEST(PrefixTest, DynamicPrefixIterator) { while (NextOptions(FLAGS_bucket_count)) { std::cout << "*** Mem table: " << options.memtable_factory->Name() @@ -452,9 +413,6 @@ TEST(PrefixTest, DynamicPrefixIterator) { HistogramImpl hist_seek_time; HistogramImpl hist_seek_comparison; - if (FLAGS_use_prefix_hash_memtable) { - read_options.prefix_seek = true; - } std::unique_ptr iter(db->NewIterator(read_options)); for (auto prefix : prefixes) { @@ -464,14 +422,15 @@ TEST(PrefixTest, DynamicPrefixIterator) { perf_context.Reset(); StopWatchNano timer(Env::Default(), true); + auto key_prefix = options.prefix_extractor->Transform(key); uint64_t total_keys = 0; - for (iter->Seek(key); iter->Valid(); iter->Next()) { + for (iter->Seek(key); + iter->Valid() && iter->key().starts_with(key_prefix); + iter->Next()) { if (FLAGS_trigger_deadlock) { std::cout << "Behold the deadlock!\n"; db->Delete(write_options, iter->key()); } - auto test_key = SliceToTestKey(iter->key()); - if (test_key->prefix != prefix) break; total_keys++; } hist_seek_time.Add(timer.ElapsedNanos()); @@ -509,116 +468,6 @@ TEST(PrefixTest, DynamicPrefixIterator) { } } -TEST(PrefixTest, PrefixHash) { - while (NextOptions(FLAGS_bucket_count)) { - std::cout << "*** Mem table: " << options.memtable_factory->Name() - << std::endl; - DestroyDB(kDbName, Options()); - auto db = OpenDb(); - WriteOptions write_options; - ReadOptions read_options; - - std::vector prefixes; - for (uint64_t i = 0; i < FLAGS_total_prefixes; ++i) { - prefixes.push_back(i); - } - - if (FLAGS_random_prefix) { - std::random_shuffle(prefixes.begin(), prefixes.end()); - } - - // insert x random prefix, each with y continuous element. - HistogramImpl hist_put_time; - HistogramImpl hist_put_comparison; - - for (auto prefix : prefixes) { - for (uint64_t sorted = 0; sorted < FLAGS_items_per_prefix; sorted++) { - TestKey test_key(prefix, sorted); - - Slice key = TestKeyToSlice(test_key); - std::string value = "v" + std::to_string(sorted); - - perf_context.Reset(); - StopWatchNano timer(Env::Default(), true); - ASSERT_OK(db->Put(write_options, key, value)); - hist_put_time.Add(timer.ElapsedNanos()); - hist_put_comparison.Add(perf_context.user_key_comparison_count); - } - } - - std::cout << "Put key comparison: \n" << hist_put_comparison.ToString() - << "Put time: \n" << hist_put_time.ToString(); - - - // test seek existing keys - HistogramImpl hist_seek_time; - HistogramImpl hist_seek_comparison; - - for (auto prefix : prefixes) { - TestKey test_key(prefix, 0); - Slice key = TestKeyToSlice(test_key); - std::string value = "v" + std::to_string(0); - - Slice key_prefix; - if (FLAGS_use_prefix_hash_memtable) { - key_prefix = options.prefix_extractor->Transform(key); - read_options.prefix = &key_prefix; - } - std::unique_ptr iter(db->NewIterator(read_options)); - - perf_context.Reset(); - StopWatchNano timer(Env::Default(), true); - uint64_t total_keys = 0; - for (iter->Seek(key); iter->Valid(); iter->Next()) { - if (FLAGS_trigger_deadlock) { - std::cout << "Behold the deadlock!\n"; - db->Delete(write_options, iter->key()); - } - auto test_key = SliceToTestKey(iter->key()); - if (test_key->prefix != prefix) break; - total_keys++; - } - hist_seek_time.Add(timer.ElapsedNanos()); - hist_seek_comparison.Add(perf_context.user_key_comparison_count); - ASSERT_EQ(total_keys, FLAGS_items_per_prefix); - } - - std::cout << "Seek key comparison: \n" - << hist_seek_comparison.ToString() - << "Seek time: \n" - << hist_seek_time.ToString(); - - // test non-existing keys - HistogramImpl hist_no_seek_time; - HistogramImpl hist_no_seek_comparison; - - for (auto prefix = FLAGS_total_prefixes; - prefix < FLAGS_total_prefixes + 100; - prefix++) { - TestKey test_key(prefix, 0); - Slice key = TestKeyToSlice(test_key); - - if (FLAGS_use_prefix_hash_memtable) { - Slice key_prefix = options.prefix_extractor->Transform(key); - read_options.prefix = &key_prefix; - } - std::unique_ptr iter(db->NewIterator(read_options)); - - perf_context.Reset(); - StopWatchNano timer(Env::Default(), true); - iter->Seek(key); - hist_no_seek_time.Add(timer.ElapsedNanos()); - hist_no_seek_comparison.Add(perf_context.user_key_comparison_count); - ASSERT_TRUE(!iter->Valid()); - } - - std::cout << "non-existing Seek key comparison: \n" - << hist_no_seek_comparison.ToString() - << "non-existing Seek time: \n" - << hist_no_seek_time.ToString(); - } -} - } int main(int argc, char** argv) { diff --git a/db/repair.cc b/db/repair.cc index c154c04ac..8ae64b219 100644 --- a/db/repair.cc +++ b/db/repair.cc @@ -231,7 +231,8 @@ class Repairer { // since ExtractMetaData() will also generate edits. FileMetaData meta; meta.number = next_file_number_++; - Iterator* iter = mem->NewIterator(); + ReadOptions ro; + Iterator* iter = mem->NewIterator(ro, true /* enforce_total_order */); status = BuildTable(dbname_, env_, options_, storage_options_, table_cache_, iter, &meta, icmp_, 0, 0, kNoCompression); delete iter; diff --git a/db/simple_table_db_test.cc b/db/simple_table_db_test.cc index a67114663..affa61465 100644 --- a/db/simple_table_db_test.cc +++ b/db/simple_table_db_test.cc @@ -83,8 +83,6 @@ public: unique_ptr && file, uint64_t file_size, unique_ptr* table_reader); - bool PrefixMayMatch(const Slice& internal_prefix) override; - Iterator* NewIterator(const ReadOptions&) override; Status Get(const ReadOptions&, const Slice& key, void* arg, @@ -220,10 +218,6 @@ std::shared_ptr SimpleTableReader::GetTableProperties() return rep_->table_properties; } -bool SimpleTableReader::PrefixMayMatch(const Slice& internal_prefix) { - return true; -} - Iterator* SimpleTableReader::NewIterator(const ReadOptions& options) { return new SimpleTableIterator(this); } diff --git a/db/table_cache.cc b/db/table_cache.cc index 395951324..8cecfdb59 100644 --- a/db/table_cache.cc +++ b/db/table_cache.cc @@ -191,16 +191,16 @@ Status TableCache::GetTableProperties( } bool TableCache::PrefixMayMatch(const ReadOptions& options, - const InternalKeyComparator& icomparator, - const FileMetaData& file_meta, - const Slice& internal_prefix, bool* table_io) { + const InternalKeyComparator& icomparator, + const FileMetaData& file_meta, + const Slice& internal_prefix, bool* table_io) { bool may_match = true; auto table_reader = file_meta.table_reader; Cache::Handle* table_handle = nullptr; if (table_reader == nullptr) { // Need to get table handle from file number Status s = FindTable(storage_options_, icomparator, file_meta.number, - file_meta.file_size, &table_handle, table_io); + file_meta.file_size, &table_handle, table_io); if (!s.ok()) { return may_match; } diff --git a/db/tailing_iter.cc b/db/tailing_iter.cc index 41d2b225a..67b59b2c9 100644 --- a/db/tailing_iter.cc +++ b/db/tailing_iter.cc @@ -60,8 +60,8 @@ void TailingIterator::Seek(const Slice& target) { // need to do a seek if 'target' belongs to that interval (i.e. immutable_ is // already at the correct position)! // - // If options.prefix_seek is used and immutable_ is not valid, seek if target - // has a different prefix than prev_key. + // If prefix seek is used and immutable_ is not valid, seek if target has a + // different prefix than prev_key. // // prev_key_ is updated by Next(). SeekImmutable() sets prev_key_ to // 'target' -- in this case, prev_key_ is included in the interval, so @@ -70,7 +70,7 @@ void TailingIterator::Seek(const Slice& target) { const Comparator* cmp = cfd_->user_comparator(); if (!is_prev_set_ || cmp->Compare(prev_key_, target) >= !is_prev_inclusive_ || (immutable_->Valid() && cmp->Compare(target, immutable_->key()) > 0) || - (read_options_.prefix_seek && !IsSamePrefix(target))) { + (cfd_->options()->prefix_extractor != nullptr && !IsSamePrefix(target))) { SeekImmutable(target); } diff --git a/db/tailing_iter.h b/db/tailing_iter.h index a66a85bc5..6b9c51375 100644 --- a/db/tailing_iter.h +++ b/db/tailing_iter.h @@ -2,9 +2,10 @@ // This source code is licensed under the BSD-style license found in the // LICENSE file in the root directory of this source tree. An additional grant // of patent rights can be found in the PATENTS file in the same directory. -#ifndef ROCKSDB_LITE #pragma once +#ifndef ROCKSDB_LITE + #include #include "rocksdb/db.h" @@ -79,7 +80,7 @@ class TailingIterator : public Iterator { bool IsCurrentVersion() const; // check if SeekImmutable() is needed due to target having a different prefix - // than prev_key_ (used when options.prefix_seek is set) + // than prev_key_ (used when in prefix seek mode) bool IsSamePrefix(const Slice& target) const; // creates mutable_ and immutable_ iterators and updates version_number_ diff --git a/db/version_set.cc b/db/version_set.cc index 45cf305b8..280db327b 100644 --- a/db/version_set.cc +++ b/db/version_set.cc @@ -226,20 +226,11 @@ static Iterator* GetFileIterator(void* arg, const ReadOptions& options, return NewErrorIterator( Status::Corruption("FileReader invoked with unexpected value")); } else { - ReadOptions options_copy; - if (options.prefix) { - // suppress prefix filtering since we have already checked the - // filters once at this point - options_copy = options; - options_copy.prefix = nullptr; - } - const EncodedFileMetaData* encoded_meta = reinterpret_cast(file_value.data()); FileMetaData meta(encoded_meta->number, encoded_meta->file_size); meta.table_reader = encoded_meta->table_reader; - return cache->NewIterator( - options.prefix ? options_copy : options, soptions, icomparator, meta, + return cache->NewIterator(options, soptions, icomparator, meta, nullptr /* don't need reference to table*/, for_compaction); } } @@ -328,15 +319,6 @@ Iterator* Version::NewConcatenatingIterator(const ReadOptions& options, int level) const { Iterator* level_iter = new LevelFileNumIterator(cfd_->internal_comparator(), &files_[level]); - if (options.prefix) { - InternalKey internal_prefix(*options.prefix, 0, kTypeValue); - if (!PrefixMayMatch(options, soptions, - internal_prefix.Encode(), level_iter)) { - delete level_iter; - // nothing in this level can match the prefix - return NewEmptyIterator(); - } - } return NewTwoLevelIterator(level_iter, &GetFileIterator, cfd_->table_cache(), options, soptions, cfd_->internal_comparator()); } diff --git a/db/write_batch_test.cc b/db/write_batch_test.cc index c2f412c59..febd35c05 100644 --- a/db/write_batch_test.cc +++ b/db/write_batch_test.cc @@ -31,7 +31,7 @@ static std::string PrintContents(WriteBatch* b) { ColumnFamilyMemTablesDefault cf_mems_default(mem, &options); Status s = WriteBatchInternal::InsertInto(b, &cf_mems_default); int count = 0; - Iterator* iter = mem->NewIterator(); + Iterator* iter = mem->NewIterator(ReadOptions()); for (iter->SeekToFirst(); iter->Valid(); iter->Next()) { ParsedInternalKey ikey; memset((void *)&ikey, 0, sizeof(ikey)); @@ -283,7 +283,7 @@ TEST(WriteBatchTest, PutGatherSlices) { namespace { class ColumnFamilyHandleImplDummy : public ColumnFamilyHandleImpl { public: - ColumnFamilyHandleImplDummy(int id) + explicit ColumnFamilyHandleImplDummy(int id) : ColumnFamilyHandleImpl(nullptr, nullptr, nullptr), id_(id) {} uint32_t GetID() const override { return id_; } diff --git a/include/rocksdb/c.h b/include/rocksdb/c.h index 7d4a374d9..7f2c082d0 100644 --- a/include/rocksdb/c.h +++ b/include/rocksdb/c.h @@ -463,13 +463,9 @@ extern void rocksdb_readoptions_set_verify_checksums( unsigned char); extern void rocksdb_readoptions_set_fill_cache( rocksdb_readoptions_t*, unsigned char); -extern void rocksdb_readoptions_set_prefix_seek( - rocksdb_readoptions_t*, unsigned char); extern void rocksdb_readoptions_set_snapshot( rocksdb_readoptions_t*, const rocksdb_snapshot_t*); -extern void rocksdb_readoptions_set_prefix( - rocksdb_readoptions_t*, const char* key, size_t keylen); extern void rocksdb_readoptions_set_read_tier( rocksdb_readoptions_t*, int); extern void rocksdb_readoptions_set_tailing( diff --git a/include/rocksdb/memtablerep.h b/include/rocksdb/memtablerep.h index 0d251a9a6..d23f41b62 100644 --- a/include/rocksdb/memtablerep.h +++ b/include/rocksdb/memtablerep.h @@ -148,13 +148,6 @@ class MemTableRep { // GetIterator(). virtual Iterator* GetIterator(const Slice& user_key) { return GetIterator(); } - // Return an iterator over at least the keys with the specified prefix. The - // iterator may also allow access to other keys, but doesn't have to. Default: - // GetIterator(). - virtual Iterator* GetPrefixIterator(const Slice& prefix) { - return GetIterator(); - } - // Return an iterator that has a special Seek semantics. The result of // a Seek might only include keys with the same prefix as the target key. virtual Iterator* GetDynamicPrefixIterator() { return GetIterator(); } diff --git a/include/rocksdb/options.h b/include/rocksdb/options.h index 7f1bf39a9..e95fb557e 100644 --- a/include/rocksdb/options.h +++ b/include/rocksdb/options.h @@ -817,7 +817,10 @@ struct ReadOptions { // If this option is set and memtable implementation allows, Seek // might only return keys with the same prefix as the seek-key - bool prefix_seek; + // + // ! DEPRECATED: prefix_seek is on by default when prefix_extractor + // is configured + // bool prefix_seek; // If "snapshot" is non-nullptr, read as of the supplied snapshot // (which must belong to the DB that is being read and which must @@ -837,7 +840,9 @@ struct ReadOptions { // prefix, and SeekToLast() is not supported. prefix filter with this // option will sometimes reduce the number of read IOPs. // Default: nullptr - const Slice* prefix; + // + // ! DEPRECATED + // const Slice* prefix; // Specify if this read request should process data that ALREADY // resides on a particular cache. If the required data is not @@ -856,17 +861,13 @@ struct ReadOptions { ReadOptions() : verify_checksums(true), fill_cache(true), - prefix_seek(false), snapshot(nullptr), - prefix(nullptr), read_tier(kReadAllTier), tailing(false) {} ReadOptions(bool cksum, bool cache) : verify_checksums(cksum), fill_cache(cache), - prefix_seek(false), snapshot(nullptr), - prefix(nullptr), read_tier(kReadAllTier), tailing(false) {} }; diff --git a/include/rocksdb/table.h b/include/rocksdb/table.h index b50007a32..53bf18e87 100644 --- a/include/rocksdb/table.h +++ b/include/rocksdb/table.h @@ -62,9 +62,7 @@ struct BlockBasedTableOptions { kBinarySearch, // The hash index, if enabled, will do the hash lookup when - // `ReadOption.prefix_seek == true`. User should also specify - // `Options.prefix_extractor` to allow the index block to correctly - // extract the prefix of the given key and perform hash table lookup. + // `Options.prefix_extractor` is provided. kHashSearch, }; diff --git a/table/block_based_table_reader.cc b/table/block_based_table_reader.cc index 35f6a194c..d932a9281 100644 --- a/table/block_based_table_reader.cc +++ b/table/block_based_table_reader.cc @@ -919,15 +919,6 @@ bool BlockBasedTable::PrefixMayMatch(const Slice& internal_prefix) { } Iterator* BlockBasedTable::NewIterator(const ReadOptions& options) { - if (options.prefix) { - InternalKey internal_prefix(*options.prefix, 0, kTypeValue); - if (!PrefixMayMatch(internal_prefix.Encode())) { - // nothing in this file can match the prefix, so we should not - // bother doing I/O to this file when iterating. - return NewEmptyIterator(); - } - } - return NewTwoLevelIterator(NewIndexIterator(options), &BlockBasedTable::DataBlockReader, const_cast(this), options, diff --git a/table/plain_table_reader.cc b/table/plain_table_reader.cc index 9a93e205d..196201730 100644 --- a/table/plain_table_reader.cc +++ b/table/plain_table_reader.cc @@ -149,12 +149,8 @@ Status PlainTableReader::Open( void PlainTableReader::SetupForCompaction() { } -bool PlainTableReader::PrefixMayMatch(const Slice& internal_prefix) { - return true; -} - Iterator* PlainTableReader::NewIterator(const ReadOptions& options) { - return new PlainTableIterator(this, options.prefix_seek); + return new PlainTableIterator(this, options_.prefix_extractor != nullptr); } struct PlainTableReader::IndexRecord { diff --git a/table/plain_table_reader.h b/table/plain_table_reader.h index 7fa3644ef..756439b5c 100644 --- a/table/plain_table_reader.h +++ b/table/plain_table_reader.h @@ -2,8 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. See the AUTHORS file for names of contributors. -#ifndef ROCKSDB_LITE #pragma once + +#ifndef ROCKSDB_LITE #include #include #include @@ -53,8 +54,6 @@ class PlainTableReader: public TableReader { const int bloom_bits_per_key, double hash_table_ratio, size_t index_sparseness); - bool PrefixMayMatch(const Slice& internal_prefix); - Iterator* NewIterator(const ReadOptions&); Status Get(const ReadOptions&, const Slice& key, void* arg, diff --git a/table/table_reader.h b/table/table_reader.h index 3d2738c9c..118d3100f 100644 --- a/table/table_reader.h +++ b/table/table_reader.h @@ -29,7 +29,9 @@ class TableReader { // contains the key a key starting with iternal_prefix. The specific // table implementation can use bloom filter and/or other heuristic // to filter out this table as a whole. - virtual bool PrefixMayMatch(const Slice& internal_prefix) = 0; + virtual bool PrefixMayMatch(const Slice& internal_prefix) { + return true; + } // Returns a new iterator over the table contents. // The result of NewIterator() is initially invalid (caller must diff --git a/table/table_reader_bench.cc b/table/table_reader_bench.cc index 32f6ee618..a0ff0d7f0 100644 --- a/table/table_reader_bench.cc +++ b/table/table_reader_bench.cc @@ -68,8 +68,6 @@ void TableReaderBenchmark(Options& opts, EnvOptions& env_options, bool through_db, bool measured_by_nanosecond) { rocksdb::InternalKeyComparator ikc(opts.comparator); - Slice prefix = Slice(); - std::string file_name = test::TmpDir() + "/rocksdb_table_reader_benchmark"; std::string dbname = test::TmpDir() + "/rocksdb_table_reader_bench_db"; @@ -156,10 +154,6 @@ void TableReaderBenchmark(Options& opts, EnvOptions& env_options, } std::string start_key = MakeKey(r1, r2, through_db); std::string end_key = MakeKey(r1, r2 + r2_len, through_db); - if (prefix_len < 16) { - prefix = Slice(start_key.data(), prefix_len); - read_options.prefix = &prefix; - } uint64_t total_time = 0; uint64_t start_time = Now(env, measured_by_nanosecond); port::MemoryBarrier(); @@ -254,7 +248,6 @@ int main(int argc, char** argv) { options.compression = rocksdb::CompressionType::kNoCompression; if (FLAGS_plain_table) { - ro.prefix_seek = true; options.allow_mmap_reads = true; env_options.use_mmap_reads = true; tf = new rocksdb::PlainTableFactory(16, (FLAGS_prefix_len == 16) ? 0 : 8, diff --git a/table/table_test.cc b/table/table_test.cc index 0426122ff..2e21c5064 100644 --- a/table/table_test.cc +++ b/table/table_test.cc @@ -307,11 +307,9 @@ class KeyConvertingIterator: public Iterator { class TableConstructor: public Constructor { public: explicit TableConstructor(const Comparator* cmp, - bool convert_to_internal_key = false, - bool prefix_seek = false) + bool convert_to_internal_key = false) : Constructor(cmp), - convert_to_internal_key_(convert_to_internal_key), - prefix_seek_(prefix_seek) {} + convert_to_internal_key_(convert_to_internal_key) {} ~TableConstructor() { Reset(); } virtual Status FinishImpl(const Options& options, @@ -352,9 +350,6 @@ class TableConstructor: public Constructor { virtual Iterator* NewIterator() const { ReadOptions ro; - if (prefix_seek_) { - ro.prefix_seek = true; - } Iterator* iter = table_reader_->NewIterator(ro); if (convert_to_internal_key_) { return new KeyConvertingIterator(iter); @@ -388,7 +383,6 @@ class TableConstructor: public Constructor { source_.reset(); } bool convert_to_internal_key_; - bool prefix_seek_; uint64_t uniq_id_; unique_ptr sink_; @@ -434,7 +428,7 @@ class MemTableConstructor: public Constructor { return Status::OK(); } virtual Iterator* NewIterator() const { - return new KeyConvertingIterator(memtable_->NewIterator()); + return new KeyConvertingIterator(memtable_->NewIterator(ReadOptions())); } private: @@ -699,7 +693,7 @@ class Harness { options_.prefix_extractor.reset(new FixedOrLessPrefixTransform(2)); options_.allow_mmap_reads = true; options_.table_factory.reset(NewPlainTableFactory()); - constructor_ = new TableConstructor(options_.comparator, true, true); + constructor_ = new TableConstructor(options_.comparator, true); internal_comparator_.reset( new InternalKeyComparator(options_.comparator)); break; @@ -709,7 +703,7 @@ class Harness { options_.prefix_extractor.reset(NewNoopTransform()); options_.allow_mmap_reads = true; options_.table_factory.reset(NewPlainTableFactory()); - constructor_ = new TableConstructor(options_.comparator, true, true); + constructor_ = new TableConstructor(options_.comparator, true); internal_comparator_.reset( new InternalKeyComparator(options_.comparator)); break; @@ -719,7 +713,7 @@ class Harness { options_.prefix_extractor = nullptr; options_.allow_mmap_reads = true; options_.table_factory.reset(NewTotalOrderPlainTableFactory()); - constructor_ = new TableConstructor(options_.comparator, true, false); + constructor_ = new TableConstructor(options_.comparator, true); internal_comparator_.reset( new InternalKeyComparator(options_.comparator)); break; @@ -1667,7 +1661,7 @@ TEST(MemTableTest, Simple) { ColumnFamilyMemTablesDefault cf_mems_default(memtable, &options); ASSERT_TRUE(WriteBatchInternal::InsertInto(&batch, &cf_mems_default).ok()); - Iterator* iter = memtable->NewIterator(); + Iterator* iter = memtable->NewIterator(ReadOptions()); iter->SeekToFirst(); while (iter->Valid()) { fprintf(stderr, "key: '%s' -> '%s'\n", diff --git a/tools/db_stress.cc b/tools/db_stress.cc index d71bd6a15..8b8523f89 100644 --- a/tools/db_stress.cc +++ b/tools/db_stress.cc @@ -1008,7 +1008,6 @@ class StressTest { prefixes[i].resize(FLAGS_prefix_size); prefix_slices[i] = Slice(prefixes[i]); readoptionscopy[i] = readoptions; - readoptionscopy[i].prefix_seek = true; readoptionscopy[i].snapshot = snapshot; iters[i] = db_->NewIterator(readoptionscopy[i], column_family); iters[i]->Seek(prefix_slices[i]); @@ -1074,7 +1073,6 @@ class StressTest { const Snapshot* snapshot = db_->GetSnapshot(); ReadOptions readoptionscopy = readoptions; readoptionscopy.snapshot = snapshot; - readoptionscopy.prefix_seek = FLAGS_prefix_size > 0; unique_ptr iter(db_->NewIterator(readoptionscopy, column_family)); iter->Seek(key); @@ -1198,7 +1196,6 @@ class StressTest { // prefix if (!FLAGS_test_batches_snapshots) { Slice prefix = Slice(key.data(), FLAGS_prefix_size); - read_opts.prefix_seek = true; Iterator* iter = db_->NewIterator(read_opts, column_family); int64_t count = 0; for (iter->Seek(prefix); @@ -1277,7 +1274,6 @@ class StressTest { } if (!thread->rand.OneIn(2)) { // Use iterator to verify this range - options.prefix_seek = FLAGS_prefix_size > 0; unique_ptr iter( db_->NewIterator(options, column_families_[cf])); iter->Seek(Key(start)); diff --git a/util/hash_linklist_rep.cc b/util/hash_linklist_rep.cc index 9e77afa3e..64aa2d9e8 100644 --- a/util/hash_linklist_rep.cc +++ b/util/hash_linklist_rep.cc @@ -73,9 +73,6 @@ class HashLinkListRep : public MemTableRep { virtual MemTableRep::Iterator* GetIterator(const Slice& slice) override; - virtual MemTableRep::Iterator* GetPrefixIterator(const Slice& prefix) - override; - virtual MemTableRep::Iterator* GetDynamicPrefixIterator() override; private: @@ -429,19 +426,14 @@ MemTableRep::Iterator* HashLinkListRep::GetIterator() { return new FullListIterator(list, new_arena); } -MemTableRep::Iterator* HashLinkListRep::GetPrefixIterator( - const Slice& prefix) { - auto bucket = GetBucket(prefix); +MemTableRep::Iterator* HashLinkListRep::GetIterator(const Slice& slice) { + auto bucket = GetBucket(transform_->Transform(slice)); if (bucket == nullptr) { return new EmptyIterator(); } return new Iterator(this, bucket); } -MemTableRep::Iterator* HashLinkListRep::GetIterator(const Slice& slice) { - return GetPrefixIterator(transform_->Transform(slice)); -} - MemTableRep::Iterator* HashLinkListRep::GetDynamicPrefixIterator() { return new DynamicIterator(*this); } diff --git a/util/hash_skiplist_rep.cc b/util/hash_skiplist_rep.cc index e27ec5949..21df9f62b 100644 --- a/util/hash_skiplist_rep.cc +++ b/util/hash_skiplist_rep.cc @@ -42,9 +42,6 @@ class HashSkipListRep : public MemTableRep { virtual MemTableRep::Iterator* GetIterator(const Slice& slice) override; - virtual MemTableRep::Iterator* GetPrefixIterator(const Slice& prefix) - override; - virtual MemTableRep::Iterator* GetDynamicPrefixIterator() override; private: @@ -307,18 +304,14 @@ MemTableRep::Iterator* HashSkipListRep::GetIterator() { return new Iterator(list, true, new_arena); } -MemTableRep::Iterator* HashSkipListRep::GetPrefixIterator(const Slice& prefix) { - auto bucket = GetBucket(prefix); +MemTableRep::Iterator* HashSkipListRep::GetIterator(const Slice& slice) { + auto bucket = GetBucket(transform_->Transform(slice)); if (bucket == nullptr) { return new EmptyIterator(); } return new Iterator(bucket, false); } -MemTableRep::Iterator* HashSkipListRep::GetIterator(const Slice& slice) { - return GetPrefixIterator(transform_->Transform(slice)); -} - MemTableRep::Iterator* HashSkipListRep::GetDynamicPrefixIterator() { return new DynamicIterator(*this); }