]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
os/bluestore: implement the lightweight OMAP iteration
authorRadoslaw Zarzynski <rzarzyns@redhat.com>
Sat, 12 Oct 2024 10:13:36 +0000 (10:13 +0000)
committerRadoslaw Zarzynski <rzarzyns@redhat.com>
Tue, 14 Jan 2025 12:50:36 +0000 (12:50 +0000)
Signed-off-by: Radoslaw Zarzynski <rzarzyns@redhat.com>
(cherry picked from commit 87d6447079e18f601703d7e8ffec3fc2d33a4c4e)

src/os/bluestore/BlueStore.cc
src/os/bluestore/BlueStore.h

index 7c263397153d36319d69c01d10366680e7dfe1af..1efd4cc1a19190687f68496b91638beafe7f9032 100644 (file)
@@ -13458,6 +13458,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
 
index 06dc691b7f144764db4af3222c6137b1a728e9da..fe2257d375a1b9f79072f058a119181269d173d7 100644 (file)
@@ -3315,6 +3315,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;
   }