From ca86033b528369abf2235a3f4ba2b8e64c7a354c Mon Sep 17 00:00:00 2001 From: Yingxin Cheng Date: Mon, 7 Jun 2021 10:45:18 +0800 Subject: [PATCH] crimson/onode-staged-tree: remove compile-time node SIZE Switch to run-time node_extent_t::node_size instead. Signed-off-by: Yingxin Cheng --- .../staged-fltree/stages/node_stage.cc | 74 +++++++++--- .../staged-fltree/stages/node_stage.h | 29 +++-- .../staged-fltree/stages/node_stage_layout.cc | 25 ++-- .../staged-fltree/stages/node_stage_layout.h | 112 +++++++++++------- 4 files changed, 159 insertions(+), 81 deletions(-) diff --git a/src/crimson/os/seastore/onode_manager/staged-fltree/stages/node_stage.cc b/src/crimson/os/seastore/onode_manager/staged-fltree/stages/node_stage.cc index 20d5ac89395..246e5eb4640 100644 --- a/src/crimson/os/seastore/onode_manager/staged-fltree/stages/node_stage.cc +++ b/src/crimson/os/seastore/onode_manager/staged-fltree/stages/node_stage.cc @@ -18,7 +18,8 @@ const char* NODE_T::p_left_bound() const // N3 internal node doesn't have the right part return nullptr; } else { - auto ret = p_start() + fields().get_item_end_offset(keys()); + auto ret = p_start() + + fields().get_item_end_offset(keys(), node_size); if constexpr (NODE_TYPE == node_type_t::INTERNAL) { if (is_level_tail()) { ret -= sizeof(laddr_t); @@ -36,7 +37,8 @@ node_offset_t NODE_T::size_to_nxt_at(index_t index) const FIELD_TYPE == field_type_t::N1) { return FieldType::estimate_insert_one(); } else if constexpr (FIELD_TYPE == field_type_t::N2) { - auto p_end = p_start() + p_fields->get_item_end_offset(index); + auto p_end = p_start() + + p_fields->get_item_end_offset(index, node_size); return FieldType::estimate_insert_one() + ns_oid_view_t(p_end).size(); } else { ceph_abort("N3 node is not nested"); @@ -49,8 +51,10 @@ memory_range_t NODE_T::get_nxt_container(index_t index) const if constexpr (std::is_same_v) { ceph_abort("N3 internal node doesn't have the right part"); } else { - node_offset_t item_start_offset = p_fields->get_item_start_offset(index); - node_offset_t item_end_offset = p_fields->get_item_end_offset(index); + node_offset_t item_start_offset = p_fields->get_item_start_offset( + index, node_size); + node_offset_t item_end_offset = p_fields->get_item_end_offset( + index, node_size); assert(item_start_offset < item_end_offset); auto item_p_start = p_start() + item_start_offset; auto item_p_end = p_start() + item_end_offset; @@ -81,6 +85,8 @@ template void NODE_T::update_is_level_tail( NodeExtentMutable& mut, const node_extent_t& extent, bool value) { + assert(mut.get_length() == extent.node_size); + assert(mut.get_read() == extent.p_start()); node_header_t::update_is_level_tail(mut, extent.p_fields->header, value); } @@ -90,13 +96,16 @@ memory_range_t NODE_T::insert_prefix_at( NodeExtentMutable& mut, const node_extent_t& node, const full_key_t& key, index_t index, node_offset_t size, const char* p_left_bound) { + assert(mut.get_length() == node.node_size); + assert(mut.get_read() == node.p_start()); if constexpr (FIELD_TYPE == field_type_t::N0 || FIELD_TYPE == field_type_t::N1) { assert(index <= node.keys()); assert(p_left_bound == node.p_left_bound()); assert(size > FieldType::estimate_insert_one()); auto size_right = size - FieldType::estimate_insert_one(); - const char* p_insert = node.p_start() + node.fields().get_item_end_offset(index); + const char* p_insert = node.p_start() + + node.fields().get_item_end_offset(index, mut.get_length()); const char* p_insert_front = p_insert - size_right; FieldType::template insert_at(mut, key, node.fields(), index, size_right); mut.shift_absolute(p_left_bound, @@ -130,6 +139,8 @@ template void NODE_T::update_size_at( NodeExtentMutable& mut, const node_extent_t& node, index_t index, int change) { + assert(mut.get_length() == node.node_size); + assert(mut.get_read() == node.p_start()); assert(index < node.keys()); FieldType::update_size_at(mut, node.fields(), index, change); } @@ -138,6 +149,8 @@ template node_offset_t NODE_T::trim_until( NodeExtentMutable& mut, const node_extent_t& node, index_t index) { + assert(mut.get_length() == node.node_size); + assert(mut.get_read() == node.p_start()); assert(!node.is_level_tail()); auto keys = node.keys(); assert(index <= keys); @@ -159,14 +172,18 @@ node_offset_t NODE_T::trim_at( NodeExtentMutable& mut, const node_extent_t& node, index_t index, node_offset_t trimmed) { + assert(mut.get_length() == node.node_size); + assert(mut.get_read() == node.p_start()); assert(!node.is_level_tail()); assert(index < node.keys()); if constexpr (std::is_same_v) { ceph_abort("not implemented"); } else { - node_offset_t offset = node.p_fields->get_item_start_offset(index); + extent_len_t node_size = mut.get_length(); + node_offset_t offset = node.p_fields->get_item_start_offset( + index, node_size); size_t new_offset = offset + trimmed; - assert(new_offset < node.p_fields->get_item_end_offset(index)); + assert(new_offset < node.p_fields->get_item_end_offset(index, node_size)); mut.copy_in_absolute(const_cast(node.p_fields->p_offset(index)), node_offset_t(new_offset)); mut.copy_in_absolute( @@ -181,6 +198,8 @@ node_offset_t NODE_T::erase_at( NodeExtentMutable& mut, const node_extent_t& node, index_t index, const char* p_left_bound) { + assert(mut.get_length() == node.node_size); + assert(mut.get_read() == node.p_start()); if constexpr (FIELD_TYPE == field_type_t::N0 || FIELD_TYPE == field_type_t::N1) { assert(node.keys() > 0); @@ -211,13 +230,18 @@ APPEND_T::Appender(NodeExtentMutable* p_mut, const node_extent_t& node, bool ope { assert(p_start == node.p_start()); assert(node.keys()); + assert(node.node_size == p_mut->get_length()); + extent_len_t node_size = node.node_size; if (open) { // seek as open_nxt() if constexpr (FIELD_TYPE == field_type_t::N0 || FIELD_TYPE == field_type_t::N1) { - p_append_left = p_start + node.fields().get_key_start_offset(node.keys() - 1); + p_append_left = p_start + node.fields().get_key_start_offset( + node.keys() - 1, node_size); p_append_left += sizeof(typename FieldType::key_t); - p_append_right = p_start + node.fields().get_item_end_offset(node.keys() - 1); + p_append_right = p_start + + node.fields().get_item_end_offset(node.keys() - 1, + node_size); } else if constexpr (FIELD_TYPE == field_type_t::N2) { ceph_abort("not implemented"); } else { @@ -226,10 +250,14 @@ APPEND_T::Appender(NodeExtentMutable* p_mut, const node_extent_t& node, bool ope num_keys = node.keys() - 1; } else { if constexpr (std::is_same_v) { + std::ignore = node_size; ceph_abort("not implemented"); } else { - p_append_left = p_start + node.fields().get_key_start_offset(node.keys()); - p_append_right = p_start + node.fields().get_item_end_offset(node.keys()); + p_append_left = p_start + node.fields().get_key_start_offset( + node.keys(), node_size); + p_append_right = p_start + + node.fields().get_item_end_offset(node.keys(), + node_size); } num_keys = node.keys(); } @@ -245,6 +273,8 @@ void APPEND_T::append(const node_extent_t& src, index_t from, index_t items) } else { assert(p_src == &src); } + assert(p_src->node_size == p_mut->get_length()); + extent_len_t node_size = src.node_size; if (items == 0) { return; } @@ -252,11 +282,14 @@ void APPEND_T::append(const node_extent_t& src, index_t from, index_t items) assert(from + items <= src.keys()); num_keys += items; if constexpr (std::is_same_v) { + std::ignore = node_size; ceph_abort("not implemented"); } else { // append left part forwards - node_offset_t offset_left_start = src.fields().get_key_start_offset(from); - node_offset_t offset_left_end = src.fields().get_key_start_offset(from + items); + node_offset_t offset_left_start = src.fields().get_key_start_offset( + from, node_size); + node_offset_t offset_left_end = src.fields().get_key_start_offset( + from + items, node_size); node_offset_t left_size = offset_left_end - offset_left_start; if (num_keys == 0) { // no need to adjust offset @@ -266,7 +299,8 @@ void APPEND_T::append(const node_extent_t& src, index_t from, index_t items) src.p_start() + offset_left_start, left_size); } else { node_offset_t step_size = FieldType::estimate_insert_one(); - node_offset_t offset_base = src.fields().get_item_end_offset(from); + node_offset_t offset_base = src.fields().get_item_end_offset( + from, node_size); int offset_change = p_append_right - p_start - offset_base; auto p_offset_dst = p_append_left; if constexpr (FIELD_TYPE != field_type_t::N2) { @@ -277,8 +311,10 @@ void APPEND_T::append(const node_extent_t& src, index_t from, index_t items) p_offset_dst += sizeof(typename FieldType::key_t); } for (auto i = from; i < from + items; ++i) { - p_mut->copy_in_absolute(p_offset_dst, - node_offset_t(src.fields().get_item_start_offset(i) + offset_change)); + p_mut->copy_in_absolute( + p_offset_dst, + node_offset_t(src.fields().get_item_start_offset(i, node_size) + + offset_change)); p_offset_dst += step_size; } assert(p_append_left + left_size + sizeof(typename FieldType::key_t) == @@ -287,8 +323,10 @@ void APPEND_T::append(const node_extent_t& src, index_t from, index_t items) p_append_left += left_size; // append right part backwards - node_offset_t offset_right_start = src.fields().get_item_end_offset(from + items); - node_offset_t offset_right_end = src.fields().get_item_end_offset(from); + node_offset_t offset_right_start = src.fields().get_item_end_offset( + from + items, node_size); + node_offset_t offset_right_end = src.fields().get_item_end_offset( + from, node_size); node_offset_t right_size = offset_right_end - offset_right_start; p_append_right -= right_size; p_mut->copy_in_absolute(p_append_right, diff --git a/src/crimson/os/seastore/onode_manager/staged-fltree/stages/node_stage.h b/src/crimson/os/seastore/onode_manager/staged-fltree/stages/node_stage.h index e726e0ed978..35e5598f0b5 100644 --- a/src/crimson/os/seastore/onode_manager/staged-fltree/stages/node_stage.h +++ b/src/crimson/os/seastore/onode_manager/staged-fltree/stages/node_stage.h @@ -44,7 +44,7 @@ class node_extent_t { const char* p_start() const { return fields_start(*p_fields); } const char* off_to_ptr(node_offset_t off) const { - assert(off <= FieldType::SIZE); + assert(off <= node_size); return p_start() + off; } @@ -52,26 +52,30 @@ class node_extent_t { auto _ptr = static_cast(ptr); assert(_ptr >= p_start()); auto off = _ptr - p_start(); - assert(off <= FieldType::SIZE); + assert(off <= node_size); return off; } bool is_level_tail() const { return p_fields->is_level_tail(); } level_t level() const { return p_fields->header.level; } node_offset_t free_size() const { - return p_fields->template free_size_before(keys()); + return p_fields->template free_size_before( + keys(), node_size); + } + node_offset_t total_size() const { + return p_fields->total_size(node_size); } - node_offset_t total_size() const { return p_fields->total_size(); } const char* p_left_bound() const; template std::enable_if_t get_end_p_laddr() const { assert(is_level_tail()); if constexpr (FIELD_TYPE == field_type_t::N3) { - return p_fields->get_p_child_addr(keys()); + return p_fields->get_p_child_addr(keys(), node_size); } else { - auto offset_start = p_fields->get_item_end_offset(keys()); - assert(offset_start <= FieldType::SIZE); + auto offset_start = p_fields->get_item_end_offset( + keys(), node_size); + assert(offset_start <= node_size); offset_start -= sizeof(laddr_packed_t); auto p_addr = p_start() + offset_start; return reinterpret_cast(p_addr); @@ -82,9 +86,12 @@ class node_extent_t { using key_get_type = typename FieldType::key_get_type; static constexpr auto CONTAINER_TYPE = ContainerType::INDEXABLE; index_t keys() const { return p_fields->num_keys; } - key_get_type operator[] (index_t index) const { return p_fields->get_key(index); } + key_get_type operator[] (index_t index) const { + return p_fields->get_key(index, node_size); + } node_offset_t size_before(index_t index) const { - auto free_size = p_fields->template free_size_before(index); + auto free_size = p_fields->template free_size_before( + index, node_size); assert(total_size() >= free_size); return total_size() - free_size; } @@ -98,7 +105,7 @@ class node_extent_t { get_p_value(index_t index) const { assert(index < keys()); if constexpr (NODE_TYPE == node_type_t::INTERNAL) { - return p_fields->get_p_child_addr(index); + return p_fields->get_p_child_addr(index, node_size); } else { auto range = get_nxt_container(index); auto ret = reinterpret_cast(range.p_start); @@ -204,7 +211,7 @@ class node_extent_t::Appender { assert(p_fields->num_keys == 0); #endif p_append_left = p_start + FieldType::HEADER_SIZE; - p_append_right = p_start + FieldType::SIZE; + p_append_right = p_start + p_mut->get_length(); } Appender(NodeExtentMutable*, const node_extent_t&, bool open = false); void append(const node_extent_t& src, index_t from, index_t items); diff --git a/src/crimson/os/seastore/onode_manager/staged-fltree/stages/node_stage_layout.cc b/src/crimson/os/seastore/onode_manager/staged-fltree/stages/node_stage_layout.cc index b2c4ef71a47..83b70f7ffa7 100644 --- a/src/crimson/os/seastore/onode_manager/staged-fltree/stages/node_stage_layout.cc +++ b/src/crimson/os/seastore/onode_manager/staged-fltree/stages/node_stage_layout.cc @@ -36,11 +36,12 @@ void F013_T::update_size_at( NodeExtentMutable& mut, const me_t& node, index_t index, int change) { assert(index <= node.num_keys); + extent_len_t node_size = mut.get_length(); #ifndef NDEBUG // check underflow if (change < 0 && index != node.num_keys) { - assert(node.get_item_start_offset(index) < - node.get_item_end_offset(index)); + assert(node.get_item_start_offset(index, node_size) < + node.get_item_end_offset(index, node_size)); } #endif for (const auto* p_slot = &node.slots[index]; @@ -55,7 +56,7 @@ void F013_T::update_size_at( // check overflow if (change > 0 && index != node.num_keys) { assert(node.num_keys > 0); - assert(node.get_key_start_offset(node.num_keys) <= + assert(node.get_key_start_offset(node.num_keys, node_size) <= node.slots[node.num_keys - 1].right_offset); } #endif @@ -84,14 +85,18 @@ void F013_T::insert_at( const me_t& node, index_t index, node_offset_t size_right) { assert(index <= node.num_keys); + extent_len_t node_size = mut.get_length(); update_size_at(mut, node, index, size_right); auto p_insert = const_cast(fields_start(node)) + - node.get_key_start_offset(index); - auto p_shift_end = fields_start(node) + node.get_key_start_offset(node.num_keys); + node.get_key_start_offset(index, node_size); + auto p_shift_end = fields_start(node) + + node.get_key_start_offset(node.num_keys, node_size); mut.shift_absolute(p_insert, p_shift_end - p_insert, estimate_insert_one()); mut.copy_in_absolute((void*)&node.num_keys, num_keys_t(node.num_keys + 1)); append_key(mut, key_t::template from_key(key), p_insert); - append_offset(mut, node.get_item_end_offset(index) - size_right, p_insert); + append_offset(mut, + node.get_item_end_offset(index, node_size) - size_right, + p_insert); } #define IA_TEMPLATE(ST, KT) template void F013_INST(ST):: \ insert_at(NodeExtentMutable&, const full_key_t&, \ @@ -107,13 +112,15 @@ template node_offset_t F013_T::erase_at( NodeExtentMutable& mut, const me_t& node, index_t index, const char* p_left_bound) { - auto offset_item_start = node.get_item_start_offset(index); - auto offset_item_end = node.get_item_end_offset(index); + extent_len_t node_size = mut.get_length(); + auto offset_item_start = node.get_item_start_offset(index, node_size); + auto offset_item_end = node.get_item_end_offset(index, node_size); assert(offset_item_start < offset_item_end); auto erase_size = offset_item_end - offset_item_start; // fix and shift the left part update_size_at(mut, node, index + 1, -erase_size); - const char* p_shift_start = fields_start(node) + node.get_key_start_offset(index + 1); + const char* p_shift_start = fields_start(node) + + node.get_key_start_offset(index + 1, node_size); extent_len_t shift_len = sizeof(SlotType) * (node.num_keys - index - 1); int shift_off = -(int)sizeof(SlotType); mut.shift_absolute(p_shift_start, shift_len, shift_off); diff --git a/src/crimson/os/seastore/onode_manager/staged-fltree/stages/node_stage_layout.h b/src/crimson/os/seastore/onode_manager/staged-fltree/stages/node_stage_layout.h index 24e37a638a1..cf2bf199aec 100644 --- a/src/crimson/os/seastore/onode_manager/staged-fltree/stages/node_stage_layout.h +++ b/src/crimson/os/seastore/onode_manager/staged-fltree/stages/node_stage_layout.h @@ -82,19 +82,17 @@ const char* fields_start(const FieldType& node) { template node_range_t fields_free_range_before( - const FieldType& node, index_t index) { + const FieldType& node, index_t index, extent_len_t node_size) { assert(index <= node.num_keys); - node_offset_t offset_start = node.get_key_start_offset(index); - node_offset_t offset_end = - (index == 0 ? FieldType::SIZE - : node.get_item_start_offset(index - 1)); + node_offset_t offset_start = node.get_key_start_offset(index, node_size); + node_offset_t offset_end = node.get_item_end_offset(index, node_size); if constexpr (NODE_TYPE == node_type_t::INTERNAL) { if (node.is_level_tail() && index == node.num_keys) { offset_end -= sizeof(laddr_t); } } assert(offset_start <= offset_end); - assert(offset_end - offset_start < FieldType::SIZE); + assert(offset_end - offset_start < (int)node_size); return {offset_start, offset_end}; } @@ -129,39 +127,46 @@ struct _node_fields_013_t { using key_get_type = const key_t&; using me_t = _node_fields_013_t; static constexpr field_type_t FIELD_TYPE = SlotType::FIELD_TYPE; - static constexpr node_offset_t SIZE = NODE_BLOCK_SIZE; static constexpr node_offset_t HEADER_SIZE = sizeof(node_header_t) + sizeof(num_keys_t); static constexpr node_offset_t ITEM_OVERHEAD = SlotType::OVERHEAD; bool is_level_tail() const { return header.get_is_level_tail(); } - node_offset_t total_size() const { return SIZE; } - key_get_type get_key(index_t index) const { + node_offset_t total_size(extent_len_t node_size) const { + return node_size; + } + key_get_type get_key( + index_t index, extent_len_t node_size) const { assert(index < num_keys); return slots[index].key; } - node_offset_t get_key_start_offset(index_t index) const { + node_offset_t get_key_start_offset( + index_t index, extent_len_t node_size) const { assert(index <= num_keys); auto offset = HEADER_SIZE + sizeof(SlotType) * index; - assert(offset < SIZE); + assert(offset < node_size); return offset; } - node_offset_t get_item_start_offset(index_t index) const { + node_offset_t get_item_start_offset( + index_t index, extent_len_t node_size) const { assert(index < num_keys); auto offset = slots[index].right_offset; - assert(offset <= SIZE); + assert(offset < node_size); return offset; } const void* p_offset(index_t index) const { assert(index < num_keys); return &slots[index].right_offset; } - node_offset_t get_item_end_offset(index_t index) const { - return index == 0 ? SIZE : get_item_start_offset(index - 1); + node_offset_t get_item_end_offset( + index_t index, extent_len_t node_size) const { + return index == 0 ? node_size + : get_item_start_offset(index - 1, node_size); } template - node_offset_t free_size_before(index_t index) const { - auto range = fields_free_range_before(*this, index); + node_offset_t free_size_before( + index_t index, extent_len_t node_size) const { + auto range = fields_free_range_before(*this, index, node_size); return range.end - range.start; } @@ -216,43 +221,48 @@ struct node_fields_2_t { using key_t = ns_oid_view_t; using key_get_type = key_t; static constexpr field_type_t FIELD_TYPE = field_type_t::N2; - static constexpr node_offset_t SIZE = NODE_BLOCK_SIZE; static constexpr node_offset_t HEADER_SIZE = sizeof(node_header_t) + sizeof(num_keys_t); static constexpr node_offset_t ITEM_OVERHEAD = sizeof(node_offset_t); bool is_level_tail() const { return header.get_is_level_tail(); } - node_offset_t total_size() const { return SIZE; } - key_get_type get_key(index_t index) const { + node_offset_t total_size(extent_len_t node_size) const { + return node_size; + } + key_get_type get_key( + index_t index, extent_len_t node_size) const { assert(index < num_keys); - node_offset_t item_end_offset = - (index == 0 ? SIZE : offsets[index - 1]); - assert(item_end_offset <= SIZE); + node_offset_t item_end_offset = get_item_end_offset(index, node_size); const char* p_start = fields_start(*this); return key_t(p_start + item_end_offset); } - node_offset_t get_key_start_offset(index_t index) const { + node_offset_t get_key_start_offset( + index_t index, extent_len_t node_size) const { assert(index <= num_keys); auto offset = HEADER_SIZE + sizeof(node_offset_t) * num_keys; - assert(offset <= SIZE); + assert(offset <= node_size); return offset; } - node_offset_t get_item_start_offset(index_t index) const { + node_offset_t get_item_start_offset( + index_t index, extent_len_t node_size) const { assert(index < num_keys); auto offset = offsets[index]; - assert(offset <= SIZE); + assert(offset < node_size); return offset; } const void* p_offset(index_t index) const { assert(index < num_keys); return &offsets[index]; } - node_offset_t get_item_end_offset(index_t index) const { - return index == 0 ? SIZE : get_item_start_offset(index - 1); + node_offset_t get_item_end_offset( + index_t index, extent_len_t node_size) const { + return index == 0 ? node_size + : get_item_start_offset(index - 1, node_size); } template - node_offset_t free_size_before(index_t index) const { - auto range = fields_free_range_before(*this, index); + node_offset_t free_size_before( + index_t index, extent_len_t node_size) const { + auto range = fields_free_range_before(*this, index, node_size); return range.end - range.start; } @@ -303,7 +313,6 @@ struct internal_fields_3_t { // should be enough to index all keys under 64 KiB node using num_keys_t = uint16_t; static constexpr field_type_t FIELD_TYPE = field_type_t::N3; - static constexpr node_offset_t SIZE = NODE_BLOCK_SIZE; static constexpr node_offset_t HEADER_SIZE = sizeof(node_header_t) + sizeof(num_keys_t); static constexpr node_offset_t ITEM_SIZE = @@ -311,23 +320,24 @@ struct internal_fields_3_t { static constexpr node_offset_t ITEM_OVERHEAD = 0u; bool is_level_tail() const { return header.get_is_level_tail(); } - node_offset_t total_size() const { + node_offset_t total_size(extent_len_t node_size) const { if (is_level_tail()) { - return SIZE - sizeof(snap_gen_t); + return node_size - sizeof(snap_gen_t); } else { - return SIZE; + return node_size; } } - key_get_type get_key(index_t index) const { + key_get_type get_key( + index_t index, extent_len_t node_size) const { assert(index < num_keys); return keys[index]; } template std::enable_if_t - free_size_before(index_t index) const { + free_size_before(index_t index, extent_len_t node_size) const { assert(index <= num_keys); - assert(num_keys <= get_max_num_keys()); - auto free = total_size() - HEADER_SIZE - + assert(num_keys <= get_max_num_keys(node_size)); + auto free = total_size(node_size) - HEADER_SIZE - index * ITEM_SIZE; if (is_level_tail() && index == num_keys) { free -= sizeof(laddr_t); @@ -335,6 +345,22 @@ struct internal_fields_3_t { return free; } + const laddr_packed_t* get_p_child_addr( + index_t index, extent_len_t node_size) const { +#ifndef NDEBUG + if (is_level_tail()) { + assert(index <= num_keys); + } else { + assert(index < num_keys); + } +#endif + auto p_addrs = reinterpret_cast( + &keys[get_num_keys_limit(node_size)]); + auto ret = p_addrs + index; + assert((const char*)ret < fields_start(*this) + node_size); + return ret; + } + static node_offset_t estimate_insert_one() { return ITEM_SIZE; } template @@ -355,12 +381,12 @@ struct internal_fields_3_t { snap_gen_t keys[]; private: - num_keys_t get_max_num_keys() const { - auto num_limit = get_num_keys_limit(); + num_keys_t get_max_num_keys(extent_len_t node_size) const { + auto num_limit = get_num_keys_limit(node_size); return (is_level_tail() ? num_limit - 1 : num_limit); } - static num_keys_t get_num_keys_limit() { - return (SIZE - HEADER_SIZE) / ITEM_SIZE; + static num_keys_t get_num_keys_limit(extent_len_t node_size) { + return (node_size - HEADER_SIZE) / ITEM_SIZE; } } __attribute__((packed)); -- 2.39.5