]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
os/kstore: bring support for omap_iterate
authorRadoslaw Zarzynski <rzarzyns@redhat.com>
Tue, 26 Nov 2024 19:00:16 +0000 (19:00 +0000)
committerRadoslaw Zarzynski <rzarzyns@redhat.com>
Tue, 14 Jan 2025 13:01:06 +0000 (13:01 +0000)
Signed-off-by: Radoslaw Zarzynski <rzarzyns@redhat.com>
(cherry picked from commit e3df536e591c80a859fba95ab958341fd822739b)

src/os/kstore/KStore.cc
src/os/kstore/KStore.h

index 9cd1268023f9a7819a05c2c50e76f37886aec9e3..a069d429155a80f85bf3bcbc17d428e2962000f1 100644 (file)
@@ -1873,6 +1873,71 @@ ObjectMap::ObjectMapIterator KStore::get_omap_iterator(
   return ObjectMap::ObjectMapIterator(new OmapIteratorImpl(c, o, it));
 }
 
+int KStore::omap_iterate(
+  CollectionHandle &ch,   ///< [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)
+{
+  dout(10) << __func__ << " " << ch->cid << " " << oid << dendl;
+  Collection *c = static_cast<Collection*>(ch.get());
+  {
+    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__ << " header = " << o->onode.omap_head <<dendl;
+
+    KeyValueDB::Iterator it = db->get_iterator(PREFIX_OMAP);
+    std::string tail;
+    std::string seek_key;
+    if (o->onode.omap_head) {
+      return 0; // nothing to do
+    }
+
+    // acquire data depedencies for seek & iterate
+    get_omap_key(o->onode.omap_head, start_from.seek_position, &seek_key);
+    get_omap_tail(o->onode.omap_head, &tail);
+
+    // acquire the iterator
+    {
+      it = db->get_iterator(PREFIX_OMAP);
+    }
+
+    // seek the iterator
+    {
+      if (start_from.seek_type == omap_iter_seek_t::LOWER_BOUND) {
+        it->lower_bound(seek_key);
+      } else {
+        it->upper_bound(seek_key);
+      }
+    }
+
+    // iterate!
+    while (it->valid()) {
+      std::string user_key;
+      if (const auto& db_key = it->raw_key().second; db_key >= tail) {
+        break;
+      } else {
+        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
index 4cef5b1039aca20903a84b2c8f21e572feaea9b7..06115d3cab7c24703f2d07bf45e75035481479f7 100644 (file)
@@ -554,6 +554,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;
   }