// Copyright (c) 2011-present, Facebook, Inc. All rights reserved. // This source code is licensed under both the GPLv2 (found in the // COPYING file in the root directory) and Apache 2.0 License // (found in the LICENSE.Apache file in the root directory). #pragma once #ifndef ROCKSDB_LITE #include "rocksdb/iterator.h" #include "utilities/blob_db/blob_db_impl.h" namespace rocksdb { namespace blob_db { using rocksdb::ManagedSnapshot; class BlobDBIterator : public Iterator { public: BlobDBIterator(ManagedSnapshot* snapshot, ArenaWrappedDBIter* iter, BlobDBImpl* blob_db) : snapshot_(snapshot), iter_(iter), blob_db_(blob_db) {} virtual ~BlobDBIterator() = default; bool Valid() const override { if (!iter_->Valid()) { return false; } return status_.ok(); } Status status() const override { if (!iter_->status().ok()) { return iter_->status(); } return status_; } void SeekToFirst() override { iter_->SeekToFirst(); UpdateBlobValue(); } void SeekToLast() override { iter_->SeekToLast(); UpdateBlobValue(); } void Seek(const Slice& target) override { iter_->Seek(target); UpdateBlobValue(); } void SeekForPrev(const Slice& target) override { iter_->SeekForPrev(target); UpdateBlobValue(); } void Next() override { assert(Valid()); iter_->Next(); UpdateBlobValue(); } void Prev() override { assert(Valid()); iter_->Prev(); UpdateBlobValue(); } Slice key() const override { assert(Valid()); return iter_->key(); } Slice value() const override { assert(Valid()); if (!iter_->IsBlob()) { return iter_->value(); } return value_; } // Iterator::Refresh() not supported. private: void UpdateBlobValue() { TEST_SYNC_POINT("BlobDBIterator::UpdateBlobValue:Start:1"); TEST_SYNC_POINT("BlobDBIterator::UpdateBlobValue:Start:2"); value_.Reset(); if (iter_->Valid() && iter_->IsBlob()) { status_ = blob_db_->GetBlobValue(iter_->key(), iter_->value(), &value_); } } std::unique_ptr snapshot_; std::unique_ptr iter_; BlobDBImpl* blob_db_; Status status_; PinnableSlice value_; }; } // namespace blob_db } // namespace rocksdb #endif // !ROCKSDB_LITE