]> git.proxmox.com Git - ceph.git/blame - ceph/src/crimson/os/seastore/onode_manager/staged-fltree/node_layout_replayable.h
import quincy beta 17.1.0
[ceph.git] / ceph / src / crimson / os / seastore / onode_manager / staged-fltree / node_layout_replayable.h
CommitLineData
f67539c2
TL
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:nil -*-
2// vim: ts=8 sw=2 smarttab
3
4#pragma once
5
6#include "node_extent_mutable.h"
7#include "stages/node_stage.h"
8#include "stages/stage.h"
9
10#define STAGE_T node_to_stage_t<node_stage_t>
11
12namespace crimson::os::seastore::onode {
13
14/**
15 * NodeLayoutReplayableT
16 *
17 * Contains templated logics to modify the layout of a NodeExtend which are
18 * also replayable. Used by NodeExtentAccessorT at runtime and by
19 * DeltaRecorderT during replay.
20 */
21template <typename FieldType, node_type_t NODE_TYPE>
22struct NodeLayoutReplayableT {
23 using node_stage_t = node_extent_t<FieldType, NODE_TYPE>;
24 using position_t = typename STAGE_T::position_t;
25 using StagedIterator = typename STAGE_T::StagedIterator;
20effc67 26 using value_input_t = value_input_type_t<NODE_TYPE>;
f67539c2
TL
27 using value_t = value_type_t<NODE_TYPE>;
28 static constexpr auto FIELD_TYPE = FieldType::FIELD_TYPE;
29
30 template <KeyT KT>
31 static const value_t* insert(
32 NodeExtentMutable& mut,
33 const node_stage_t& node_stage,
34 const full_key_t<KT>& key,
20effc67 35 const value_input_t& value,
f67539c2
TL
36 position_t& insert_pos,
37 match_stage_t& insert_stage,
38 node_offset_t& insert_size) {
39 auto p_value = STAGE_T::template proceed_insert<KT, false>(
40 mut, node_stage, key, value, insert_pos, insert_stage, insert_size);
41 return p_value;
42 }
43
44 static void split(
45 NodeExtentMutable& mut,
46 const node_stage_t& node_stage,
47 StagedIterator& split_at) {
48 node_stage_t::update_is_level_tail(mut, node_stage, false);
49 STAGE_T::trim(mut, split_at);
50 }
51
52 template <KeyT KT>
53 static const value_t* split_insert(
54 NodeExtentMutable& mut,
55 const node_stage_t& node_stage,
56 StagedIterator& split_at,
57 const full_key_t<KT>& key,
20effc67 58 const value_input_t& value,
f67539c2
TL
59 position_t& insert_pos,
60 match_stage_t& insert_stage,
61 node_offset_t& insert_size) {
62 node_stage_t::update_is_level_tail(mut, node_stage, false);
63 STAGE_T::trim(mut, split_at);
64 auto p_value = STAGE_T::template proceed_insert<KT, true>(
65 mut, node_stage, key, value, insert_pos, insert_stage, insert_size);
66 return p_value;
67 }
68
69 static void update_child_addr(
70 NodeExtentMutable& mut, const laddr_t new_addr, laddr_packed_t* p_addr) {
71 assert(NODE_TYPE == node_type_t::INTERNAL);
72 mut.copy_in_absolute(p_addr, new_addr);
73 }
20effc67
TL
74
75 static std::tuple<match_stage_t, position_t> erase(
76 NodeExtentMutable& mut,
77 const node_stage_t& node_stage,
78 const position_t& _erase_pos) {
79 if (_erase_pos.is_end()) {
80 // must be internal node
81 assert(node_stage.is_level_tail());
82 // return erase_stage, last_pos
83 return update_last_to_tail(mut, node_stage);
84 }
85
86 assert(node_stage.keys() != 0);
87 position_t erase_pos = _erase_pos;
88 auto erase_stage = STAGE_T::erase(mut, node_stage, erase_pos);
89 // return erase_stage, next_pos
90 return {erase_stage, erase_pos};
91 }
92
93 static position_t make_tail(
94 NodeExtentMutable& mut,
95 const node_stage_t& node_stage) {
96 assert(!node_stage.is_level_tail());
97 if constexpr (NODE_TYPE == node_type_t::INTERNAL) {
98 auto [r_stage, r_last_pos] = update_last_to_tail(mut, node_stage);
99 std::ignore = r_stage;
100 return r_last_pos;
101 } else {
102 node_stage_t::update_is_level_tail(mut, node_stage, true);
103 // no need to calculate the last pos
104 return position_t::end();
105 }
106 }
107
108 private:
109 static std::tuple<match_stage_t, position_t> update_last_to_tail(
110 NodeExtentMutable& mut,
111 const node_stage_t& node_stage) {
112 if constexpr (NODE_TYPE == node_type_t::INTERNAL) {
113 assert(node_stage.keys() != 0);
114 position_t last_pos;
115 laddr_t last_value;
116 {
117 const laddr_packed_t* p_last_value;
118 STAGE_T::template get_largest_slot<true, false, true>(
119 node_stage, &last_pos, nullptr, &p_last_value);
120 last_value = p_last_value->value;
121 }
122
123 auto erase_pos = last_pos;
124 auto erase_stage = STAGE_T::erase(mut, node_stage, erase_pos);
125 assert(erase_pos.is_end());
126
127 node_stage_t::update_is_level_tail(mut, node_stage, true);
128 auto p_last_value = const_cast<laddr_packed_t*>(
129 node_stage.get_end_p_laddr());
130 mut.copy_in_absolute(p_last_value, last_value);
131 // return erase_stage, last_pos
132 return {erase_stage, last_pos};
133 } else {
134 ceph_abort("impossible path");
135 }
136 }
f67539c2
TL
137};
138
139}