std::pair<K, V> *next ///< [out] first key after key
) = 0; ///< @return 0 on success, -ENOENT if there is no next
+ virtual int get_next_or_current(
+ const K &key, ///< [in] key at-which-or-after to get
+ std::pair<K, V> *next_or_current
+ ) = 0; ///< @return 0 on success, -ENOENT if there is no next
+
virtual ~StoreDriver() {}
};
int OSDriver::get_next(
const std::string &key,
- pair<std::string, ceph::buffer::list> *next)
+ std::pair<std::string, ceph::buffer::list> *next)
{
ObjectMap::ObjectMapIterator iter =
os->get_omap_iterator(ch, hoid);
}
}
+int OSDriver::get_next_or_current(
+ const std::string &key,
+ std::pair<std::string, ceph::buffer::list> *next_or_current)
+{
+ ObjectMap::ObjectMapIterator iter =
+ os->get_omap_iterator(ch, hoid);
+ if (!iter) {
+ ceph_abort();
+ return -EINVAL;
+ }
+ iter->lower_bound(key);
+ if (iter->valid()) {
+ if (next_or_current)
+ *next_or_current = make_pair(iter->key(), iter->value());
+ return 0;
+ } else {
+ return -ENOENT;
+ }
+}
+
string SnapMapper::get_prefix(int64_t pool, snapid_t snap)
{
static_assert(sizeof(pool) == 8, "assumed by the formatting code");
int64_t pool, snapid_t snap,
snapid_t *begin, snapid_t *end)
{
+ OSDriver backend(store, ch, hoid);
string k = make_purged_snap_key(pool, snap);
- auto it = store->get_omap_iterator(ch, hoid);
- it->lower_bound(k);
- if (!it->valid()) {
+ std::pair<std::string, ceph::buffer::list> kv;
+ if (auto ret = backend.get_next_or_current(k, &kv); ret == -ENOENT) {
dout(20) << __func__ << " pool " << pool << " snap " << snap
<< " key '" << k << "' lower_bound not found" << dendl;
return -ENOENT;
}
- if (it->key().find(PURGED_SNAP_PREFIX) != 0) {
+ if (kv.first.find(PURGED_SNAP_PREFIX) != 0) {
dout(20) << __func__ << " pool " << pool << " snap " << snap
<< " key '" << k << "' lower_bound got mismatched prefix '"
- << it->key() << "'" << dendl;
+ << kv.first << "'" << dendl;
return -ENOENT;
}
- ceph::buffer::list v = it->value();
+ ceph::buffer::list v = kv.second;
auto p = v.cbegin();
int64_t gotpool;
decode(gotpool, p);
}
OSDriver(ObjectStore *os, const coll_t& cid, const ghobject_t &hoid) :
+ OSDriver(os, os->open_collection(cid), hoid) {}
+ OSDriver(ObjectStore *os, ObjectStore::CollectionHandle ch, const ghobject_t &hoid) :
os(os),
- hoid(hoid) {
- ch = os->open_collection(cid);
- }
+ ch(ch),
+ hoid(hoid) {}
+
int get_keys(
const std::set<std::string> &keys,
std::map<std::string, ceph::buffer::list> *out) override;
int get_next(
const std::string &key,
std::pair<std::string, ceph::buffer::list> *next) override;
+ int get_next_or_current(
+ const std::string &key,
+ std::pair<std::string, ceph::buffer::list> *next_or_current) override;
};
/**
return -ENOENT;
}
}
+ int get_next_or_current(
+ const string &key,
+ pair<string, bufferlist> *next_or_current) override {
+ std::lock_guard l{lock};
+ map<string, bufferlist>::iterator j = store.lower_bound(key);
+ if (j != store.end()) {
+ if (next_or_current)
+ *next_or_current = *j;
+ return 0;
+ } else {
+ return -ENOENT;
+ }
+ }
void submit(Transaction *t) {
doer.submit(t->ops);
doer.submit(t->callbacks);