From: Radoslaw Zarzynski Date: Tue, 26 Nov 2024 00:54:54 +0000 (+0000) Subject: osd: ReplicatedBackend::build_push_op switch to omap_iterate X-Git-Tag: v20.3.0~156^2~19 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=c633477822f8329b36d97bfdcfacbdc4e66d3b00;p=ceph.git osd: ReplicatedBackend::build_push_op switch to omap_iterate Signed-off-by: Radoslaw Zarzynski --- diff --git a/src/osd/ReplicatedBackend.cc b/src/osd/ReplicatedBackend.cc index e11a801cfdc..7fac267eb93 100644 --- a/src/osd/ReplicatedBackend.cc +++ b/src/osd/ReplicatedBackend.cc @@ -2127,6 +2127,12 @@ void ReplicatedBackend::send_pulls(int prio, map > &p } } +static bufferlist to_bufferlist(std::string_view in) { + bufferlist bl; + bl.append(in); + return bl; +} + int ReplicatedBackend::build_push_op(const ObjectRecoveryInfo &recovery_info, const ObjectRecoveryProgress &progress, ObjectRecoveryProgress *out_progress, @@ -2188,29 +2194,43 @@ int ReplicatedBackend::build_push_op(const ObjectRecoveryInfo &recovery_info, uint64_t available = cct->_conf->osd_recovery_max_chunk; if (!progress.omap_complete) { - ObjectMap::ObjectMapIterator iter = - store->get_omap_iterator(ch, - ghobject_t(recovery_info.soid)); - ceph_assert(iter); - for (iter->lower_bound(progress.omap_recovered_to); - iter->valid(); - iter->next()) { - if (!out_op->omap_entries.empty() && - ((cct->_conf->osd_recovery_max_omap_entries_per_chunk > 0 && - out_op->omap_entries.size() >= cct->_conf->osd_recovery_max_omap_entries_per_chunk) || - available <= iter->key().size() + iter->value().length())) - break; - out_op->omap_entries.insert(make_pair(iter->key(), iter->value())); - - if ((iter->key().size() + iter->value().length()) <= available) - available -= (iter->key().size() + iter->value().length()); - else - available = 0; - } - if (!iter->valid()) + std::optional more_from; + using omap_iter_seek_t = ObjectStore::omap_iter_seek_t; + auto result = store->omap_iterate( + ch, + ghobject_t{recovery_info.soid}, + // try to seek as many keys-at-once as possible for the sake of performance. + // note complexity should be logarithmic, so seek(n/2) + seek(n/2) is worse + // than just seek(n). + ObjectStore::omap_iter_seek_t{ + .seek_position = progress.omap_recovered_to, + .seek_type = omap_iter_seek_t::LOWER_BOUND + }, + [&available, &more_from, &omap_entries=out_op->omap_entries, + max_entries=cct->_conf->osd_recovery_max_omap_entries_per_chunk] + (std::string_view key, std::string_view value) mutable { + const auto num_new_bytes = key.size() + value.size(); + if (auto cur_num_entries = omap_entries.size(); cur_num_entries > 0) { + if (max_entries > 0 && cur_num_entries >= max_entries) { + more_from = key; + return ObjectStore::omap_iter_ret_t::STOP; + } + if (num_new_bytes >= available) { + more_from = key; + return ObjectStore::omap_iter_ret_t::STOP; + } + } + omap_entries.insert(make_pair(key, to_bufferlist(value))); + available -= std::min(available, num_new_bytes); + return ObjectStore::omap_iter_ret_t::NEXT; + }); + if (result < 0) { + return -EIO; + } else if (more_from) { + new_progress.omap_recovered_to = *more_from; + } else { new_progress.omap_complete = true; - else - new_progress.omap_recovered_to = iter->key(); + } } if (available > 0) {