}
int cls_cxx_map_get_vals(cls_method_context_t hctx,
- const string &start_obj,
- const string &filter_prefix,
- uint64_t max_to_get,
- map<string, bufferlist> *vals,
- bool *more)
+ const std::string& start_obj,
+ const std::string& filter_prefix,
+ const uint64_t max_to_get,
+ std::map<std::string, ceph::bufferlist> *vals,
+ bool* const more)
{
- return 0;
+ OSDOp op{ CEPH_OSD_OP_OMAPGETVALS };
+ encode(start_obj, op.indata);
+ encode(max_to_get, op.indata);
+ encode(filter_prefix, op.indata);
+ try {
+ reinterpret_cast<ceph::osd::OpsExecuter*>(hctx)->do_osd_op(op).get();
+ } catch (ceph::osd::error& e) {
+ return -e.code().value();
+ }
+ try {
+ auto iter = op.outdata.cbegin();
+ decode(*vals, iter);
+ decode(*more, iter);
+ } catch (buffer::error&) {
+ return -EIO;
+ }
+ return vals->size();
}
int cls_cxx_map_read_header(cls_method_context_t hctx, bufferlist *outbl)
return do_read_op([&osd_op] (auto& backend, const auto& os) {
return backend.omap_get_keys(os, osd_op);
});
+ case CEPH_OSD_OP_OMAPGETVALS:
+ return do_read_op([&osd_op] (auto& backend, const auto& os) {
+ return backend.omap_get_vals(os, osd_op);
+ });
case CEPH_OSD_OP_OMAPGETVALSBYKEYS:
return do_read_op([&osd_op] (auto& backend, const auto& os) {
return backend.omap_get_vals_by_keys(os, osd_op);
//ctx->delta_stats.num_rd++;
}
+seastar::future<> PGBackend::omap_get_vals(
+ const ObjectState& os,
+ OSDOp& osd_op) const
+{
+ std::string start_after;
+ uint64_t max_return;
+ std::string filter_prefix;
+ try {
+ auto p = osd_op.indata.cbegin();
+ decode(start_after, p);
+ decode(max_return, p);
+ decode(filter_prefix, p);
+ } catch (buffer::error&) {
+ throw ceph::osd::invalid_argument{};
+ }
+
+ max_return = \
+ std::min(max_return, local_conf()->osd_max_omap_entries_per_request);
+
+ // TODO: truly chunk the reading
+ return maybe_get_omap_vals(store, coll, os.oi, start_after).then(
+ [=, &osd_op] (const bool done,
+ ceph::os::FuturizedStore::omap_values_t vals) {
+ assert(done);
+ ceph::bufferlist result;
+ bool truncated = false;
+ uint32_t num = 0;
+ auto iter = filter_prefix > start_after ? vals.lower_bound(filter_prefix)
+ : std::begin(vals);
+ for (; iter != std::end(vals); ++iter) {
+ const auto& [key, value] = *iter;
+ if (key.substr(0, filter_prefix.size()) != filter_prefix) {
+ break;
+ } else if (num++ >= max_return ||
+ result.length() >= local_conf()->osd_max_omap_bytes_per_request) {
+ truncated = true;
+ break;
+ }
+ encode(key, result);
+ encode(value, result);
+ }
+ encode(num, osd_op.outdata);
+ osd_op.outdata.claim_append(result);
+ encode(truncated, osd_op.outdata);
+ return seastar::now();
+ });
+
+ // TODO:
+ //ctx->delta_stats.num_rd_kb += shift_round_up(osd_op.outdata.length(), 10);
+ //ctx->delta_stats.num_rd++;
+}
seastar::future<> PGBackend::omap_get_vals_by_keys(
const ObjectState& os,
OSDOp& osd_op) const
seastar::future<> omap_get_keys(
const ObjectState& os,
OSDOp& osd_op) const;
+ seastar::future<> omap_get_vals(
+ const ObjectState& os,
+ OSDOp& osd_op) const;
seastar::future<> omap_get_vals_by_keys(
const ObjectState& os,
OSDOp& osd_op) const;