namespace crimson::os::seastore {
+constexpr uint16_t MAX_FIXEDKVBTREE_DEPTH = 8;
+
template <typename T>
struct min_max_t {};
using index_t = boost::intrusive::set<btree_range_pin_t>;
- static auto get_tuple(const fixed_kv_node_meta_t<node_bound_t> &meta) {
- return std::make_tuple(-meta.depth, meta.begin);
- }
-
void acquire_ref() {
ref = CachedExtentRef(extent);
}
friend bool operator<(
const btree_range_pin_t &lhs, const btree_range_pin_t &rhs) {
- return get_tuple(lhs.range) < get_tuple(rhs.range);
+ assert(lhs.range.depth == rhs.range.depth);
+ return lhs.range.begin < rhs.range.begin;
}
friend bool operator>(
const btree_range_pin_t &lhs, const btree_range_pin_t &rhs) {
- return get_tuple(lhs.range) > get_tuple(rhs.range);
+ assert(lhs.range.depth == rhs.range.depth);
+ return lhs.range.begin > rhs.range.begin;
}
friend bool operator==(
const btree_range_pin_t &lhs, const btree_range_pin_t &rhs) {
- return get_tuple(lhs.range) == rhs.get_tuple(rhs.range);
+ assert(lhs.range.depth == rhs.range.depth);
+ return lhs.range.begin == rhs.range.begin;
}
struct meta_cmp_t {
bool operator()(
const btree_range_pin_t &lhs, const fixed_kv_node_meta_t<node_bound_t> &rhs) const {
- return get_tuple(lhs.range) < get_tuple(rhs);
+ assert(lhs.range.depth == rhs.depth);
+ return lhs.range.begin < rhs.begin;
}
bool operator()(
const fixed_kv_node_meta_t<node_bound_t> &lhs, const btree_range_pin_t &rhs) const {
- return get_tuple(lhs) < get_tuple(rhs.range);
+ assert(lhs.depth == rhs.range.depth);
+ return lhs.begin < rhs.range.begin;
}
};
template <typename node_bound_t>
class btree_pin_set_t {
friend class btree_range_pin_t<node_bound_t>;
- using pins_t = typename btree_range_pin_t<node_bound_t>::index_t;
- pins_t pins;
+ using pins_by_depth_t = std::array<
+ typename btree_range_pin_t<node_bound_t>::index_t,
+ MAX_FIXEDKVBTREE_DEPTH>;
+ pins_by_depth_t pins_by_depth;
/// Removes pin from set optionally checking whether parent has other children
void remove_pin(btree_range_pin_t<node_bound_t> &pin, bool do_check_parent)
ceph_assert(pin.pins);
ceph_assert(!pin.ref);
- pins.erase(pin);
+ auto &layer = pins_by_depth[pin.range.depth];
+ layer.erase(layer.s_iterator_to(pin));
pin.pins = nullptr;
if (do_check_parent) {
btree_range_pin_t<node_bound_t> &to,
btree_range_pin_t<node_bound_t> &from)
{
- pins.replace_node(pins.iterator_to(from), to);
+ assert(to.range.depth == from.range.depth);
+ pins_by_depth[from.range.depth].replace_node(
+ btree_range_pin_t<node_bound_t>::index_t::s_iterator_to(from), to);
}
/// Returns parent pin if exists
{
auto cmeta = meta;
cmeta.depth++;
- auto iter = pins.upper_bound(
+ auto &layer = pins_by_depth[cmeta.depth];
+ auto iter = layer.upper_bound(
cmeta,
typename btree_range_pin_t<node_bound_t>::meta_cmp_t());
- if (iter == pins.begin()) {
+ if (iter == layer.begin()) {
return nullptr;
} else {
--iter;
auto cmeta = meta;
cmeta.depth--;
- auto iter = pins.lower_bound(
+ auto &layer = pins_by_depth[cmeta.depth];
+ auto iter = layer.lower_bound(
cmeta,
typename btree_range_pin_t<node_bound_t>::meta_cmp_t());
- if (iter == pins.end()) {
+ if (iter == layer.end()) {
return nullptr;
} else if (meta.is_parent_of(iter->range)) {
return &*iter;
}
public:
+ btree_pin_set_t() {}
/// Adds pin to set, assumes set is consistent
void add_pin(btree_range_pin_t<node_bound_t> &pin)
{
ceph_assert(!pin.pins);
ceph_assert(!pin.ref);
- auto [prev, inserted] = pins.insert(pin);
+ auto &layer = pins_by_depth[pin.range.depth];
+ auto [prev, inserted] = layer.insert(pin);
if (!inserted) {
crimson::get_logger(ceph_subsys_seastore_lba).error(
"{}: unable to add {} ({}), found {} ({})",
template <typename F>
void scan(F &&f) {
- for (auto &i : pins) {
- std::invoke(f, i);
+ for (auto &layer : pins_by_depth) {
+ for (auto &i : layer) {
+ std::invoke(f, i);
+ }
}
}
~btree_pin_set_t() {
- ceph_assert(pins.empty());
+ for (auto &layer : pins_by_depth) {
+ ceph_assert(layer.empty());
+ }
}
};