简单数据库实现——Part13 - 更新父节点
接下来一步,我们将处理在分裂叶节点后如何修复父节点。以下面的例子为参考:
在我们的例子中,我们将key3添加到树中,这会导致左叶节点分裂。分裂之后我们将通过以下操作来修复树:
- 将父节点中的第一个键更新为左孩子中的最大键(3)
- 在更新key之后添加新的键指对
- 新的指针指向新的子节点
- 新键是新子节点中的最大键(5)
因此,首先,用两个新的函数调用替换原来的代码:步骤一的update_internal_node_key()
和步骤二的internal_node_insert()
@@ -670,9 +725,11 @@ void leaf_node_split_and_insert(Cursor* cursor, uint32_t key, Row* value) {
*/
void* old_node = get_page(cursor->table->pager, cursor->page_num);
+ uint32_t old_max = get_node_max_key(old_node);
uint32_t new_page_num = get_unused_page_num(cursor->table->pager);
void* new_node = get_page(cursor->table->pager, new_page_num);
initialize_leaf_node(new_node);
+ *node_parent(new_node) = *node_parent(old_node);
*leaf_node_next_leaf(new_node) = *leaf_node_next_leaf(old_node);
*leaf_node_next_leaf(old_node) = new_page_num;
@@ -709,8 +766,12 @@ void leaf_node_split_and_insert(Cursor* cursor, uint32_t key, Row* value) {
if (is_node_root(old_node)) {
return create_new_root(cursor->table, new_page_num);
} else {
- printf("Need to implement updating parent after split\n");
- exit(EXIT_FAILURE);
+ uint32_t parent_page_num = *node_parent(old_node);
+ uint32_t new_max = get_node_max_key(old_node);
+ void* parent = get_page(cursor->table->pager, parent_page_num);
+
+ update_internal_node_key(parent, old_max, new_max);
+ internal_node_insert(cursor->table, parent_p