namespace crimson::os::seastore {
-constexpr size_t MAX_SIZE = std::numeric_limits<size_t>::max();
std::ostream &operator<<(std::ostream &out, const std::list<std::string> &rhs);
std::ostream &operator<<(std::ostream &out, const std::map<std::string, std::string> &rhs);
* it it is not set, list all keys after string start.
* @retval listed key->value mapping and next key
*/
+ struct omap_list_config_t {
+ size_t max_result_size = 128;
+ bool inclusive = false;
+
+ omap_list_config_t(
+ size_t max_result_size,
+ bool inclusive)
+ : max_result_size(max_result_size),
+ inclusive(inclusive) {}
+ omap_list_config_t() {}
+ omap_list_config_t(const omap_list_config_t &) = default;
+ omap_list_config_t(omap_list_config_t &&) = default;
+ omap_list_config_t &operator=(const omap_list_config_t &) = default;
+ omap_list_config_t &operator=(omap_list_config_t &&) = default;
+
+ static omap_list_config_t with_max(size_t max) {
+ omap_list_config_t ret{};
+ ret.max_result_size = max;
+ return ret;
+ }
+
+ static omap_list_config_t with_inclusive(bool inclusive) {
+ omap_list_config_t ret{};
+ ret.inclusive = inclusive;
+ return ret;
+ }
+
+ auto with_reduced_max(size_t reduced_by) const {
+ assert(reduced_by <= max_result_size);
+ return omap_list_config_t(
+ max_result_size - reduced_by,
+ inclusive
+ );
+ }
+ };
using omap_list_ertr = base_ertr;
using omap_list_bare_ret = std::pair<
bool,
- std::map<std::string, bufferlist>>;
+ std::map<std::string, bufferlist, std::less<>>>;
using omap_list_ret = omap_list_ertr::future<omap_list_bare_ret>;
virtual omap_list_ret omap_list(
const omap_root_t &omap_root,
Transaction &t,
const std::optional<std::string> &start,
- size_t max_result_size = MAX_SIZE) = 0;
+ omap_list_config_t config = omap_list_config_t()) = 0;
/**
* clear all omap tree key->value mapping
root_extent->set_size(0);
omap_node_meta_t meta{1};
root_extent->set_meta(meta);
- omap_root_t omap_root = omap_root_t(root_extent->get_laddr(), 1);
+ omap_root_t omap_root;
+ omap_root.update(root_extent->get_laddr(), 1);
return initialize_omap_ertr::make_ready_future<omap_root_t>(omap_root);
});
}
const omap_root_t &omap_root,
Transaction &t,
const std::optional<std::string> &start,
- size_t max_result_size = MAX_SIZE)
+ omap_list_config_t config)
{
logger().debug("{}", __func__);
return get_omap_root(
get_omap_context(t),
omap_root
- ).safe_then([this, &t, &start, max_result_size](auto extent) {
- return extent->list(get_omap_context(t), start, max_result_size);
+ ).safe_then([this, config, &t, &start](auto extent) {
+ return extent->list(
+ get_omap_context(t),
+ start,
+ config);
});
}
const omap_root_t &omap_root,
Transaction &t,
const std::optional<std::string> &start,
- size_t max_result_size) final;
+ omap_list_config_t config = omap_list_config_t()) final;
omap_clear_ret omap_clear(
omap_root_t &omap_root,
omap_context_t oc,
const std::string &key) = 0;
+ using omap_list_config_t = OMapManager::omap_list_config_t;
using list_ertr = base_ertr;
using list_bare_ret = OMapManager::omap_list_bare_ret;
using list_ret = OMapManager::omap_list_ret;
virtual list_ret list(
omap_context_t oc,
const std::optional<std::string> &start,
- size_t max_result_size) = 0;
+ omap_list_config_t config) = 0;
using clear_ertr = base_ertr;
using clear_ret = clear_ertr::future<>;
OMapInnerNode::list(
omap_context_t oc,
const std::optional<std::string> &start,
- size_t max_result_size)
+ omap_list_config_t config)
{
logger().debug("OMapInnerNode: {}", __func__);
[=, &start](auto &biter, auto &eiter, auto &ret) {
auto &[complete, result] = ret;
return crimson::do_until(
- [&, &complete=complete, &result=result, max_result_size, oc, this]()
- -> list_ertr::future<bool> {
- if (biter == eiter || result.size() == max_result_size) {
+ [&, config, oc, this]() -> list_ertr::future<bool> {
+ if (biter == eiter || result.size() == config.max_result_size) {
complete = biter == eiter;
return list_ertr::make_ready_future<bool>(true);
}
return omap_load_extent(
oc, laddr,
get_meta().depth - 1
- ).safe_then([&, max_result_size, oc] (auto &&extent) {
+ ).safe_then([&, config, oc, this] (auto &&extent) {
return extent->list(
oc,
start,
- max_result_size - result.size()
- ).safe_then([&, max_result_size](auto &&child_ret) mutable {
+ config.with_reduced_max(result.size())
+ ).safe_then([&, config, this](auto &&child_ret) mutable {
auto &[child_complete, child_result] = child_ret;
if (result.size() && child_result.size()) {
assert(child_result.begin()->first > result.rbegin()->first);
child_result.begin(),
child_result.end());
biter++;
- (void)max_result_size;
- assert(child_complete || result.size() == max_result_size);
+ assert(child_complete || result.size() == config.max_result_size);
return list_ertr::make_ready_future<bool>(false);
});
});
OMapLeafNode::list(
omap_context_t oc,
const std::optional<std::string> &start,
- size_t max_result_size)
+ omap_list_config_t config)
{
logger().debug(
- "OMapLeafNode::{} start {} max_result_size {}",
+ "OMapLeafNode::{} start {} max_result_size {} inclusive {}",
__func__,
start ? start->c_str() : "",
- max_result_size
+ config.max_result_size,
+ config.inclusive
);
auto ret = list_bare_ret(false, {});
auto &[complete, result] = ret;
auto iter = start ?
- string_upper_bound(*start) :
+ (config.inclusive ?
+ string_lower_bound(*start) :
+ string_upper_bound(*start)) :
iter_begin();
- for (; iter != iter_end() && result.size() < max_result_size; iter++) {
+ for (; iter != iter_end() && result.size() < config.max_result_size; iter++) {
result.emplace(std::make_pair(iter->get_key(), iter->get_val()));
}
list_ret list(
omap_context_t oc,
const std::optional<std::string> &start,
- size_t max_result_size) final;
+ omap_list_config_t config) final;
clear_ret clear(omap_context_t oc) final;
list_ret list(
omap_context_t oc,
const std::optional<std::string> &start,
- size_t max_result_size) final;
+ omap_list_config_t config) final;
clear_ret clear(
omap_context_t oc) final;
const omap_root_t &omap_root,
Transaction &t,
const std::optional<std::string> &start,
- size_t max = MAX_SIZE) {
+ size_t max = 128) {
if (start) {
logger().debug("list on {}", *start);
logger().debug("list on start");
}
+ auto config = OMapManager::omap_list_config_t::with_max(max);
+ config.max_result_size = max;
auto [complete, results] = omap_manager->omap_list(
- omap_root, t, start, max
+ omap_root, t, start, config
).unsafe_get0();
auto it = start ?