@@ -1873,6 +1873,71 @@ ObjectMap::ObjectMapIterator KStore::get_omap_iterator(
18731873 return ObjectMap::ObjectMapIterator (new OmapIteratorImpl (c, o, it));
18741874}
18751875
1876+ int KStore::omap_iterate (
1877+ CollectionHandle &ch, // /< [in] collection
1878+ const ghobject_t &oid, // /< [in] object
1879+ ObjectStore::omap_iter_seek_t start_from, // /< [in] where the iterator should point to at the beginning
1880+ std::function<omap_iter_ret_t (std::string_view, std::string_view)> f)
1881+ {
1882+ dout (10 ) << __func__ << " " << ch->cid << " " << oid << dendl;
1883+ Collection *c = static_cast <Collection*>(ch.get ());
1884+ {
1885+ std::shared_lock l{c->lock };
1886+
1887+ OnodeRef o = c->get_onode (oid, false );
1888+ if (!o || !o->exists ) {
1889+ dout (10 ) << __func__ << " " << oid << " doesn't exist" <<dendl;
1890+ return -ENOENT;
1891+ }
1892+ o->flush ();
1893+ dout (10 ) << __func__ << " header = " << o->onode .omap_head <<dendl;
1894+
1895+ KeyValueDB::Iterator it = db->get_iterator (PREFIX_OMAP);
1896+ std::string tail;
1897+ std::string seek_key;
1898+ if (o->onode .omap_head ) {
1899+ return 0 ; // nothing to do
1900+ }
1901+
1902+ // acquire data depedencies for seek & iterate
1903+ get_omap_key (o->onode .omap_head , start_from.seek_position , &seek_key);
1904+ get_omap_tail (o->onode .omap_head , &tail);
1905+
1906+ // acquire the iterator
1907+ {
1908+ it = db->get_iterator (PREFIX_OMAP);
1909+ }
1910+
1911+ // seek the iterator
1912+ {
1913+ if (start_from.seek_type == omap_iter_seek_t ::LOWER_BOUND) {
1914+ it->lower_bound (seek_key);
1915+ } else {
1916+ it->upper_bound (seek_key);
1917+ }
1918+ }
1919+
1920+ // iterate!
1921+ while (it->valid ()) {
1922+ std::string user_key;
1923+ if (const auto & db_key = it->raw_key ().second ; db_key >= tail) {
1924+ break ;
1925+ } else {
1926+ decode_omap_key (db_key, &user_key);
1927+ }
1928+ omap_iter_ret_t ret = f (user_key, it->value_as_sv ());
1929+ if (ret == omap_iter_ret_t ::STOP) {
1930+ break ;
1931+ } else if (ret == omap_iter_ret_t ::NEXT) {
1932+ it->next ();
1933+ } else {
1934+ ceph_abort ();
1935+ }
1936+ }
1937+ }
1938+ return 0 ;
1939+ }
1940+
18761941
18771942// -----------------
18781943// write helpers
0 commit comments