crimson/onode-staged-tree: validate safe-split from tree_conf_t

Signed-off-by: Yingxin Cheng <yingxin.cheng@intel.com>
This commit is contained in:
Yingxin Cheng 2021-06-02 13:36:11 +08:00
parent 37d721cf69
commit a28ad7ebb1
3 changed files with 45 additions and 4 deletions

View File

@ -115,6 +115,44 @@ void validate_tree_config(const tree_conf_t& conf)
ceph_assert(conf.internal_node_size % DISK_BLOCK_SIZE == 0);
ceph_assert(conf.leaf_node_size <= MAX_NODE_SIZE);
ceph_assert(conf.leaf_node_size % DISK_BLOCK_SIZE == 0);
if (conf.do_split_check) {
// In hope to comply with 3 * (oid + ns) + 2 * value < node
//
// see node_layout.h for NODE_BLOCK_SIZE considerations
//
// The below calculations also consider the internal indexing overhead in
// order to be accurate, so the equation has become:
// node-header-size + 2 * max-full-insert-size +
// max-ns/oid-split-overhead <= node-size
auto obj = ghobject_t{shard_id_t{0}, 0, 0, "", "", 0, 0};
key_hobj_t key(obj);
auto max_str_size = conf.max_ns_size + conf.max_oid_size;
#define _STAGE_T(NodeType) node_to_stage_t<typename NodeType::node_stage_t>
#define NXT_T(StageType) staged<typename StageType::next_param_t>
laddr_t i_value{0};
auto insert_size_2 =
_STAGE_T(InternalNode0)::template insert_size<KeyT::HOBJ>(key, i_value);
auto insert_size_0 =
NXT_T(NXT_T(_STAGE_T(InternalNode0)))::template insert_size<KeyT::HOBJ>(key, i_value);
unsigned internal_size_bound = sizeof(node_header_t) +
(insert_size_2 + max_str_size) * 2 +
(insert_size_2 - insert_size_0 + max_str_size);
ceph_assert(internal_size_bound <= conf.internal_node_size);
value_config_t l_value;
l_value.payload_size = conf.max_value_payload_size;
insert_size_2 =
_STAGE_T(LeafNode0)::template insert_size<KeyT::HOBJ>(key, l_value);
insert_size_0 =
NXT_T(NXT_T(_STAGE_T(LeafNode0)))::template insert_size<KeyT::HOBJ>(key, l_value);
unsigned leaf_size_bound = sizeof(node_header_t) +
(insert_size_2 + max_str_size) * 2 +
(insert_size_2 - insert_size_0 + max_str_size);
ceph_assert(leaf_size_bound <= conf.leaf_node_size);
}
}
}

View File

@ -162,6 +162,7 @@ struct tree_conf_t {
value_size_t max_value_payload_size;
extent_len_t internal_node_size;
extent_len_t leaf_node_size;
bool do_split_check = true;
};
class tree_cursor_t;

View File

@ -41,7 +41,8 @@ template <value_magic_t MAGIC,
string_size_t MAX_OID_SIZE,
value_size_t MAX_VALUE_PAYLOAD_SIZE,
extent_len_t INTERNAL_NODE_SIZE,
extent_len_t LEAF_NODE_SIZE>
extent_len_t LEAF_NODE_SIZE,
bool DO_SPLIT_CHECK>
class TestValue final : public Value {
public:
static constexpr tree_conf_t TREE_CONF = {
@ -50,7 +51,8 @@ class TestValue final : public Value {
MAX_OID_SIZE,
MAX_VALUE_PAYLOAD_SIZE,
INTERNAL_NODE_SIZE,
LEAF_NODE_SIZE
LEAF_NODE_SIZE,
DO_SPLIT_CHECK
};
using id_t = test_item_t::id_t;
@ -201,8 +203,8 @@ class TestValue final : public Value {
};
using UnboundedValue = TestValue<
value_magic_t::TEST_UNBOUND, 4096, 4096, 4096, 4096, 4096>;
value_magic_t::TEST_UNBOUND, 4096, 4096, 4096, 4096, 4096, false>;
using BoundedValue = TestValue<
value_magic_t::TEST_BOUNDED, 320, 320, 640, 4096, 4096>;
value_magic_t::TEST_BOUNDED, 320, 320, 640, 4096, 4096, true>;
}