Step 13
This commit is contained in:
parent
9b9fea0984
commit
e1b019000c
82
db.c
82
db.c
@ -124,7 +124,8 @@ const uint32_t INTERNAL_NODE_HEADER_SIZE = COMMON_NODE_HEADER_SIZE + INTERNAL_NO
|
|||||||
const uint32_t INTERNAL_NODE_KEY_SIZE = sizeof(uint32_t);
|
const uint32_t INTERNAL_NODE_KEY_SIZE = sizeof(uint32_t);
|
||||||
const uint32_t INTERNAL_NODE_CHILD_SIZE = sizeof(uint32_t);
|
const uint32_t INTERNAL_NODE_CHILD_SIZE = sizeof(uint32_t);
|
||||||
const uint32_t INTERNAL_NODE_CELL_SIZE = INTERNAL_NODE_CHILD_SIZE + INTERNAL_NODE_KEY_SIZE;
|
const uint32_t INTERNAL_NODE_CELL_SIZE = INTERNAL_NODE_CHILD_SIZE + INTERNAL_NODE_KEY_SIZE;
|
||||||
|
/* Keep this small for testing */
|
||||||
|
const uint32_t INTERNAL_NODE_MAX_CELLS = 3;
|
||||||
/*
|
/*
|
||||||
* Leaf Node Header Layout
|
* Leaf Node Header Layout
|
||||||
*/
|
*/
|
||||||
@ -167,6 +168,10 @@ void set_node_root(void* node, bool is_root) {
|
|||||||
*((uint8_t*)(node + IS_ROOT_OFFSET)) = value;
|
*((uint8_t*)(node + IS_ROOT_OFFSET)) = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t* node_parent(void* node) {
|
||||||
|
return node + PARENT_POINTER_OFFSET;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t* internal_node_num_keys(void* node) {
|
uint32_t* internal_node_num_keys(void* node) {
|
||||||
return node + INTERNAL_NODE_NUM_KEYS_OFFSET;
|
return node + INTERNAL_NODE_NUM_KEYS_OFFSET;
|
||||||
}
|
}
|
||||||
@ -192,7 +197,7 @@ uint32_t* internal_node_child(void* node, uint32_t child_num) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32_t* internal_node_key(void* node, uint32_t key_num) {
|
uint32_t* internal_node_key(void* node, uint32_t key_num) {
|
||||||
return internal_node_cell(node, key_num) + INTERNAL_NODE_CHILD_SIZE;
|
return (void*)internal_node_cell(node, key_num) + INTERNAL_NODE_CHILD_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t* leaf_node_num_cells(void* node) {
|
uint32_t* leaf_node_num_cells(void* node) {
|
||||||
@ -359,11 +364,14 @@ Cursor* leaf_node_find(Table* table, uint32_t page_num, uint32_t key) {
|
|||||||
return cursor;
|
return cursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
Cursor* internal_node_find(Table* table, uint32_t page_num, uint32_t key) {
|
uint32_t internal_node_find_child(void* node, uint32_t key) {
|
||||||
void* node = get_page(table->pager, page_num);
|
/*
|
||||||
|
* Return the index of the child which should contain
|
||||||
|
* the given key
|
||||||
|
*/
|
||||||
uint32_t num_keys = *internal_node_num_keys(node);
|
uint32_t num_keys = *internal_node_num_keys(node);
|
||||||
|
|
||||||
/* Binary search to find index of child to search */
|
/* Binary search */
|
||||||
uint32_t min_index = 0;
|
uint32_t min_index = 0;
|
||||||
uint32_t max_index = num_keys; /* there is one more child than key */
|
uint32_t max_index = num_keys; /* there is one more child than key */
|
||||||
|
|
||||||
@ -377,7 +385,14 @@ Cursor* internal_node_find(Table* table, uint32_t page_num, uint32_t key) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t child_num = *internal_node_child(node, min_index);
|
return min_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
Cursor* internal_node_find(Table* table, uint32_t page_num, uint32_t key) {
|
||||||
|
void *node = get_page(table->pager, page_num);
|
||||||
|
|
||||||
|
uint32_t child_index = internal_node_find_child(node, key);
|
||||||
|
uint32_t child_num = *internal_node_child(node, child_index);
|
||||||
void* child = get_page(table->pager, child_num);
|
void* child = get_page(table->pager, child_num);
|
||||||
switch (get_node_type(child)) {
|
switch (get_node_type(child)) {
|
||||||
case NODE_LEAF:
|
case NODE_LEAF:
|
||||||
@ -654,6 +669,50 @@ void create_new_root(Table* table, uint32_t right_child_page_num) {
|
|||||||
uint32_t left_child_max_key = get_node_max_key(left_child);
|
uint32_t left_child_max_key = get_node_max_key(left_child);
|
||||||
*internal_node_key(root, 0) = left_child_max_key;
|
*internal_node_key(root, 0) = left_child_max_key;
|
||||||
*internal_node_right_child(root) = right_child_page_num;
|
*internal_node_right_child(root) = right_child_page_num;
|
||||||
|
*node_parent(left_child) = table->root_page_num;
|
||||||
|
*node_parent(right_child) = table->root_page_num;
|
||||||
|
}
|
||||||
|
|
||||||
|
void internal_node_insert(Table* table, uint32_t parent_page_num, uint32_t child_page_num) {
|
||||||
|
/*
|
||||||
|
* Add a new child/key pair to parent that corresponds to child
|
||||||
|
*/
|
||||||
|
void* parent = get_page(table->pager, parent_page_num);
|
||||||
|
void* child = get_page(table->pager, child_page_num);
|
||||||
|
uint32_t child_max_key = get_node_max_key(child);
|
||||||
|
uint32_t index = internal_node_find_child(parent, child_max_key);
|
||||||
|
|
||||||
|
uint32_t original_num_keys = *internal_node_num_keys(parent);
|
||||||
|
*internal_node_num_keys(parent) = original_num_keys + 1;
|
||||||
|
|
||||||
|
if (original_num_keys >= INTERNAL_NODE_MAX_CELLS) {
|
||||||
|
printf("Need to implement splitting internal node\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t right_child_page_num = *internal_node_right_child(parent);
|
||||||
|
void* right_child = get_page(table->pager, right_child_page_num);
|
||||||
|
|
||||||
|
if (child_max_key > get_node_max_key(right_child)) {
|
||||||
|
/* Replace right child */
|
||||||
|
*internal_node_child(parent, original_num_keys) = right_child_page_num;
|
||||||
|
*internal_node_key(parent, original_num_keys) = get_node_max_key(right_child);
|
||||||
|
*internal_node_right_child(parent) = child_page_num;
|
||||||
|
} else {
|
||||||
|
/* Make room for new cell */
|
||||||
|
for (uint32_t i = original_num_keys; i > index; i--) {
|
||||||
|
void* destination = internal_node_cell(parent, i);
|
||||||
|
void* source = internal_node_cell(parent, i - 1);
|
||||||
|
memcpy(destination, source, INTERNAL_NODE_CELL_SIZE);
|
||||||
|
}
|
||||||
|
*internal_node_child(parent, index) = child_page_num;
|
||||||
|
*internal_node_key(parent, index) = child_max_key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void update_internal_node_key(void* node, uint32_t old_key, uint32_t new_key) {
|
||||||
|
uint32_t old_child_index = internal_node_find_child(node, old_key);
|
||||||
|
*internal_node_key(node, old_child_index) = new_key;
|
||||||
}
|
}
|
||||||
|
|
||||||
void leaf_node_split_and_insert(Cursor* cursor, uint32_t key, Row* value) {
|
void leaf_node_split_and_insert(Cursor* cursor, uint32_t key, Row* value) {
|
||||||
@ -663,9 +722,11 @@ void leaf_node_split_and_insert(Cursor* cursor, uint32_t key, Row* value) {
|
|||||||
* Update parent or create a new parent.
|
* Update parent or create a new parent.
|
||||||
*/
|
*/
|
||||||
void* old_node = get_page(cursor->table->pager, cursor->page_num);
|
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);
|
uint32_t new_page_num = get_unused_page_num(cursor->table->pager);
|
||||||
void* new_node = get_page(cursor->table->pager, new_page_num);
|
void* new_node = get_page(cursor->table->pager, new_page_num);
|
||||||
initialize_leaf_node(new_node);
|
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(new_node) = *leaf_node_next_leaf(old_node);
|
||||||
*leaf_node_next_leaf(old_node) = new_page_num;
|
*leaf_node_next_leaf(old_node) = new_page_num;
|
||||||
|
|
||||||
@ -701,8 +762,13 @@ void leaf_node_split_and_insert(Cursor* cursor, uint32_t key, Row* value) {
|
|||||||
if (is_node_root(old_node)) {
|
if (is_node_root(old_node)) {
|
||||||
return create_new_root(cursor->table, new_page_num);
|
return create_new_root(cursor->table, new_page_num);
|
||||||
} else {
|
} else {
|
||||||
printf("Need to implement updating parent after split\n");
|
uint32_t parent_page_num = *node_parent(old_node);
|
||||||
exit(EXIT_FAILURE);
|
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_page_num, new_page_num);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user