summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRadoslaw Zarzynski <rzarzyns@redhat.com>2024-10-12 12:13:36 +0200
committerRadoslaw Zarzynski <rzarzyns@redhat.com>2024-12-17 19:10:28 +0100
commit87d6447079e18f601703d7e8ffec3fc2d33a4c4e (patch)
treeb99b73096c155c0a4b6273cee5d51f646b47f966
parentkv: avoid memcpy in OMAP iterator of KeyValueDB (diff)
downloadceph-87d6447079e18f601703d7e8ffec3fc2d33a4c4e.tar.xz
ceph-87d6447079e18f601703d7e8ffec3fc2d33a4c4e.zip
os/bluestore: implement the lightweight OMAP iteration
Signed-off-by: Radoslaw Zarzynski <rzarzyns@redhat.com>
-rw-r--r--src/os/bluestore/BlueStore.cc70
-rw-r--r--src/os/bluestore/BlueStore.h7
2 files changed, 77 insertions, 0 deletions
diff --git a/src/os/bluestore/BlueStore.cc b/src/os/bluestore/BlueStore.cc
index 57d53d3dba4..ee5393f6608 100644
--- a/src/os/bluestore/BlueStore.cc
+++ b/src/os/bluestore/BlueStore.cc
@@ -13734,6 +13734,76 @@ ObjectMap::ObjectMapIterator BlueStore::get_omap_iterator(
return ObjectMap::ObjectMapIterator(new OmapIteratorImpl(logger,c, o, it));
}
+int BlueStore::omap_iterate(
+ CollectionHandle &c_, ///< [in] collection
+ const ghobject_t &oid, ///< [in] object
+ ObjectStore::omap_iter_seek_t start_from, ///< [in] where the iterator should point to at the beginning
+ std::function<omap_iter_ret_t(std::string_view, std::string_view)> f
+ )
+{
+ Collection *c = static_cast<Collection *>(c_.get());
+ dout(10) << __func__ << " " << c->get_cid() << " " << oid << dendl;
+ if (!c->exists) {
+ return -ENOENT;
+ }
+ std::shared_lock l(c->lock);
+ OnodeRef o = c->get_onode(oid, false);
+ if (!o || !o->exists) {
+ dout(10) << __func__ << " " << oid << "doesn't exist" <<dendl;
+ return -ENOENT;
+ }
+ o->flush();
+ dout(10) << __func__ << " has_omap = " << (int)o->onode.has_omap() <<dendl;
+ if (!o->onode.has_omap()) {
+ // nothing to do
+ return 0;
+ }
+
+ KeyValueDB::Iterator it;
+ {
+ auto bounds = KeyValueDB::IteratorBounds();
+ std::string lower_bound, upper_bound;
+ o->get_omap_key(string(), &lower_bound);
+ o->get_omap_tail(&upper_bound);
+ bounds.lower_bound = std::move(lower_bound);
+ bounds.upper_bound = std::move(upper_bound);
+ it = db->get_iterator(o->get_omap_prefix(), 0, std::move(bounds));
+ }
+
+ // seek the iterator
+ {
+ std::string key;
+ o->get_omap_key(start_from.seek_position, &key);
+ if (start_from.seek_type == omap_iter_seek_t::LOWER_BOUND) {
+ it->lower_bound(key);
+ } else {
+ it->upper_bound(key);
+ }
+ }
+
+ // iterate!
+ std::string tail;
+ o->get_omap_tail(&tail);
+ while (it->valid()) {
+ std::string user_key;
+ if (const auto& db_key = it->raw_key().second; db_key >= tail) {
+ break;
+ } else {
+ o->decode_omap_key(db_key, &user_key);
+ }
+ omap_iter_ret_t ret = f(user_key, it->value_as_sv());
+ if (ret == omap_iter_ret_t::STOP) {
+ break;
+ } else if (ret == omap_iter_ret_t::NEXT) {
+ it->next();
+ } else {
+ ceph_abort();
+ }
+ }
+
+ return 0;
+}
+
// -----------------
// write helpers
diff --git a/src/os/bluestore/BlueStore.h b/src/os/bluestore/BlueStore.h
index a067f256813..dc1a3edda5d 100644
--- a/src/os/bluestore/BlueStore.h
+++ b/src/os/bluestore/BlueStore.h
@@ -3423,6 +3423,13 @@ public:
const ghobject_t &oid ///< [in] object
) override;
+ int omap_iterate(
+ CollectionHandle &c, ///< [in] collection
+ const ghobject_t &oid, ///< [in] object
+ omap_iter_seek_t start_from, ///< [in] where the iterator should point to at the beginning
+ std::function<omap_iter_ret_t(std::string_view, std::string_view)> f
+ ) override;
+
void set_fsid(uuid_d u) override {
fsid = u;
}