| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 |
- // Copyright (c) Meta Platforms, Inc. and affiliates.
- // 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).
- #include "rocksdb/db.h"
- namespace ROCKSDB_NAMESPACE {
- using MultiScanIterator = MultiScan::MultiScanIterator;
- MultiScan::MultiScan(const ReadOptions& read_options,
- const MultiScanArgs& scan_opts, DB* db,
- ColumnFamilyHandle* cfh)
- : read_options_(read_options), scan_opts_(scan_opts), db_(db), cfh_(cfh) {
- bool slow_path = false;
- // Setup read_options with iterate_uuper_bound based on the first scan.
- // Subsequent scans will update and allocate a new DB iterator as necessary
- if (scan_opts.GetScanRanges()[0].range.limit) {
- upper_bound_ = *scan_opts.GetScanRanges()[0].range.limit;
- read_options_.iterate_upper_bound = &upper_bound_;
- } else {
- read_options_.iterate_upper_bound = nullptr;
- }
- for (const auto& opts : scan_opts.GetScanRanges()) {
- // Check that all the ScanOptions either specify an upper bound or not. If
- // its mixed we take the slow path which avoids calling Prepare: we have to
- // reallocate the Iterator with updated read_options everytime we switch
- // between upper bound or no upper bound, which complicates Prepare.
- if (opts.range.limit.has_value() !=
- scan_opts.GetScanRanges()[0].range.limit.has_value()) {
- slow_path = true;
- break;
- }
- }
- db_iter_.reset(db->NewIterator(read_options_, cfh));
- if (!slow_path) {
- db_iter_->Prepare(scan_opts);
- }
- }
- MultiScanIterator& MultiScanIterator::operator++() {
- status_ = db_iter_->status();
- if (!status_.ok()) {
- throw MultiScanException(status_);
- }
- if (idx_ >= scan_opts_.size()) {
- throw std::logic_error("Index out of range");
- }
- idx_++;
- if (idx_ < scan_opts_.size()) {
- // Check if we need to update read_options_
- if (scan_opts_[idx_].range.limit.has_value() !=
- (read_options_.iterate_upper_bound != nullptr)) {
- if (scan_opts_[idx_].range.limit) {
- *upper_bound_ = *scan_opts_[idx_].range.limit;
- read_options_.iterate_upper_bound = upper_bound_;
- } else {
- read_options_.iterate_upper_bound = nullptr;
- }
- db_iter_.reset(db_->NewIterator(read_options_, cfh_));
- scan_.Reset(db_iter_.get());
- } else if (scan_opts_[idx_].range.limit) {
- *upper_bound_ = *scan_opts_[idx_].range.limit;
- }
- db_iter_->Seek(*scan_opts_[idx_].range.start);
- status_ = db_iter_->status();
- if (!status_.ok()) {
- throw MultiScanException(status_);
- }
- }
- return *this;
- }
- } // namespace ROCKSDB_NAMESPACE
|