auto left_key = left_child->impl->get_largest_key_view();
auto left_child_addr = left_child->impl->laddr();
- auto left_child_addr_packed = laddr_packed_t{left_child_addr};
auto right_key = right_child->impl->get_largest_key_view();
auto right_child_addr = right_child->impl->laddr();
logger().debug("OTree::Internal::Insert: "
if (free_size >= insert_size) {
// insert
[[maybe_unused]] auto p_value = impl->insert(
- left_key, left_child_addr_packed, insert_pos, insert_stage, insert_size);
+ left_key, left_child_addr, insert_pos, insert_stage, insert_size);
assert(impl->free_size() == free_size - insert_size);
assert(insert_pos <= pos);
assert(p_value->value == left_child_addr);
insert_pos, insert_stage=insert_stage, insert_size=insert_size](auto fresh_right) mutable {
auto right_node = fresh_right.node;
auto left_child_addr = left_child->impl->laddr();
- auto left_child_addr_packed = laddr_packed_t{left_child_addr};
auto [split_pos, is_insert_left, p_value] = impl->split_insert(
- fresh_right.mut, *right_node->impl, left_key, left_child_addr_packed,
+ fresh_right.mut, *right_node->impl, left_key, left_child_addr,
insert_pos, insert_stage, insert_size);
assert(p_value->value == left_child_addr);
track_split(split_pos, right_node);
using node_stage_t = typename layout_t::node_stage_t;
using position_t = typename layout_t::position_t;
using StagedIterator = typename layout_t::StagedIterator;
- using value_t = typename layout_t::value_t;
+ using value_input_t = typename layout_t::value_input_t;
static constexpr auto FIELD_TYPE = layout_t::FIELD_TYPE;
~DeltaRecorderT() override = default;
template <KeyT KT>
void encode_insert(
const full_key_t<KT>& key,
- const value_t& value,
+ const value_input_t& value,
const position_t& insert_pos,
const match_stage_t& insert_stage,
const node_offset_t& insert_size) {
void encode_split_insert(
const StagedIterator& split_at,
const full_key_t<KT>& key,
- const value_t& value,
+ const value_input_t& value,
const position_t& insert_pos,
const match_stage_t& insert_stage,
const node_offset_t& insert_size,
auto key = key_hobj_t::decode(delta);
std::unique_ptr<char[]> value_storage_heap;
- value_t value_storage_stack;
+ value_input_t value_storage_stack;
auto p_value = decode_value(delta, value_storage_heap, value_storage_stack);
auto insert_pos = position_t::decode(delta);
auto key = key_hobj_t::decode(delta);
std::unique_ptr<char[]> value_storage_heap;
- value_t value_storage_stack;
+ value_input_t value_storage_stack;
auto p_value = decode_value(delta, value_storage_heap, value_storage_stack);
auto insert_pos = position_t::decode(delta);
}
private:
- static void encode_value(const value_t& value, ceph::bufferlist& encoded) {
- if constexpr (std::is_same_v<value_t, laddr_packed_t>) {
+ static void encode_value(const value_input_t& value, ceph::bufferlist& encoded) {
+ if constexpr (std::is_same_v<value_input_t, laddr_t>) {
// NODE_TYPE == node_type_t::INTERNAL
- ceph::encode(value.value, encoded);
- } else if constexpr (std::is_same_v<value_t, onode_t>) {
+ ceph::encode(value, encoded);
+ } else if constexpr (std::is_same_v<value_input_t, onode_t>) {
// NODE_TYPE == node_type_t::LEAF
value.encode(encoded);
} else {
}
}
- static value_t* decode_value(ceph::bufferlist::const_iterator& delta,
- std::unique_ptr<char[]>& value_storage_heap,
- value_t& value_storage_stack) {
- if constexpr (std::is_same_v<value_t, laddr_packed_t>) {
+ static value_input_t* decode_value(ceph::bufferlist::const_iterator& delta,
+ std::unique_ptr<char[]>& value_storage_heap,
+ value_input_t& value_storage_stack) {
+ if constexpr (std::is_same_v<value_input_t, laddr_t>) {
// NODE_TYPE == node_type_t::INTERNAL
laddr_t value;
ceph::decode(value, delta);
- value_storage_stack.value = value;
+ value_storage_stack = value;
return &value_storage_stack;
- } else if constexpr (std::is_same_v<value_t, onode_t>) {
+ } else if constexpr (std::is_same_v<value_input_t, onode_t>) {
// NODE_TYPE == node_type_t::LEAF
auto value_config = onode_t::decode(delta);
value_storage_heap = onode_t::allocate(value_config);
using position_t = typename layout_t::position_t;
using recorder_t = DeltaRecorderT<FieldType, NODE_TYPE>;
using StagedIterator = typename layout_t::StagedIterator;
+ using value_input_t = typename layout_t::value_input_t;
using value_t = typename layout_t::value_t;
static constexpr auto FIELD_TYPE = layout_t::FIELD_TYPE;
template <KeyT KT>
const value_t* insert_replayable(
const full_key_t<KT>& key,
- const value_t& value,
+ const value_input_t& value,
position_t& insert_pos,
match_stage_t& insert_stage,
node_offset_t& insert_size) {
const value_t* split_insert_replayable(
StagedIterator& split_at,
const full_key_t<KT>& key,
- const value_t& value,
+ const value_input_t& value,
position_t& insert_pos,
match_stage_t& insert_stage,
node_offset_t& insert_size) {
}
#pragma GCC diagnostic ignored "-Woverloaded-virtual"
virtual const laddr_packed_t* insert(
- const key_view_t&, const laddr_packed_t&, search_position_t&, match_stage_t&, node_offset_t&) {
+ const key_view_t&, const laddr_t&, search_position_t&, match_stage_t&, node_offset_t&) {
ceph_abort("impossible path");
}
#pragma GCC diagnostic ignored "-Woverloaded-virtual"
virtual std::tuple<search_position_t, bool, const laddr_packed_t*> split_insert(
- NodeExtentMutable&, NodeImpl&, const key_view_t&, const laddr_packed_t&,
+ NodeExtentMutable&, NodeImpl&, const key_view_t&, const laddr_t&,
search_position_t&, match_stage_t&, node_offset_t&) {
ceph_abort("impossible path");
}
using marker_t = typename node_marker_type<NODE_TYPE>::type;
using node_stage_t = typename extent_t::node_stage_t;
using position_t = typename extent_t::position_t;
+ using value_input_t = typename extent_t::value_input_t;
using value_t = typename extent_t::value_t;
static constexpr auto FIELD_TYPE = extent_t::FIELD_TYPE;
static constexpr auto KEY_TYPE = insert_key_type<NODE_TYPE>::type;
}
const value_t* insert(
- const full_key_t<KEY_TYPE>& key, const value_t& value,
+ const full_key_t<KEY_TYPE>& key, const value_input_t& value,
search_position_t& insert_pos, match_stage_t& insert_stage,
node_offset_t& insert_size) override {
logger().debug("OTree::Layout::Insert: begin at "
std::tuple<search_position_t, bool, const value_t*> split_insert(
NodeExtentMutable& right_mut, NodeImpl& right_impl,
- const full_key_t<KEY_TYPE>& key, const value_t& value,
+ const full_key_t<KEY_TYPE>& key, const value_input_t& value,
search_position_t& _insert_pos, match_stage_t& insert_stage,
node_offset_t& insert_size) override {
logger().info("OTree::Layout::Split: begin at "
const key_view_t& key, const laddr_t& value,
search_position_t& insert_pos) const override {
if constexpr (NODE_TYPE == node_type_t::INTERNAL) {
- auto packed_value = laddr_packed_t{value};
auto& node_stage = extent.read();
match_stage_t insert_stage;
node_offset_t insert_size;
if (unlikely(!node_stage.keys())) {
assert(insert_pos.is_end());
insert_stage = STAGE;
- insert_size = STAGE_T::template insert_size<KeyT::VIEW>(key, packed_value);
+ insert_size = STAGE_T::template insert_size<KeyT::VIEW>(key, value);
} else {
std::tie(insert_stage, insert_size) = STAGE_T::evaluate_insert(
- node_stage, key, packed_value, cast_down<STAGE>(insert_pos), false);
+ node_stage, key, value, cast_down<STAGE>(insert_pos), false);
}
return {insert_stage, insert_size};
} else {
using node_stage_t = node_extent_t<FieldType, NODE_TYPE>;
using position_t = typename STAGE_T::position_t;
using StagedIterator = typename STAGE_T::StagedIterator;
+ using value_input_t = value_input_type_t<NODE_TYPE>;
using value_t = value_type_t<NODE_TYPE>;
static constexpr auto FIELD_TYPE = FieldType::FIELD_TYPE;
NodeExtentMutable& mut,
const node_stage_t& node_stage,
const full_key_t<KT>& key,
- const value_t& value,
+ const value_input_t& value,
position_t& insert_pos,
match_stage_t& insert_stage,
node_offset_t& insert_size) {
const node_stage_t& node_stage,
StagedIterator& split_at,
const full_key_t<KT>& key,
- const value_t& value,
+ const value_input_t& value,
position_t& insert_pos,
match_stage_t& insert_stage,
node_offset_t& insert_size) {
*/
template <node_type_t NODE_TYPE>
class item_iterator_t {
+ using value_input_t = value_input_type_t<NODE_TYPE>;
using value_t = value_type_t<NODE_TYPE>;
public:
item_iterator_t(const memory_range_t& range)
template <KeyT KT>
static node_offset_t estimate_insert(
- const full_key_t<KT>& key, const value_t&) {
+ const full_key_t<KT>& key, const value_input_t&) {
return ns_oid_view_t::estimate_size<KT>(key) + sizeof(node_offset_t);
}
template <typename FieldType, node_type_t NODE_TYPE>
template <KeyT KT>
void APPEND_T::append(
- const full_key_t<KT>& key, const value_t& value, const value_t*& p_value) {
+ const full_key_t<KT>& key, const value_input_t& value, const value_t*& p_value) {
if constexpr (FIELD_TYPE == field_type_t::N3) {
ceph_abort("not implemented");
} else {
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;
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);
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");
p_append_right = p_start + FieldType::SIZE;
}
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>&);
using next_param_t = typename Params::next_param_t;
using position_t = staged_position_t<Params::STAGE>;
using result_t = staged_result_t<Params::NODE_TYPE, Params::STAGE>;
+ using value_input_t = value_input_type_t<Params::NODE_TYPE>;
using value_t = value_type_t<Params::NODE_TYPE>;
static constexpr auto CONTAINER_TYPE = container_t::CONTAINER_TYPE;
static constexpr bool IS_BOTTOM = (Params::STAGE == STAGE_BOTTOM);
template <KeyT KT, typename T = value_t>
std::enable_if_t<IS_BOTTOM, const T*> insert(
- NodeExtentMutable& mut, const full_key_t<KT>& key,
- const value_t& value, node_offset_t insert_size, const char* p_left_bound) {
+ NodeExtentMutable& mut,
+ const full_key_t<KT>& key,
+ const value_input_t& value,
+ node_offset_t insert_size,
+ const char* p_left_bound) {
return container_t::template insert_at<KT>(
mut, container, key, value, _index, insert_size, p_left_bound);
}
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) {
return container_t::template estimate_insert<KT>(key, value);
}
}
template <KeyT KT>
- static node_offset_t estimate_insert(const full_key_t<KT>& key, const value_t& value) {
+ static node_offset_t estimate_insert(const full_key_t<KT>& key,
+ const value_input_t& value) {
return container_t::template estimate_insert<KT>(key, value);
}
}
template <KeyT KT>
- static node_offset_t insert_size(const full_key_t<KT>& key, const value_t& value) {
+ static node_offset_t insert_size(const full_key_t<KT>& key,
+ const value_input_t& value) {
if constexpr (IS_BOTTOM) {
return iterator_t::template estimate_insert<KT>(key, value);
} else {
}
template <KeyT KT>
- static node_offset_t insert_size_at(
- match_stage_t stage, const full_key_t<KeyT::HOBJ>& key, const value_t& value) {
+ static node_offset_t insert_size_at(match_stage_t stage,
+ const full_key_t<KeyT::HOBJ>& key,
+ const value_input_t& value) {
if (stage == STAGE) {
return insert_size<KT>(key, value);
} else {
template <typename T = std::tuple<match_stage_t, node_offset_t>>
static std::enable_if_t<NODE_TYPE == node_type_t::INTERNAL, T> evaluate_insert(
const container_t& container, const full_key_t<KeyT::VIEW>& key,
- const value_t& value, position_t& position, bool evaluate_last) {
+ const value_input_t& value, position_t& position, bool evaluate_last) {
auto iter = iterator_t(container);
auto& index = position.index;
if (evaluate_last || index == INDEX_END) {
template <KeyT KT>
static const value_t* insert_new(
NodeExtentMutable& mut, const memory_range_t& range,
- const full_key_t<KT>& key, const value_t& value) {
+ const full_key_t<KT>& key, const value_input_t& value) {
char* p_insert = const_cast<char*>(range.p_end);
const value_t* p_value = nullptr;
StagedAppender<KT> appender;
template <KeyT KT, bool SPLIT>
static const value_t* proceed_insert_recursively(
NodeExtentMutable& mut, const container_t& container,
- const full_key_t<KT>& key, const value_t& value,
+ const full_key_t<KT>& key, const value_input_t& value,
position_t& position, match_stage_t& stage,
node_offset_t& _insert_size, const char* p_left_bound) {
// proceed insert from right to left
template <KeyT KT, bool SPLIT>
static const value_t* proceed_insert(
NodeExtentMutable& mut, const container_t& container,
- const full_key_t<KT>& key, const value_t& value,
+ const full_key_t<KT>& key, const value_input_t& value,
position_t& position, match_stage_t& stage, node_offset_t& _insert_size) {
auto p_left_bound = container.p_left_bound();
if (unlikely(!container.keys())) {
* -> std::tuple<NodeExtentMutable&, char*>
* wrap_nxt(char* p_append)
* ELSE
- * append(const full_key_t& key, const value_t& value)
+ * append(const full_key_t& key, const value_input_t& value)
*/
template <KeyT KT>
struct _BaseWithNxtAppender {
}
}
void append(const full_key_t<KT>& key,
- const value_t& value, const value_t*& p_value) {
+ const value_input_t& value, const value_t*& p_value) {
assert(!require_wrap_nxt);
if constexpr (!IS_BOTTOM) {
auto& nxt = open_nxt(key);
template <KeyT KT>
static bool append_insert(
- const full_key_t<KT>& key, const value_t& value,
+ const full_key_t<KT>& key, const value_input_t& value,
StagedIterator& src_iter, StagedAppender<KT>& appender,
bool is_front_insert, match_stage_t& stage, const value_t*& p_value) {
assert(src_iter.valid());
enum class ContainerType { ITERATIVE, INDEXABLE };
+// the input type to construct the value during insert.
+template <node_type_t> struct value_input_type;
+template<> struct value_input_type<node_type_t::INTERNAL> { using type = laddr_t; };
+template<> struct value_input_type<node_type_t::LEAF> { using type = onode_t; };
+template <node_type_t NODE_TYPE>
+using value_input_type_t = typename value_input_type<NODE_TYPE>::type;
+
template <node_type_t> struct value_type;
template<> struct value_type<node_type_t::INTERNAL> { using type = laddr_packed_t; };
template<> struct value_type<node_type_t::LEAF> { using type = onode_t; };
template <KeyT KT>
const laddr_packed_t* internal_sub_items_t::insert_at(
NodeExtentMutable& mut, const internal_sub_items_t& sub_items,
- const full_key_t<KT>& key, const laddr_packed_t& value,
+ const full_key_t<KT>& key, const laddr_t& value,
index_t index, node_offset_t size, const char* p_left_bound) {
assert(index <= sub_items.keys());
assert(size == estimate_insert<KT>(key, value));
mut.shift_absolute(p_shift_start, p_shift_end - p_shift_start, -(int)size);
auto p_insert = const_cast<char*>(p_shift_end) - size;
- auto item = internal_sub_item_t{snap_gen_t::from_key<KT>(key), value};
+ auto item = internal_sub_item_t{
+ snap_gen_t::from_key<KT>(key), laddr_packed_t{value}};
mut.copy_in_absolute(p_insert, item);
return &reinterpret_cast<internal_sub_item_t*>(p_insert)->value;
}
#define IA_TEMPLATE(KT) \
template const laddr_packed_t* internal_sub_items_t::insert_at<KT>( \
NodeExtentMutable&, const internal_sub_items_t&, const full_key_t<KT>&, \
- const laddr_packed_t&, index_t, node_offset_t, const char*)
+ const laddr_t&, index_t, node_offset_t, const char*)
IA_TEMPLATE(KeyT::VIEW);
IA_TEMPLATE(KeyT::HOBJ);
template <KeyT KT>
void internal_sub_items_t::Appender<KT>::append(
- const full_key_t<KT>& key, const laddr_packed_t& value,
+ const full_key_t<KT>& key, const laddr_t& value,
const laddr_packed_t*& p_value) {
p_append -= sizeof(internal_sub_item_t);
- auto item = internal_sub_item_t{snap_gen_t::from_key<KT>(key), value};
+ auto item = internal_sub_item_t{
+ snap_gen_t::from_key<KT>(key), laddr_packed_t{value}};
p_mut->copy_in_absolute(p_append, item);
p_value = &reinterpret_cast<internal_sub_item_t*>(p_append)->value;
}
template <KeyT KT>
static node_offset_t estimate_insert(
- const full_key_t<KT>&, const laddr_packed_t&) {
+ const full_key_t<KT>&, const laddr_t&) {
return sizeof(internal_sub_item_t);
}
template <KeyT KT>
static const laddr_packed_t* insert_at(
NodeExtentMutable&, const internal_sub_items_t&,
- const full_key_t<KT>&, const laddr_packed_t&,
+ const full_key_t<KT>&, const laddr_t&,
index_t index, node_offset_t size, const char* p_left_bound);
static node_offset_t trim_until(NodeExtentMutable&, internal_sub_items_t&, index_t);
Appender(NodeExtentMutable* p_mut, char* p_append)
: p_mut{p_mut}, p_append{p_append} {}
void append(const internal_sub_items_t& src, index_t from, index_t items);
- void append(const full_key_t<KT>&, const laddr_packed_t&, const laddr_packed_t*&);
+ void append(const full_key_t<KT>&, const laddr_t&, const laddr_packed_t*&);
char* wrap() { return p_append; }
private:
NodeExtentMutable* p_mut;
onode_t value = {2};
#define _STAGE_T(NodeType) node_to_stage_t<typename NodeType::node_stage_t>
#define NXT_T(StageType) staged<typename StageType::next_param_t>
- laddr_packed_t i_value{0};
+ laddr_t i_value{0};
logger().info("\n"
"Bytes of a key-value insertion (full-string):\n"
" s-p-c, 'n'-'o', s-g => onode_t(2): typically internal 41B, leaf 35B\n"