/
GraphTreeHeap
/
museumdb2
Обзор
Документация
Войти
/
GraphTreeHeap
/
museumdb2
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
db/multi_scan.cc
91 строка
3 KB
Andrew Chang
Fix MultiScan not respecting SupportedOps for async IO (#14510)
26 мар 2026, 19:24
26 мар 2026, 19:24
453ebd6
Код
Авторство
О чём код?
// 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 "file/file_util.h" #include "rocksdb/db.h" #include "rocksdb/file_system.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_([&] { // Disable async IO if the filesystem does not support it, consistent // with how ArenaWrappedDBIter::Init() handles ReadOptions::async_io. auto opts = scan_opts; if (opts.use_async_io && !CheckFSFeatureSupport(db->GetFileSystem(), FSSupportedOps::kAsyncIO)) { opts.use_async_io = false; } return 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