template <typename FieldType, node_type_t _NODE_TYPE>
class node_extent_t {
public:
+ using value_input_t = value_input_type_t<_NODE_TYPE>;
using value_t = value_type_t<_NODE_TYPE>;
using num_keys_t = typename FieldType::num_keys_t;
static constexpr node_type_t NODE_TYPE = _NODE_TYPE;
static constexpr field_type_t FIELD_TYPE = FieldType::FIELD_TYPE;
- static constexpr node_offset_t EXTENT_SIZE =
- (FieldType::SIZE + DISK_BLOCK_SIZE - 1u) / DISK_BLOCK_SIZE * DISK_BLOCK_SIZE;
// TODO: remove
node_extent_t() = default;
- node_extent_t(const FieldType* p_fields) : p_fields{p_fields} {
+ node_extent_t(const FieldType* p_fields, extent_len_t node_size)
+ : p_fields{p_fields}, node_size{node_size} {
+ assert(is_valid_node_size(node_size));
validate(*p_fields);
}
const char* p_start() const { return fields_start(*p_fields); }
- const char* off_to_ptr(node_offset_t off) const {
- assert(off <= FieldType::SIZE);
- return p_start() + off;
- }
-
- node_offset_t ptr_to_off(const void* ptr) const {
- auto _ptr = static_cast<const char*>(ptr);
- assert(_ptr >= p_start());
- auto off = _ptr - p_start();
- assert(off <= FieldType::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);
+ }
+ extent_len_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->child_addrs[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); }
- node_offset_t size_before(index_t index) const {
- auto free_size = p_fields->template free_size_before<NODE_TYPE>(index);
+ key_get_type operator[] (index_t index) const {
+ return p_fields->get_key(index, node_size);
+ }
+ extent_len_t size_before(index_t index) const {
+ auto free_size = p_fields->template free_size_before<NODE_TYPE>(
+ index, node_size);
assert(total_size() >= free_size);
return total_size() - free_size;
}
node_offset_t size_to_nxt_at(index_t index) const;
node_offset_t size_overhead_at(index_t index) const {
return FieldType::ITEM_OVERHEAD; }
- memory_range_t get_nxt_container(index_t index) const;
+ container_range_t get_nxt_container(index_t index) const;
template <typename T = FieldType>
std::enable_if_t<T::FIELD_TYPE == field_type_t::N3, const value_t*>
get_p_value(index_t index) const {
assert(index < keys());
if constexpr (NODE_TYPE == node_type_t::INTERNAL) {
- return &p_fields->child_addrs[index];
+ return p_fields->get_p_child_addr(index, node_size);
} else {
- auto range = get_nxt_container(index);
- auto ret = reinterpret_cast<const onode_t*>(range.p_start);
- assert(range.p_start + ret->size == range.p_end);
+ auto range = get_nxt_container(index).range;
+ auto ret = reinterpret_cast<const value_header_t*>(range.p_start);
+ assert(range.p_start + ret->allocation_size() == range.p_end);
return ret;
}
}
}
static node_extent_t decode(const char* p_node_start,
+ extent_len_t node_size,
ceph::bufferlist::const_iterator& delta) {
// nothing to decode
- return node_extent_t(reinterpret_cast<const FieldType*>(p_node_start));
+ return node_extent_t(
+ reinterpret_cast<const FieldType*>(p_node_start),
+ node_size);
}
static void validate(const FieldType& fields) {
template <KeyT KT>
static node_offset_t estimate_insert(
- const full_key_t<KT>& key, const value_t& value) {
+ const full_key_t<KT>& key, const value_input_t& value) {
auto size = FieldType::estimate_insert_one();
if constexpr (FIELD_TYPE == field_type_t::N2) {
size += ns_oid_view_t::estimate_size<KT>(key);
} else if constexpr (FIELD_TYPE == field_type_t::N3 &&
NODE_TYPE == node_type_t::LEAF) {
- size += value.size;
+ size += value.allocation_size();
}
return size;
}
template <KeyT KT>
static const value_t* insert_at(
NodeExtentMutable& mut, const node_extent_t&,
- const full_key_t<KT>& key, const value_t& value,
+ const full_key_t<KT>& key, const value_input_t& value,
index_t index, node_offset_t size, const char* p_left_bound) {
if constexpr (FIELD_TYPE == field_type_t::N3) {
ceph_abort("not implemented");
static node_offset_t trim_at(NodeExtentMutable&, const node_extent_t&,
index_t index, node_offset_t trimmed);
+ static node_offset_t erase_at(NodeExtentMutable&, const node_extent_t&,
+ index_t index, const char* p_left_bound);
+
template <KeyT KT>
class Appender;
private:
const FieldType& fields() const { return *p_fields; }
const FieldType* p_fields;
+ extent_len_t node_size;
};
template <typename FieldType, node_type_t NODE_TYPE>
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);
- void append(const full_key_t<KT>&, const value_t&, const value_t*&);
+ void append(const full_key_t<KT>&, const value_input_t&, const value_t*&);
char* wrap();
std::tuple<NodeExtentMutable*, char*> open_nxt(const key_get_type&);
std::tuple<NodeExtentMutable*, char*> open_nxt(const full_key_t<KT>&);
assert(p_append < p_append_right);
assert(p_append_left < p_append);
p_append_right = p_append;
- FieldType::append_offset(*p_mut, p_append - p_start, p_append_left);
+ auto new_offset = p_append - p_start;
+ assert(new_offset > 0);
+ assert(new_offset < p_mut->get_length());
+ FieldType::append_offset(*p_mut, new_offset, p_append_left);
++num_keys;
} else {
ceph_abort("not implemented");