1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:nil -*-
2 // vim: ts=8 sw=2 smarttab
4 #include "node_stage_layout.h"
6 #include "crimson/os/seastore/onode_manager/staged-fltree/node_extent_mutable.h"
8 namespace crimson::os::seastore::onode
{
10 void node_header_t::bootstrap_extent(
11 NodeExtentMutable
& mut
,
12 field_type_t field_type
, node_type_t node_type
,
13 bool is_level_tail
, level_t level
)
16 header
.set_field_type(field_type
);
17 header
.set_node_type(node_type
);
18 header
.set_is_level_tail(is_level_tail
);
20 mut
.copy_in_relative(0, header
);
23 void node_header_t::update_is_level_tail(
24 NodeExtentMutable
& mut
, const node_header_t
& header
, bool value
)
26 auto& _header
= const_cast<node_header_t
&>(header
);
27 _header
.set_is_level_tail(value
);
28 mut
.validate_inplace_update(_header
);
31 #define F013_T _node_fields_013_t<SlotType>
32 #define F013_INST(ST) _node_fields_013_t<ST>
34 template <typename SlotType
>
35 void F013_T::update_size_at(
36 NodeExtentMutable
& mut
, const me_t
& node
, index_t index
, int change
)
38 assert(index
<= node
.num_keys
);
39 [[maybe_unused
]] extent_len_t node_size
= mut
.get_length();
42 if (change
< 0 && index
!= node
.num_keys
) {
43 assert(node
.get_item_start_offset(index
, node_size
) <
44 node
.get_item_end_offset(index
, node_size
));
47 for (const auto* p_slot
= &node
.slots
[index
];
48 p_slot
< &node
.slots
[node
.num_keys
];
50 node_offset_t offset
= p_slot
->right_offset
;
51 int new_offset
= offset
- change
;
52 assert(new_offset
> 0);
53 assert(new_offset
< (int)node_size
);
55 (void*)&(p_slot
->right_offset
),
56 node_offset_t(new_offset
));
60 if (change
> 0 && index
!= node
.num_keys
) {
61 assert(node
.num_keys
> 0);
62 assert(node
.get_key_start_offset(node
.num_keys
, node_size
) <=
63 node
.slots
[node
.num_keys
- 1].right_offset
);
68 template <typename SlotType
>
69 void F013_T::append_key(
70 NodeExtentMutable
& mut
, const key_t
& key
, char*& p_append
)
72 mut
.copy_in_absolute(p_append
, key
);
73 p_append
+= sizeof(key_t
);
76 template <typename SlotType
>
77 void F013_T::append_offset(
78 NodeExtentMutable
& mut
, node_offset_t offset_to_right
, char*& p_append
)
80 mut
.copy_in_absolute(p_append
, offset_to_right
);
81 p_append
+= sizeof(node_offset_t
);
84 template <typename SlotType
>
86 void F013_T::insert_at(
87 NodeExtentMutable
& mut
, const full_key_t
<KT
>& key
,
88 const me_t
& node
, index_t index
, node_offset_t size_right
)
90 assert(index
<= node
.num_keys
);
91 extent_len_t node_size
= mut
.get_length();
92 update_size_at(mut
, node
, index
, size_right
);
93 auto p_insert
= const_cast<char*>(fields_start(node
)) +
94 node
.get_key_start_offset(index
, node_size
);
95 auto p_shift_end
= fields_start(node
) +
96 node
.get_key_start_offset(node
.num_keys
, node_size
);
97 mut
.shift_absolute(p_insert
, p_shift_end
- p_insert
, estimate_insert_one());
98 mut
.copy_in_absolute((void*)&node
.num_keys
, num_keys_t(node
.num_keys
+ 1));
99 append_key(mut
, key_t::template from_key
<KT
>(key
), p_insert
);
100 int new_offset
= node
.get_item_end_offset(index
, node_size
) - size_right
;
101 assert(new_offset
> 0);
102 assert(new_offset
< (int)node_size
);
103 append_offset(mut
, new_offset
, p_insert
);
105 #define IA_TEMPLATE(ST, KT) template void F013_INST(ST):: \
106 insert_at<KT>(NodeExtentMutable&, const full_key_t<KT>&, \
107 const F013_INST(ST)&, index_t, node_offset_t)
108 IA_TEMPLATE(slot_0_t
, KeyT::VIEW
);
109 IA_TEMPLATE(slot_1_t
, KeyT::VIEW
);
110 IA_TEMPLATE(slot_3_t
, KeyT::VIEW
);
111 IA_TEMPLATE(slot_0_t
, KeyT::HOBJ
);
112 IA_TEMPLATE(slot_1_t
, KeyT::HOBJ
);
113 IA_TEMPLATE(slot_3_t
, KeyT::HOBJ
);
115 template <typename SlotType
>
116 node_offset_t
F013_T::erase_at(
117 NodeExtentMutable
& mut
, const me_t
& node
, index_t index
, const char* p_left_bound
)
119 extent_len_t node_size
= mut
.get_length();
120 auto offset_item_start
= node
.get_item_start_offset(index
, node_size
);
121 auto offset_item_end
= node
.get_item_end_offset(index
, node_size
);
122 assert(offset_item_start
< offset_item_end
);
123 auto erase_size
= offset_item_end
- offset_item_start
;
124 // fix and shift the left part
125 update_size_at(mut
, node
, index
+ 1, -erase_size
);
126 const char* p_shift_start
= fields_start(node
) +
127 node
.get_key_start_offset(index
+ 1, node_size
);
128 extent_len_t shift_len
= sizeof(SlotType
) * (node
.num_keys
- index
- 1);
129 int shift_off
= -(int)sizeof(SlotType
);
130 mut
.shift_absolute(p_shift_start
, shift_len
, shift_off
);
131 // shift the right part
132 p_shift_start
= p_left_bound
;
133 shift_len
= fields_start(node
) + offset_item_start
- p_left_bound
;
134 shift_off
= erase_size
;
135 mut
.shift_absolute(p_shift_start
, shift_len
, shift_off
);
137 mut
.copy_in_absolute((void*)&node
.num_keys
, num_keys_t(node
.num_keys
- 1));
141 #define F013_TEMPLATE(ST) template struct F013_INST(ST)
142 F013_TEMPLATE(slot_0_t
);
143 F013_TEMPLATE(slot_1_t
);
144 F013_TEMPLATE(slot_3_t
);
146 void node_fields_2_t::append_offset(
147 NodeExtentMutable
& mut
, node_offset_t offset_to_right
, char*& p_append
)
149 mut
.copy_in_absolute(p_append
, offset_to_right
);
150 p_append
+= sizeof(node_offset_t
);