Switch to run-time node_extent_t::node_size instead.
Signed-off-by: Yingxin Cheng <yingxin.cheng@intel.com>
// 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);
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");
if constexpr (std::is_same_v<FieldType, internal_fields_3_t>) {
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;
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);
}
NodeExtentMutable& mut, const node_extent_t& node, const full_key_t<KT>& 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<KT>(mut, key, node.fields(), index, size_right);
mut.shift_absolute(p_left_bound,
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);
}
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);
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<FieldType, internal_fields_3_t>) {
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<void*>(node.p_fields->p_offset(index)),
node_offset_t(new_offset));
mut.copy_in_absolute(
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);
{
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 {
num_keys = node.keys() - 1;
} else {
if constexpr (std::is_same_v<FieldType, internal_fields_3_t>) {
+ 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();
}
} 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;
}
assert(from + items <= src.keys());
num_keys += items;
if constexpr (std::is_same_v<FieldType, internal_fields_3_t>) {
+ 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
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) {
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) ==
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,
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;
}
auto _ptr = static_cast<const char*>(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<NODE_TYPE>(keys());
+ return p_fields->template free_size_before<NODE_TYPE>(
+ 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 <node_type_t T = NODE_TYPE>
std::enable_if_t<T == node_type_t::INTERNAL, const laddr_packed_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<const laddr_packed_t*>(p_addr);
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<NODE_TYPE>(index);
+ auto free_size = p_fields->template free_size_before<NODE_TYPE>(
+ index, node_size);
assert(total_size() >= free_size);
return total_size() - free_size;
}
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<const value_header_t*>(range.p_start);
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);
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];
// 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
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<char*>(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<KT>(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<KT>(NodeExtentMutable&, const full_key_t<KT>&, \
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);
template <node_type_t NODE_TYPE, typename FieldType>
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};
}
using key_get_type = const key_t&;
using me_t = _node_fields_013_t<SlotType>;
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_type_t NODE_TYPE>
- node_offset_t free_size_before(index_t index) const {
- auto range = fields_free_range_before<NODE_TYPE>(*this, index);
+ node_offset_t free_size_before(
+ index_t index, extent_len_t node_size) const {
+ auto range = fields_free_range_before<NODE_TYPE>(*this, index, node_size);
return range.end - range.start;
}
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_type_t NODE_TYPE>
- node_offset_t free_size_before(index_t index) const {
- auto range = fields_free_range_before<NODE_TYPE>(*this, index);
+ node_offset_t free_size_before(
+ index_t index, extent_len_t node_size) const {
+ auto range = fields_free_range_before<NODE_TYPE>(*this, index, node_size);
return range.end - range.start;
}
// 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 =
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 <node_type_t NODE_TYPE>
std::enable_if_t<NODE_TYPE == node_type_t::INTERNAL, node_offset_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);
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<const laddr_packed_t*>(
+ &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 <KeyT KT>
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));