diff --git a/Makefile b/Makefile index ef068592d..1bd202bc9 100644 --- a/Makefile +++ b/Makefile @@ -116,7 +116,8 @@ TESTS = \ table_test \ thread_local_test \ geodb_test \ - rate_limiter_test \ + rate_limiter_test \ + cuckoo_table_builder_test \ options_test \ cuckoo_table_builder_test \ cuckoo_table_reader_test \ @@ -235,7 +236,7 @@ valgrind_check: all $(PROGRAMS) $(TESTS) echo $$t $$((etime - stime)) >> $(VALGRIND_DIR)/valgrind_tests_times; \ done -unity.cc: +unity.cc: $(shell (export ROCKSDB_ROOT="$(CURDIR)"; "$(CURDIR)/build_tools/unity" "$(CURDIR)/unity.cc")) unity: unity.cc unity.o diff --git a/db/db_impl.cc b/db/db_impl.cc index 4b5200390..758441980 100644 --- a/db/db_impl.cc +++ b/db/db_impl.cc @@ -35,7 +35,6 @@ #include "db/merge_helper.h" #include "db/table_cache.h" #include "db/table_properties_collector.h" -#include "db/tailing_iter.h" #include "db/forward_iterator.h" #include "db/transaction_log_impl.h" #include "db/version_set.h" @@ -3704,7 +3703,10 @@ Status DBImpl::NewIterators( #else for (auto cfh : column_families) { auto cfd = reinterpret_cast(cfh)->cfd(); - iterators->push_back(new TailingIterator(env_, this, options, cfd)); + auto iter = new ForwardIterator(this, options, cfd); + iterators->push_back( + NewDBIterator(env_, *cfd->options(), cfd->user_comparator(), iter, + kMaxSequenceNumber)); } #endif } else { diff --git a/db/tailing_iter.cc b/db/tailing_iter.cc deleted file mode 100644 index 67b59b2c9..000000000 --- a/db/tailing_iter.cc +++ /dev/null @@ -1,221 +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. - -#ifndef ROCKSDB_LITE -#include "db/tailing_iter.h" - -#include -#include -#include -#include "db/db_impl.h" -#include "db/db_iter.h" -#include "db/column_family.h" -#include "rocksdb/env.h" -#include "rocksdb/slice.h" -#include "rocksdb/slice_transform.h" -#include "table/merger.h" - -namespace rocksdb { - -TailingIterator::TailingIterator(Env* const env, DBImpl* db, - const ReadOptions& read_options, ColumnFamilyData* cfd) - : env_(env), - db_(db), - read_options_(read_options), - cfd_(cfd), - super_version_(nullptr), - current_(nullptr), - status_(Status::InvalidArgument("Seek() not called on this iterator")) {} - -TailingIterator::~TailingIterator() { - Cleanup(); -} - -bool TailingIterator::Valid() const { - return current_ != nullptr; -} - -void TailingIterator::SeekToFirst() { - if (!IsCurrentVersion()) { - CreateIterators(); - } - - mutable_->SeekToFirst(); - immutable_->SeekToFirst(); - UpdateCurrent(); -} - -void TailingIterator::Seek(const Slice& target) { - if (!IsCurrentVersion()) { - CreateIterators(); - } - - mutable_->Seek(target); - - // We maintain the interval (prev_key_, immutable_->key()] such that there - // are no records with keys within that range in immutable_ other than - // immutable_->key(). Since immutable_ can't change in this version, we don't - // need to do a seek if 'target' belongs to that interval (i.e. immutable_ is - // already at the correct position)! - // - // 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 - // prev_inclusive_ has to be set. - - 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) || - (cfd_->options()->prefix_extractor != nullptr && !IsSamePrefix(target))) { - SeekImmutable(target); - } - - UpdateCurrent(); -} - -void TailingIterator::Next() { - assert(Valid()); - - if (!IsCurrentVersion()) { - // save the current key, create new iterators and then seek - std::string current_key = key().ToString(); - Slice key_slice(current_key.data(), current_key.size()); - - CreateIterators(); - Seek(key_slice); - - if (!Valid() || key().compare(key_slice) != 0) { - // record with current_key no longer exists - return; - } - - } else if (current_ == immutable_.get()) { - // immutable iterator is advanced -- update prev_key_ - prev_key_ = key().ToString(); - is_prev_inclusive_ = false; - is_prev_set_ = true; - } - - current_->Next(); - UpdateCurrent(); -} - -Slice TailingIterator::key() const { - assert(Valid()); - return current_->key(); -} - -Slice TailingIterator::value() const { - assert(Valid()); - return current_->value(); -} - -Status TailingIterator::status() const { - if (!status_.ok()) { - return status_; - } else if (!mutable_->status().ok()) { - return mutable_->status(); - } else { - return immutable_->status(); - } -} - -void TailingIterator::Prev() { - status_ = Status::NotSupported("This iterator doesn't support Prev()"); -} - -void TailingIterator::SeekToLast() { - status_ = Status::NotSupported("This iterator doesn't support SeekToLast()"); -} - -void TailingIterator::Cleanup() { - // Release old super version if necessary - mutable_.reset(); - immutable_.reset(); - if (super_version_ != nullptr && super_version_->Unref()) { - DBImpl::DeletionState deletion_state; - db_->mutex_.Lock(); - super_version_->Cleanup(); - db_->FindObsoleteFiles(deletion_state, false, true); - db_->mutex_.Unlock(); - delete super_version_; - if (deletion_state.HaveSomethingToDelete()) { - db_->PurgeObsoleteFiles(deletion_state); - } - } -} - -void TailingIterator::CreateIterators() { - Cleanup(); - super_version_= cfd_->GetReferencedSuperVersion(&(db_->mutex_)); - - Iterator* mutable_iter = super_version_->mem->NewIterator(read_options_); - // create a DBIter that only uses memtable content; see NewIterator() - mutable_.reset( - NewDBIterator(env_, *cfd_->options(), cfd_->user_comparator(), - mutable_iter, kMaxSequenceNumber)); - - std::vector list; - super_version_->imm->AddIterators(read_options_, &list); - super_version_->current->AddIterators( - read_options_, *cfd_->soptions(), &list); - Iterator* immutable_iter = - NewMergingIterator(&cfd_->internal_comparator(), &list[0], list.size()); - - // create a DBIter that only uses memtable content; see NewIterator() - immutable_.reset( - NewDBIterator(env_, *cfd_->options(), cfd_->user_comparator(), - immutable_iter, kMaxSequenceNumber)); - - current_ = nullptr; - is_prev_set_ = false; -} - -void TailingIterator::UpdateCurrent() { - current_ = nullptr; - - if (mutable_->Valid()) { - current_ = mutable_.get(); - } - const Comparator* cmp = cfd_->user_comparator(); - if (immutable_->Valid() && - (current_ == nullptr || - cmp->Compare(immutable_->key(), current_->key()) < 0)) { - current_ = immutable_.get(); - } - - if (!status_.ok()) { - // reset status that was set by Prev() or SeekToLast() - status_ = Status::OK(); - } -} - -bool TailingIterator::IsCurrentVersion() const { - return super_version_ != nullptr && - super_version_->version_number == cfd_->GetSuperVersionNumber(); -} - -bool TailingIterator::IsSamePrefix(const Slice& target) const { - const SliceTransform* extractor = cfd_->options()->prefix_extractor.get(); - - assert(extractor); - assert(is_prev_set_); - - return extractor->Transform(target) - .compare(extractor->Transform(prev_key_)) == 0; -} - -void TailingIterator::SeekImmutable(const Slice& target) { - prev_key_ = target.ToString(); - is_prev_inclusive_ = true; - is_prev_set_ = true; - - immutable_->Seek(target); -} - -} // namespace rocksdb -#endif // ROCKSDB_LITE diff --git a/db/tailing_iter.h b/db/tailing_iter.h deleted file mode 100644 index 6b9c51375..000000000 --- a/db/tailing_iter.h +++ /dev/null @@ -1,97 +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. -#pragma once - -#ifndef ROCKSDB_LITE - -#include - -#include "rocksdb/db.h" -#include "rocksdb/iterator.h" -#include "rocksdb/options.h" - -namespace rocksdb { - -class DBImpl; -class Env; -struct SuperVersion; -class ColumnFamilyData; - -/** - * TailingIterator is a special type of iterator that doesn't use an (implicit) - * snapshot. In other words, it can be used to read data that was added to the - * db after the iterator had been created. - * - * TailingIterator is optimized for sequential reading. It doesn't support - * Prev() and SeekToLast() operations. - */ -class TailingIterator : public Iterator { - public: - TailingIterator(Env* const env, DBImpl* db, const ReadOptions& read_options, - ColumnFamilyData* cfd); - virtual ~TailingIterator(); - - virtual bool Valid() const override; - virtual void SeekToFirst() override; - virtual void SeekToLast() override; - virtual void Seek(const Slice& target) override; - virtual void Next() override; - virtual void Prev() override; - virtual Slice key() const override; - virtual Slice value() const override; - virtual Status status() const override; - - private: - void Cleanup(); - - Env* const env_; - DBImpl* const db_; - const ReadOptions read_options_; - ColumnFamilyData* const cfd_; - SuperVersion* super_version_; - - // TailingIterator merges the contents of the two iterators below (one using - // mutable memtable contents only, other over SSTs and immutable memtables). - // See DBIter::GetTailingIteratorPair(). - std::unique_ptr mutable_; - std::unique_ptr immutable_; - - // points to either mutable_ or immutable_ - Iterator* current_; - - // key that precedes immutable iterator's current key - std::string prev_key_; - - // unless prev_set is true, prev_key/prev_head is not valid and shouldn't be - // used; reset by createIterators() - bool is_prev_set_; - - // prev_key_ was set by SeekImmutable(), which means that the interval of - // keys covered by immutable_ is [prev_key_, current], i.e. it includes the - // left endpoint - bool is_prev_inclusive_; - - // internal iterator status - Status status_; - - // check if this iterator's version matches DB's version - bool IsCurrentVersion() const; - - // check if SeekImmutable() is needed due to target having a different prefix - // than prev_key_ (used when in prefix seek mode) - bool IsSamePrefix(const Slice& target) const; - - // creates mutable_ and immutable_ iterators and updates version_number_ - void CreateIterators(); - - // set current_ to be one of the iterators with the smallest key - void UpdateCurrent(); - - // seek on immutable_ and update prev_key - void SeekImmutable(const Slice& target); -}; - -} // namespace rocksdb -#endif // ROCKSDB_LITE