* cannot be rewritten) because their parents must be mutated upon remapping.
*/
public:
- TCachedExtentRef<T> find_pending_version(Transaction &t, node_key_t key) {
+ std::pair<bool, TCachedExtentRef<T>> resolve_transaction(
+ Transaction &t, node_key_t key) {
auto &me = down_cast();
- assert(me.is_stable());
- auto mut_iter = me.mutation_pending_extents.find(
- t.get_trans_id(), trans_spec_view_t::cmp_t());
- if (mut_iter != me.mutation_pending_extents.end()) {
- assert(copy_dests_by_trans.find(t.get_trans_id()) ==
- copy_dests_by_trans.end());
- return static_cast<T*>(&(*mut_iter));
+ ceph_assert(me.is_valid());
+ auto [viewable, state] = me.is_viewable_by_trans(t);
+ if (viewable) {
+ return {viewable, &me};
}
- auto iter = copy_dests_by_trans.find(
- t.get_trans_id(), trans_spec_view_t::cmp_t());
- ceph_assert(iter != copy_dests_by_trans.end());
- auto ©_dests = static_cast<copy_dests_t&>(*iter);
- auto it = copy_dests.dests_by_key.lower_bound(key);
- if (it == copy_dests.dests_by_key.end() || (*it)->get_begin() > key) {
- ceph_assert(it != copy_dests.dests_by_key.begin());
- --it;
- }
- ceph_assert((*it)->get_begin() <= key && key < (*it)->get_end());
- return *it;
+ return {viewable, find_pending_version(t, key, state)};
}
template <typename ChildT>
auto &me = down_cast();
maybe_expand_children(me.get_size());
}
+
+ TCachedExtentRef<T> find_pending_version(
+ Transaction &t, node_key_t key, CachedExtent::viewable_state_t &hint) {
+ auto &me = down_cast();
+ assert(me.is_stable());
+ if (hint == CachedExtent::viewable_state_t::stable_become_pending) {
+ auto mut_iter = me.mutation_pending_extents.find(
+ t.get_trans_id(), trans_spec_view_t::cmp_t());
+ assert(mut_iter != me.mutation_pending_extents.end());
+ assert(copy_dests_by_trans.find(t.get_trans_id()) ==
+ copy_dests_by_trans.end());
+ return static_cast<T*>(&(*mut_iter));
+ }
+ ceph_assert(hint == CachedExtent::viewable_state_t::stable_become_retired);
+ auto iter = copy_dests_by_trans.find(
+ t.get_trans_id(), trans_spec_view_t::cmp_t());
+ ceph_assert(iter != copy_dests_by_trans.end());
+ auto ©_dests = static_cast<copy_dests_t&>(*iter);
+ auto it = copy_dests.dests_by_key.lower_bound(key);
+ if (it == copy_dests.dests_by_key.end() || (*it)->get_begin() > key) {
+ ceph_assert(it != copy_dests.dests_by_key.begin());
+ --it;
+ }
+ ceph_assert((*it)->get_begin() <= key && key < (*it)->get_end());
+ return *it;
+ }
+
void add_copy_dest(Transaction &t, TCachedExtentRef<T> dest) {
ceph_assert(down_cast().is_stable());
ceph_assert(dest->is_pending());
// as the parents, so they are ChildNodes.
template <typename ParentT, typename T, typename key_t>
class ChildNode : public BaseChildNode<ParentT, key_t> {
+public:
+ using get_parent_node_iertr = get_child_iertr;
+ using get_parent_node_ret =
+ get_parent_node_iertr::future<TCachedExtentRef<ParentT>>;
+ get_parent_node_ret get_parent_node(
+ Transaction &t,
+ ExtentTransViewRetriever &etvr)
+ {
+ auto &me = down_cast();
+ if (this->has_parent_tracker()) {
+ return this->_get_parent_node(t, etvr, me.get_begin());
+ } else {
+ assert(me.is_mutation_pending());
+ auto prior = me.get_prior_instance()->template cast<T>();
+ return prior->_get_parent_node(t, etvr, prior->get_begin());
+ }
+ }
+
protected:
void on_invalidated() {
this->reset_parent_tracker();
return *static_cast<const T*>(this);
}
+ get_parent_node_ret _get_parent_node(
+ Transaction &t,
+ ExtentTransViewRetriever &etvr,
+ key_t key)
+ {
+ return etvr.maybe_wait_accessible(
+ t, *this->peek_parent_node()
+ ).si_then([&t, key, this] {
+ auto parent = this->peek_parent_node();
+ return parent->resolve_transaction(t, key).second;
+ });
+ }
+
void _take_parent_from_prior() {
auto &me = down_cast();
assert(!me.is_btree_root());