]> git.proxmox.com Git - ceph.git/blame - ceph/src/crimson/os/seastore/onode_manager/staged-fltree/stages/sub_items_stage.cc
import quincy beta 17.1.0
[ceph.git] / ceph / src / crimson / os / seastore / onode_manager / staged-fltree / stages / sub_items_stage.cc
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#include "sub_items_stage.h"
5
6#include "crimson/os/seastore/onode_manager/staged-fltree/node_extent_mutable.h"
7
8namespace crimson::os::seastore::onode {
9
10template <KeyT KT>
11const laddr_packed_t* internal_sub_items_t::insert_at(
12 NodeExtentMutable& mut, const internal_sub_items_t& sub_items,
20effc67
TL
13 const full_key_t<KT>& key, const laddr_t& value,
14 index_t index, node_offset_t size, const char* p_left_bound)
15{
f67539c2
TL
16 assert(index <= sub_items.keys());
17 assert(size == estimate_insert<KT>(key, value));
18 const char* p_shift_start = p_left_bound;
19 const char* p_shift_end = reinterpret_cast<const char*>(
20 sub_items.p_first_item + 1 - index);
21 mut.shift_absolute(p_shift_start, p_shift_end - p_shift_start, -(int)size);
22
23 auto p_insert = const_cast<char*>(p_shift_end) - size;
20effc67
TL
24 auto item = internal_sub_item_t{
25 snap_gen_t::from_key<KT>(key), laddr_packed_t{value}};
f67539c2
TL
26 mut.copy_in_absolute(p_insert, item);
27 return &reinterpret_cast<internal_sub_item_t*>(p_insert)->value;
28}
29#define IA_TEMPLATE(KT) \
30 template const laddr_packed_t* internal_sub_items_t::insert_at<KT>( \
31 NodeExtentMutable&, const internal_sub_items_t&, const full_key_t<KT>&, \
20effc67 32 const laddr_t&, index_t, node_offset_t, const char*)
f67539c2
TL
33IA_TEMPLATE(KeyT::VIEW);
34IA_TEMPLATE(KeyT::HOBJ);
35
36node_offset_t internal_sub_items_t::trim_until(
20effc67
TL
37 NodeExtentMutable& mut, internal_sub_items_t& items, index_t index)
38{
f67539c2
TL
39 assert(index != 0);
40 auto keys = items.keys();
41 assert(index <= keys);
42 size_t ret = sizeof(internal_sub_item_t) * (keys - index);
20effc67 43 assert(ret < mut.get_length());
f67539c2
TL
44 return ret;
45}
46
20effc67
TL
47node_offset_t internal_sub_items_t::erase_at(
48 NodeExtentMutable& mut, const internal_sub_items_t& sub_items,
49 index_t index, const char* p_left_bound)
50{
51 assert(index < sub_items.keys());
52 node_offset_t erase_size = sizeof(internal_sub_item_t);
53 const char* p_shift_start = p_left_bound;
54 const char* p_shift_end = reinterpret_cast<const char*>(
55 sub_items.p_first_item - index);
56 mut.shift_absolute(p_shift_start, p_shift_end - p_shift_start, erase_size);
57 return erase_size;
58}
59
f67539c2
TL
60template <KeyT KT>
61void internal_sub_items_t::Appender<KT>::append(
20effc67
TL
62 const internal_sub_items_t& src, index_t from, index_t items)
63{
f67539c2
TL
64 assert(from <= src.keys());
65 if (items == 0) {
66 return;
67 }
68 assert(from < src.keys());
69 assert(from + items <= src.keys());
70 node_offset_t size = sizeof(internal_sub_item_t) * items;
71 p_append -= size;
72 p_mut->copy_in_absolute(p_append, src.p_first_item + 1 - from - items, size);
73}
74
75template <KeyT KT>
76void internal_sub_items_t::Appender<KT>::append(
20effc67
TL
77 const full_key_t<KT>& key, const laddr_t& value,
78 const laddr_packed_t*& p_value)
79{
f67539c2 80 p_append -= sizeof(internal_sub_item_t);
20effc67
TL
81 auto item = internal_sub_item_t{
82 snap_gen_t::from_key<KT>(key), laddr_packed_t{value}};
f67539c2
TL
83 p_mut->copy_in_absolute(p_append, item);
84 p_value = &reinterpret_cast<internal_sub_item_t*>(p_append)->value;
85}
86
87template <KeyT KT>
20effc67 88const value_header_t* leaf_sub_items_t::insert_at(
f67539c2 89 NodeExtentMutable& mut, const leaf_sub_items_t& sub_items,
20effc67
TL
90 const full_key_t<KT>& key, const value_config_t& value,
91 index_t index, node_offset_t size, const char* p_left_bound)
92{
f67539c2
TL
93 assert(index <= sub_items.keys());
94 assert(size == estimate_insert<KT>(key, value));
95 // a. [... item(index)] << size
96 const char* p_shift_start = p_left_bound;
97 const char* p_shift_end = sub_items.get_item_end(index);
98 mut.shift_absolute(p_shift_start, p_shift_end - p_shift_start, -(int)size);
99
100 // b. insert item
101 auto p_insert = const_cast<char*>(p_shift_end - size);
20effc67
TL
102 auto p_value = reinterpret_cast<value_header_t*>(p_insert);
103 p_value->initiate(mut, value);
104 p_insert += value.allocation_size();
f67539c2
TL
105 mut.copy_in_absolute(p_insert, snap_gen_t::template from_key<KT>(key));
106 assert(p_insert + sizeof(snap_gen_t) + sizeof(node_offset_t) == p_shift_end);
107
108 // c. compensate affected offsets
20effc67 109 auto item_size = value.allocation_size() + sizeof(snap_gen_t);
f67539c2
TL
110 for (auto i = index; i < sub_items.keys(); ++i) {
111 const node_offset_packed_t& offset_i = sub_items.get_offset(i);
112 mut.copy_in_absolute((void*)&offset_i, node_offset_t(offset_i.value + item_size));
113 }
114
115 // d. [item(index-1) ... item(0) ... offset(index)] <<< sizeof(node_offset_t)
116 const char* p_offset = (index == 0 ?
117 (const char*)&sub_items.get_offset(0) + sizeof(node_offset_t) :
118 (const char*)&sub_items.get_offset(index - 1));
119 p_shift_start = p_shift_end;
120 p_shift_end = p_offset;
121 mut.shift_absolute(p_shift_start, p_shift_end - p_shift_start, -(int)sizeof(node_offset_t));
122
123 // e. insert offset
124 node_offset_t offset_to_item_start = item_size + sub_items.get_offset_to_end(index);
125 mut.copy_in_absolute(
126 const_cast<char*>(p_shift_end) - sizeof(node_offset_t), offset_to_item_start);
127
128 // f. update num_sub_keys
129 mut.copy_in_absolute((void*)sub_items.p_num_keys, num_keys_t(sub_items.keys() + 1));
130
131 return p_value;
132}
20effc67 133template const value_header_t* leaf_sub_items_t::insert_at<KeyT::HOBJ>(
f67539c2 134 NodeExtentMutable&, const leaf_sub_items_t&, const full_key_t<KeyT::HOBJ>&,
20effc67 135 const value_config_t&, index_t, node_offset_t, const char*);
f67539c2
TL
136
137node_offset_t leaf_sub_items_t::trim_until(
20effc67
TL
138 NodeExtentMutable& mut, leaf_sub_items_t& items, index_t index)
139{
f67539c2
TL
140 assert(index != 0);
141 auto keys = items.keys();
142 assert(index <= keys);
143 if (index == keys) {
144 return 0;
145 }
146 index_t trim_items = keys - index;
147 const char* p_items_start = items.p_start();
148 const char* p_shift_start = items.get_item_end(index);
149 const char* p_shift_end = items.get_item_end(0);
150 size_t size_trim_offsets = sizeof(node_offset_t) * trim_items;
151 mut.shift_absolute(p_shift_start, p_shift_end - p_shift_start,
152 size_trim_offsets);
153 mut.copy_in_absolute((void*)items.p_num_keys, num_keys_t(index));
154 size_t ret = size_trim_offsets + (p_shift_start - p_items_start);
20effc67 155 assert(ret < mut.get_length());
f67539c2
TL
156 return ret;
157}
158
20effc67
TL
159node_offset_t leaf_sub_items_t::erase_at(
160 NodeExtentMutable& mut, const leaf_sub_items_t& sub_items,
161 index_t index, const char* p_left_bound)
162{
163 assert(sub_items.keys() > 0);
164 assert(index < sub_items.keys());
165 auto p_item_start = sub_items.get_item_start(index);
166 auto p_item_end = sub_items.get_item_end(index);
167 assert(p_item_start < p_item_end);
168 node_offset_t item_erase_size = p_item_end - p_item_start;
169 node_offset_t erase_size = item_erase_size + sizeof(node_offset_t);
170 auto p_offset_end = (const char*)&sub_items.get_offset(index);
171
172 // a. compensate affected offset[n] ... offset[index+1]
173 for (auto i = index + 1; i < sub_items.keys(); ++i) {
174 const node_offset_packed_t& offset_i = sub_items.get_offset(i);
175 mut.copy_in_absolute((void*)&offset_i, node_offset_t(offset_i.value - item_erase_size));
176 }
177
178 // b. kv[index-1] ... kv[0] ... offset[index+1] >> sizeof(node_offset_t)
179 mut.shift_absolute(p_item_end, p_offset_end - p_item_end, sizeof(node_offset_t));
180
181 // c. ... kv[n] ... kv[index+1] >> item_erase_size
182 mut.shift_absolute(p_left_bound, p_item_start - p_left_bound, erase_size);
183
184 // d. update num_keys
185 mut.copy_in_absolute((void*)sub_items.p_num_keys, num_keys_t(sub_items.keys() - 1));
186
187 return erase_size;
188}
189
f67539c2
TL
190template class internal_sub_items_t::Appender<KeyT::VIEW>;
191template class internal_sub_items_t::Appender<KeyT::HOBJ>;
192
193// helper type for the visitor
194template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
195// explicit deduction guide
196template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
197
198template <KeyT KT>
20effc67
TL
199void leaf_sub_items_t::Appender<KT>::append(
200 const leaf_sub_items_t& src, index_t from, index_t items)
201{
202 if (p_append) {
203 // append from empty
204 assert(cnt <= APPENDER_LIMIT);
205 assert(from <= src.keys());
206 if (items == 0) {
207 return;
208 }
209 if (op_src) {
210 assert(*op_src == src);
211 } else {
212 op_src = src;
213 }
214 assert(from < src.keys());
215 assert(from + items <= src.keys());
216 appends[cnt] = range_items_t{from, items};
217 ++cnt;
218 } else {
219 // append from existing
220 assert(op_dst.has_value());
221 assert(!p_appended);
222 assert(from == 0);
223 assert(items);
224 assert(items == src.keys());
225
226 num_keys_t num_keys = op_dst->keys();
227 node_offset_t compensate = op_dst->get_offset(num_keys - 1).value;
228 const char* p_items_start = op_dst->p_start();
229 const char* p_items_end = op_dst->p_items_end;
230
231 // update dst num_keys
232 num_keys += items;
233 p_mut->copy_in_absolute((char*)op_dst->p_num_keys, num_keys);
234
235 // shift dst items
236 std::size_t src_offsets_size = sizeof(node_offset_t) * items;
237 p_mut->shift_absolute(p_items_start,
238 p_items_end - p_items_start,
239 -(int)src_offsets_size);
240
241 // fill offsets from src
242 node_offset_t offset;
243 char* p_cur_offset = const_cast<char*>(p_items_end);
244 for (auto i = from; i < from + items; ++i) {
245 offset = src.get_offset(i).value + compensate;
246 p_cur_offset -= sizeof(node_offset_t);
247 p_mut->copy_in_absolute(p_cur_offset, offset);
248 }
249
250 // fill items from src
251 auto p_src_items_start = src.get_item_end(from + items);
252 std::size_t src_items_size = src.get_item_end(from) - p_src_items_start;
253 p_appended = const_cast<char*>(p_items_start) - src_offsets_size - src_items_size;
254 p_mut->copy_in_absolute(p_appended, p_src_items_start, src_items_size);
255 }
256}
257
258template <KeyT KT>
259char* leaf_sub_items_t::Appender<KT>::wrap()
260{
261 if (op_dst.has_value()) {
262 // append from existing
263 assert(p_appended);
264 return p_appended;
265 }
266 // append from empty
267 assert(p_append);
f67539c2
TL
268 auto p_cur = p_append;
269 num_keys_t num_keys = 0;
270 for (auto i = 0u; i < cnt; ++i) {
271 auto& a = appends[i];
272 std::visit(overloaded {
273 [&] (const range_items_t& arg) { num_keys += arg.items; },
274 [&] (const kv_item_t& arg) { ++num_keys; }
275 }, a);
276 }
277 assert(num_keys);
278 p_cur -= sizeof(num_keys_t);
279 p_mut->copy_in_absolute(p_cur, num_keys);
280
281 node_offset_t last_offset = 0;
282 for (auto i = 0u; i < cnt; ++i) {
283 auto& a = appends[i];
284 std::visit(overloaded {
285 [&] (const range_items_t& arg) {
286 int compensate = (last_offset - op_src->get_offset_to_end(arg.from));
287 node_offset_t offset;
288 for (auto i = arg.from; i < arg.from + arg.items; ++i) {
289 offset = op_src->get_offset(i).value + compensate;
290 p_cur -= sizeof(node_offset_t);
291 p_mut->copy_in_absolute(p_cur, offset);
292 }
293 last_offset = offset;
294 },
295 [&] (const kv_item_t& arg) {
20effc67 296 last_offset += sizeof(snap_gen_t) + arg.value_config.allocation_size();
f67539c2
TL
297 p_cur -= sizeof(node_offset_t);
298 p_mut->copy_in_absolute(p_cur, last_offset);
299 }
300 }, a);
301 }
302
303 for (auto i = 0u; i < cnt; ++i) {
304 auto& a = appends[i];
305 std::visit(overloaded {
306 [&] (const range_items_t& arg) {
307 auto _p_start = op_src->get_item_end(arg.from + arg.items);
308 size_t _len = op_src->get_item_end(arg.from) - _p_start;
309 p_cur -= _len;
310 p_mut->copy_in_absolute(p_cur, _p_start, _len);
311 },
312 [&] (const kv_item_t& arg) {
313 assert(pp_value);
314 p_cur -= sizeof(snap_gen_t);
315 p_mut->copy_in_absolute(p_cur, snap_gen_t::template from_key<KT>(*arg.p_key));
20effc67
TL
316 p_cur -= arg.value_config.allocation_size();
317 auto p_value = reinterpret_cast<value_header_t*>(p_cur);
318 p_value->initiate(*p_mut, arg.value_config);
319 *pp_value = p_value;
f67539c2
TL
320 }
321 }, a);
322 }
323 return p_cur;
324}
325
326template class leaf_sub_items_t::Appender<KeyT::VIEW>;
327template class leaf_sub_items_t::Appender<KeyT::HOBJ>;
328
329}