Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
I
ISC_144 - B+ Tree Project
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
This is an archived project. Repository and other project resources are read-only.
Show more breadcrumbs
florian.burgener
ISC_144 - B+ Tree Project
Commits
f756db1a
Commit
f756db1a
authored
2 years ago
by
Florian Burgener
Browse files
Options
Downloads
Patches
Plain Diff
Documentation
parent
778d324d
Branches
Branches containing commit
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
src/BPTree.c
+186
-7
186 additions, 7 deletions
src/BPTree.c
src/BPTree.h
+7
-7
7 additions, 7 deletions
src/BPTree.h
with
193 additions
and
14 deletions
src/BPTree.c
+
186
−
7
View file @
f756db1a
...
...
@@ -19,7 +19,7 @@
* @brief Initializes the "BPTreeNode" data structure.
*
* @param order The order of the node.
* @param is_leaf
fals
e = the node is
not
a leaf,
tru
e = the node is a leaf.
* @param is_leaf
tru
e = the node is a leaf,
fals
e = the node is
not
a leaf.
* @return BPTreeNode* The initialized node.
*/
static
BPTreeNode
*
BPTreeNode_init
(
int
order
,
bool
is_leaf
)
{
...
...
@@ -28,6 +28,7 @@ static BPTreeNode *BPTreeNode_init(int order, bool is_leaf) {
root
->
is_leaf
=
is_leaf
;
root
->
keys
=
IntegerArray_init
(
2
*
root
->
order
);
root
->
data
=
IntegerArray_init
(
2
*
root
->
order
);
// The length of the children's array is always 1 greater than the keys.
root
->
children
=
BPTreeNodeArray_init
(
2
*
root
->
order
+
1
);
root
->
next
=
NULL
;
return
root
;
...
...
@@ -99,19 +100,19 @@ bool BPTree_search(BPTreeNode *root, uint64_t key, uint64_t *data) {
return
found
;
}
int
child_index
=
IntegerArray_lower_bound
(
root
->
keys
,
key
);
int
index_in_children
=
IntegerArray_lower_bound
(
root
->
keys
,
key
);
if
(
child_index
<
root
->
keys
->
size
&&
root
->
keys
->
items
[
child_index
]
==
key
)
{
child_index
+=
1
;
if
(
index_in_children
<
root
->
keys
->
size
&&
root
->
keys
->
items
[
index_in_children
]
==
key
)
{
index_in_children
+=
1
;
}
return
BPTree_search
(
root
->
children
->
items
[
child_index
],
key
,
data
);
return
BPTree_search
(
root
->
children
->
items
[
index_in_children
],
key
,
data
);
}
// "traverse" function for insertion and deletion.
/**
* @brief Finds
the next node from a node with respect to a given
key.
* @brief Finds
out which child node to traverse based on the
key.
*
* @param node The origin node.
* @param key The key that must be compared.
...
...
@@ -121,6 +122,7 @@ static BPTreeNode *traverse(BPTreeNode *node, uint64_t key) {
int
virtual_insertion_index
=
IntegerArray_lower_bound
(
node
->
keys
,
key
);
if
(
virtual_insertion_index
<
node
->
keys
->
size
&&
node
->
keys
->
items
[
virtual_insertion_index
]
==
key
)
{
// If the key is equal to the place where it should be inserted, it is necessary to take the child to the right of it.
virtual_insertion_index
+=
1
;
}
...
...
@@ -141,6 +143,14 @@ static void insert_non_full(BPTreeNode *node, uint64_t key, uint64_t data, BPTre
}
}
/**
* @brief Redistributes the keys. The right node is empty and the left node contains all the informations.
*
* @param left_node The left node.
* @param right_node The right node.
* @param left_index The informations is cut in the left node from the left_index. The information in the left_index is not included.
* @param right_index The information is cut in the left node from the right index.
*/
static
void
redistribute_keys
(
BPTreeNode
*
left_node
,
BPTreeNode
*
right_node
,
int
left_index
,
int
right_index
)
{
for
(
int
i
=
right_index
;
i
<
left_node
->
keys
->
size
;
i
++
)
{
IntegerArray_append
(
right_node
->
keys
,
left_node
->
keys
->
items
[
i
]);
...
...
@@ -148,6 +158,7 @@ static void redistribute_keys(BPTreeNode *left_node, BPTreeNode *right_node, int
left_node
->
keys
->
size
=
left_index
;
// The data is also redistributed if there is any.
for
(
int
i
=
right_index
;
i
<
left_node
->
data
->
size
;
i
++
)
{
IntegerArray_append
(
right_node
->
data
,
left_node
->
data
->
items
[
i
]);
}
...
...
@@ -157,6 +168,15 @@ static void redistribute_keys(BPTreeNode *left_node, BPTreeNode *right_node, int
}
}
/**
* @brief Splits a leaf.
*
* @param node The node to split. It must be a leaf.
* @param key The key to insert after splitting.
* @param data The data to insert after splitting.
* @param split_right_node In this variable is assigned the right node split.
* @return uint64_t The median value resulting from the split.
*/
static
uint64_t
split_leaf
(
BPTreeNode
*
node
,
uint64_t
key
,
uint64_t
data
,
BPTreeNode
**
split_right_node
)
{
int
virtual_insertion_index
=
IntegerArray_lower_bound
(
node
->
keys
,
key
);
int
median_index
=
node
->
keys
->
size
/
2
;
...
...
@@ -164,30 +184,45 @@ static uint64_t split_leaf(BPTreeNode *node, uint64_t key, uint64_t data, BPTree
*
split_right_node
=
BPTreeNode_init
(
node
->
order
,
true
);
if
(
virtual_insertion_index
<
median_index
)
{
// The key is inserted to the left of the median value.
median_value
=
node
->
keys
->
items
[
median_index
-
1
];
redistribute_keys
(
node
,
*
split_right_node
,
median_index
-
1
,
median_index
-
1
);
// Inserts the key and the data.
int
insertion_index
=
IntegerArray_insert_sorted
(
node
->
keys
,
key
);
IntegerArray_insert_at_index
(
node
->
data
,
insertion_index
,
data
);
}
else
if
(
virtual_insertion_index
>
median_index
)
{
// The key is inserted to the right of the median value.
median_value
=
node
->
keys
->
items
[
median_index
];
redistribute_keys
(
node
,
*
split_right_node
,
median_index
,
median_index
);
// Inserts the key and the data.
int
insertion_index
=
IntegerArray_insert_sorted
((
*
split_right_node
)
->
keys
,
key
);
IntegerArray_insert_at_index
((
*
split_right_node
)
->
data
,
insertion_index
,
data
);
}
else
{
// The key is inserted at exactly the place of the median value.
median_value
=
key
;
redistribute_keys
(
node
,
*
split_right_node
,
median_index
,
median_index
);
// Inserts the key and the data.
int
insertion_index
=
IntegerArray_insert_sorted
((
*
split_right_node
)
->
keys
,
key
);
IntegerArray_insert_at_index
((
*
split_right_node
)
->
data
,
insertion_index
,
data
);
}
// Maintains the linked list of leaf nodes.
if
(
node
->
next
!=
NULL
)
{
(
*
split_right_node
)
->
next
=
node
->
next
;
}
node
->
next
=
*
split_right_node
;
return
median_value
;
}
/**
* @brief Redistributes the children. The right node is empty and the left node contains all the informations.
*
* @param left_node The left node.
* @param right_node The right node.
* @param left_index The informations is cut in the left node from the left_index. The information in the left_index is not included.
* @param right_index The information is cut in the left node from the right index.
*/
static
void
redistribute_children
(
BPTreeNode
*
left_node
,
BPTreeNode
*
right_node
,
int
left_index
,
int
right_index
)
{
for
(
int
i
=
right_index
;
i
<
left_node
->
children
->
size
;
i
++
)
{
BPTreeNodeArray_append
(
right_node
->
children
,
left_node
->
children
->
items
[
i
]);
...
...
@@ -196,6 +231,15 @@ static void redistribute_children(BPTreeNode *left_node, BPTreeNode *right_node,
left_node
->
children
->
size
=
left_index
;
}
/**
* @brief Splits an internal node.
*
* @param node The node to split. It must be an internal node.
* @param key The key to insert after splitting.
* @param previous_split_right_node The node resulting from a previous split that must be inserted after the split.
* @param split_right_node In this variable is assigned the right node split.
* @return uint64_t The median value resulting from the split.
*/
static
uint64_t
split_internal
(
BPTreeNode
*
node
,
uint64_t
key
,
BPTreeNode
*
previous_split_right_node
,
BPTreeNode
**
split_right_node
)
{
int
virtual_insertion_index
=
IntegerArray_lower_bound
(
node
->
keys
,
key
);
int
median_index
=
node
->
keys
->
size
/
2
;
...
...
@@ -203,27 +247,43 @@ static uint64_t split_internal(BPTreeNode *node, uint64_t key, BPTreeNode *previ
*
split_right_node
=
BPTreeNode_init
(
node
->
order
,
false
);
if
(
virtual_insertion_index
<
median_index
)
{
// The key is inserted to the left of the median value.
median_value
=
node
->
keys
->
items
[
median_index
-
1
];
redistribute_keys
(
node
,
*
split_right_node
,
median_index
-
1
,
median_index
);
redistribute_children
(
node
,
*
split_right_node
,
median_index
,
median_index
);
int
insertion_index
=
IntegerArray_insert_sorted
(
node
->
keys
,
key
);
// previous_split_right_node is inserted to the right of the key in the child array.
BPTreeNodeArray_insert_at_index
(
node
->
children
,
insertion_index
+
1
,
previous_split_right_node
);
}
else
if
(
virtual_insertion_index
>
median_index
)
{
// The key is inserted to the right of the median value.
median_value
=
node
->
keys
->
items
[
median_index
];
redistribute_keys
(
node
,
*
split_right_node
,
median_index
,
median_index
+
1
);
redistribute_children
(
node
,
*
split_right_node
,
median_index
+
1
,
median_index
+
1
);
int
insertion_index
=
IntegerArray_insert_sorted
((
*
split_right_node
)
->
keys
,
key
);
// previous_split_right_node is inserted to the right of the key in the child array.
BPTreeNodeArray_insert_at_index
((
*
split_right_node
)
->
children
,
insertion_index
+
1
,
previous_split_right_node
);
}
else
{
// The key is inserted at exactly the place of the median value.
median_value
=
key
;
redistribute_keys
(
node
,
*
split_right_node
,
median_index
,
median_index
);
redistribute_children
(
node
,
*
split_right_node
,
median_index
+
1
,
median_index
+
1
);
// previous_split_right_node is always inserted at index 0 the array of children of split_right_node.
BPTreeNodeArray_insert_at_index
((
*
split_right_node
)
->
children
,
0
,
previous_split_right_node
);
}
return
median_value
;
}
/**
* @brief Inserts information when the node is full.
*
* @param node The node to split.
* @param key The key to insert after splitting.
* @param data The data to insert after splitting.
* @param previous_split_right_node The node resulting from a previous split that must be inserted after the split.
* @param split_right_node In this variable is assigned the right node split.
* @return uint64_t The median value resulting from the split.
*/
static
uint64_t
insert_full
(
BPTreeNode
*
node
,
uint64_t
key
,
uint64_t
data
,
BPTreeNode
*
previous_split_right_node
,
BPTreeNode
**
split_right_node
)
{
if
(
node
->
is_leaf
)
{
return
split_leaf
(
node
,
key
,
data
,
split_right_node
);
...
...
@@ -232,12 +292,22 @@ static uint64_t insert_full(BPTreeNode *node, uint64_t key, uint64_t data, BPTre
return
split_internal
(
node
,
key
,
previous_split_right_node
,
split_right_node
);
}
/**
* @brief Grows the tree.
*
* @param root The real root node.
* @param median_value The median value of the split.
* @param split_right_node The right node of the split.
*/
static
void
grow
(
BPTreeNode
*
root
,
uint64_t
median_value
,
BPTreeNode
*
split_right_node
)
{
// When the tree grows is necessarily no longer a leaf.
root
->
is_leaf
=
false
;
BPTreeNode
*
left_node
=
BPTreeNode_init
(
root
->
order
,
split_right_node
->
is_leaf
);
// Maintains the linked list of leaf nodes.
left_node
->
next
=
root
->
next
;
root
->
next
=
NULL
;
// Copy the data from the root to the left_node.
IntegerArray_copy
(
root
->
keys
,
left_node
->
keys
);
IntegerArray_copy
(
root
->
data
,
left_node
->
data
);
BPTreeNodeArray_copy
(
root
->
children
,
left_node
->
children
);
...
...
@@ -246,37 +316,57 @@ static void grow(BPTreeNode *root, uint64_t median_value, BPTreeNode *split_righ
IntegerArray_clear
(
root
->
data
);
BPTreeNodeArray_clear
(
root
->
children
);
// Reorganizes the root node.
IntegerArray_append
(
root
->
keys
,
median_value
);
BPTreeNodeArray_append
(
root
->
children
,
left_node
);
BPTreeNodeArray_append
(
root
->
children
,
split_right_node
);
}
/**
* @brief Insertion sub-function that performs the insertion recursively.
*
* @param parent The parent of the root node.
* @param root The root node.
* @param key The key to insert. A pointer is used for recursions.
* @param data The data to be inserted with the key.
* @param split_right_node A pointer is used for recursions.
* @return true The key has been inserted.
* @return false The key has not been inserted.
*/
static
bool
_BPTree_insert
(
BPTreeNode
*
parent
,
BPTreeNode
*
root
,
uint64_t
*
key
,
uint64_t
data
,
BPTreeNode
**
split_right_node
)
{
BPTreeNode
*
previous_split_right_node
=
NULL
;
if
(
!
root
->
is_leaf
&&
!
_BPTree_insert
(
root
,
traverse
(
root
,
*
key
),
key
,
data
,
&
previous_split_right_node
))
{
// The previous recursion indicates that it is not possible to insert the key.
return
false
;
}
// The first time the leaf is visited, it is necessary to check if it is possible to insert the key.
int
index
;
bool
is_found
=
IntegerArray_binary_search
(
root
->
keys
,
*
key
,
&
index
);
if
(
root
->
is_leaf
&&
is_found
)
{
// The key cannot be inserted because it already exists.
return
false
;
}
if
(
!
root
->
is_leaf
&&
previous_split_right_node
==
NULL
)
{
// Prevents from reaching the code below because the insertion is finished.
*
split_right_node
=
NULL
;
return
true
;
}
if
(
root
->
keys
->
size
<
2
*
root
->
order
)
{
// There is enough room in the root node to insert the key.
insert_non_full
(
root
,
*
key
,
data
,
previous_split_right_node
);
// End the insertions.
*
split_right_node
=
NULL
;
return
true
;
}
// Inserts and splits the root node.
*
key
=
insert_full
(
root
,
*
key
,
data
,
previous_split_right_node
,
split_right_node
);
if
(
parent
==
NULL
)
{
// If the root node is the real root, the tree must grow.
grow
(
root
,
*
key
,
*
split_right_node
);
}
...
...
@@ -290,6 +380,12 @@ bool BPTree_insert(BPTreeNode *root, uint64_t key, uint64_t data) {
// BPTree : Deletion
/**
* @brief Finds the smallest key in the subtree.
*
* @param root The root node of a subtree.
* @return uint64_t The smallest key of the subtree.
*/
static
uint64_t
find_smallest_key
(
BPTreeNode
*
root
)
{
if
(
root
->
is_leaf
)
{
return
root
->
keys
->
items
[
0
];
...
...
@@ -298,10 +394,16 @@ static uint64_t find_smallest_key(BPTreeNode *root) {
return
find_smallest_key
(
root
->
children
->
items
[
0
]);
}
/**
* @brief Shrinks the height of the tree.
*
* @param root The real root node of the tree.
*/
static
void
shrink
(
BPTreeNode
*
root
)
{
BPTreeNode
*
child
=
root
->
children
->
items
[
0
];
root
->
is_leaf
=
child
->
is_leaf
;
// Copies the information of the only child in the root.
IntegerArray_copy
(
child
->
keys
,
root
->
keys
);
IntegerArray_copy
(
child
->
data
,
root
->
data
);
...
...
@@ -311,36 +413,66 @@ static void shrink(BPTreeNode *root) {
BPTreeNode_destroy
(
&
child
);
}
/**
* @brief Finds the best sibling of the node.
*
* @param parent The parent of the node.
* @param node The node.
* @return BPTreeNode* The best sibling.
*/
static
BPTreeNode
*
find_sibling
(
BPTreeNode
*
parent
,
BPTreeNode
*
node
)
{
int
index_in_children
=
BPTreeNodeArray_search
(
parent
->
children
,
node
);
if
(
index_in_children
==
0
)
{
// No other choice but to take the index 1.
return
parent
->
children
->
items
[
1
];
}
if
(
index_in_children
==
parent
->
children
->
size
-
1
)
{
// No other choice but to take the index parent->children->size - 2.
return
parent
->
children
->
items
[
parent
->
children
->
size
-
2
];
}
if
(
parent
->
children
->
items
[
index_in_children
-
1
]
->
keys
->
size
>
parent
->
order
)
{
// The left sibling has enough keys.
return
parent
->
children
->
items
[
index_in_children
-
1
];
}
if
(
parent
->
children
->
items
[
index_in_children
+
1
]
->
keys
->
size
>
parent
->
order
)
{
// The right sibling has enough keys.
return
parent
->
children
->
items
[
index_in_children
+
1
];
}
// None of the siblings have enough keys, so the left sibling is chosen.
return
parent
->
children
->
items
[
index_in_children
-
1
];
}
/**
* @brief Checks if the sibling is to the left side of the node.
*
* @param parent The parent of the node and the sibling.
* @param node The node.
* @param sibling The sibling.
* @return true The sibling is to the left of the node.
* @return false The sibling is not on the left of the node.
*/
static
bool
is_sibling_left_side
(
BPTreeNode
*
parent
,
BPTreeNode
*
node
,
BPTreeNode
*
sibling
)
{
return
BPTreeNodeArray_search
(
parent
->
children
,
sibling
)
<
BPTreeNodeArray_search
(
parent
->
children
,
node
);
}
/**
* @brief Merges the left node and the right node.
*
* @param parent The parent of the left_node and right_node.
* @param left_node The left node.
* @param right_node The right node.
*/
static
void
merge
(
BPTreeNode
*
parent
,
BPTreeNode
*
left_node
,
BPTreeNode
*
right_node
)
{
// The right node is always merged into the left node.
int
index_in_children
=
BPTreeNodeArray_search
(
parent
->
children
,
left_node
);
if
(
!
left_node
->
is_leaf
)
{
// If it is an internal node the key that links the left and right nodes must also be merge.
IntegerArray_append
(
left_node
->
keys
,
parent
->
keys
->
items
[
index_in_children
]);
}
...
...
@@ -359,16 +491,28 @@ static void merge(BPTreeNode *parent, BPTreeNode *left_node, BPTreeNode *right_n
BPTreeNodeArray_append
(
left_node
->
children
,
right_node
->
children
->
items
[
i
]);
}
// Deletes the correct information from the parent.
IntegerArray_delete_at_index
(
parent
->
keys
,
index_in_children
);
BPTreeNodeArray_delete_at_index
(
parent
->
children
,
index_in_children
+
1
);
// Maintains the linked list of leaf nodes.
left_node
->
next
=
right_node
->
next
;
BPTreeNode_destroy
(
&
right_node
);
}
/**
* @brief Steals a key from the sibling. The nodes are leaf.
*
* @param parent The parent of the node and the sibling.
* @param node The node.
* @param sibling The sibling.
*/
static
void
steal_leaf
(
BPTreeNode
*
parent
,
BPTreeNode
*
node
,
BPTreeNode
*
sibling
)
{
int
index_in_children
=
BPTreeNodeArray_search
(
parent
->
children
,
node
);
if
(
is_sibling_left_side
(
parent
,
node
,
sibling
))
{
// If the sibling is on the left the last key is stolen from the sibling.
uint64_t
stealed_key
=
sibling
->
keys
->
items
[
sibling
->
keys
->
size
-
1
];
IntegerArray_insert_at_index
(
node
->
keys
,
0
,
stealed_key
);
IntegerArray_delete_at_index
(
sibling
->
keys
,
sibling
->
keys
->
size
-
1
);
...
...
@@ -378,6 +522,7 @@ static void steal_leaf(BPTreeNode *parent, BPTreeNode *node, BPTreeNode *sibling
IntegerArray_insert_at_index
(
node
->
data
,
0
,
sibling
->
data
->
items
[
sibling
->
data
->
size
-
1
]);
IntegerArray_delete_at_index
(
sibling
->
data
,
sibling
->
data
->
size
-
1
);
}
else
{
// If the sibling is on the right the first key is stolen from the sibling.
uint64_t
stealed_key
=
sibling
->
keys
->
items
[
0
];
IntegerArray_append
(
node
->
keys
,
stealed_key
);
IntegerArray_delete_at_index
(
sibling
->
keys
,
0
);
...
...
@@ -389,16 +534,25 @@ static void steal_leaf(BPTreeNode *parent, BPTreeNode *node, BPTreeNode *sibling
}
}
/**
* @brief Steals a key from the sibling. The nodes are internal.
*
* @param parent The parent of the node and the sibling.
* @param node The node.
* @param sibling The sibling.
*/
static
void
steal_internal
(
BPTreeNode
*
parent
,
BPTreeNode
*
node
,
BPTreeNode
*
sibling
)
{
int
index_in_children
=
BPTreeNodeArray_search
(
parent
->
children
,
node
);
if
(
is_sibling_left_side
(
parent
,
node
,
sibling
))
{
// If the sibling is on the left the last key is stolen from the sibling.
IntegerArray_insert_at_index
(
node
->
keys
,
0
,
parent
->
keys
->
items
[
index_in_children
-
1
]);
parent
->
keys
->
items
[
index_in_children
-
1
]
=
sibling
->
keys
->
items
[
sibling
->
keys
->
size
-
1
];
IntegerArray_delete_at_index
(
sibling
->
keys
,
sibling
->
keys
->
size
-
1
);
BPTreeNodeArray_insert_at_index
(
node
->
children
,
0
,
sibling
->
children
->
items
[
sibling
->
children
->
size
-
1
]);
BPTreeNodeArray_delete_at_index
(
sibling
->
children
,
sibling
->
children
->
size
-
1
);
}
else
{
// If the sibling is on the right the first key is stolen from the sibling.
IntegerArray_append
(
node
->
keys
,
parent
->
keys
->
items
[
index_in_children
]);
parent
->
keys
->
items
[
index_in_children
]
=
sibling
->
keys
->
items
[
0
];
IntegerArray_delete_at_index
(
sibling
->
keys
,
0
);
...
...
@@ -407,45 +561,70 @@ static void steal_internal(BPTreeNode *parent, BPTreeNode *node, BPTreeNode *sib
}
}
/**
* @brief Rebalances the tree.
*
* @param parent The parent of the node.
* @param node The node.
*/
static
void
deletion_rebalance
(
BPTreeNode
*
parent
,
BPTreeNode
*
node
)
{
BPTreeNode
*
sibling
=
find_sibling
(
parent
,
node
);
if
(
sibling
->
keys
->
size
==
sibling
->
order
)
{
// The sibling does not have enough keys to steal one, a merge is required.
if
(
is_sibling_left_side
(
parent
,
node
,
sibling
))
{
merge
(
parent
,
sibling
,
node
);
}
else
{
merge
(
parent
,
node
,
sibling
);
}
}
else
if
(
node
->
is_leaf
)
{
// Steals a key from a leaf.
steal_leaf
(
parent
,
node
,
sibling
);
}
else
{
// Steals a key from an internal node.
steal_internal
(
parent
,
node
,
sibling
);
}
}
/**
* @brief Sub-function of deletion that performs the deletion recursively.
*
* @param parent The parent of the root node.
* @param root The root node.
* @param key The key to delete.
* @return true The key has been deleted.
* @return false The key has not been deleted.
*/
static
bool
_BPTree_delete
(
BPTreeNode
*
parent
,
BPTreeNode
*
root
,
uint64_t
key
)
{
if
(
!
root
->
is_leaf
&&
!
_BPTree_delete
(
root
,
traverse
(
root
,
key
),
key
))
{
// The previous recursion indicates that it is not possible to delete the key.
return
false
;
}
// The first time the leaf is visited, it is necessary to check if it is possible to delete the key.
int
index
;
bool
is_found
=
IntegerArray_binary_search
(
root
->
keys
,
key
,
&
index
);
if
(
root
->
is_leaf
&&
!
is_found
)
{
// The key cannot be inserted because it doesn't exists.
return
false
;
}
if
(
root
->
is_leaf
)
{
// The key is deleted from the leaf as well as its data.
IntegerArray_delete_at_index
(
root
->
keys
,
index
);
IntegerArray_delete_at_index
(
root
->
data
,
index
);
}
else
if
(
is_found
)
{
// The key must be replaced by the smallest key of the right subtree.
root
->
keys
->
items
[
index
]
=
find_smallest_key
(
root
->
children
->
items
[
index
+
1
]);
}
if
(
parent
==
NULL
&&
!
root
->
is_leaf
&&
root
->
keys
->
size
==
0
)
{
// The real root node of the tree is empty, the tree must be shrink.
shrink
(
root
);
}
if
(
parent
!=
NULL
&&
root
->
keys
->
size
<
root
->
order
)
{
// Rebalances of the tree after deletion.
deletion_rebalance
(
parent
,
root
);
}
...
...
This diff is collapsed.
Click to expand it.
src/BPTree.h
+
7
−
7
View file @
f756db1a
...
...
@@ -26,7 +26,7 @@ typedef struct BPTreeNode {
}
BPTreeNode
;
/**
* @brief Initializes
the
B+ Tree
data structure
.
* @brief Initializes
a
B+ Tree.
*
* @param order The order of the B+ Tree.
* @return BPTreeNode* An empty B+ Tree.
...
...
@@ -44,7 +44,7 @@ void BPTree_destroy(BPTreeNode **root);
* @brief Displays the B+ Tree.
*
* @param root The root of the B+ Tree.
* @param depth
Pass the value 0
.
* @param depth
Always pass 0 to this variable
.
*/
void
BPTree_print
(
BPTreeNode
*
root
,
int
depth
);
...
...
@@ -54,7 +54,7 @@ void BPTree_print(BPTreeNode *root, int depth);
* @param root The root of the B+ Tree.
* @param key The key to search.
* @param data The data found will be assigned to this variable.
* @return true The key exists in the B+
T
ree.
* @return true
The key exists in the B+
t
ree.
* @return false The key does not exist in the B+ Tree.
*/
bool
BPTree_search
(
BPTreeNode
*
root
,
uint64_t
key
,
uint64_t
*
data
);
...
...
@@ -65,8 +65,8 @@ bool BPTree_search(BPTreeNode *root, uint64_t key, uint64_t *data);
* @param root The root of the B+ Tree.
* @param key The key to insert.
* @param data The data to be inserted with the key.
* @return true The key
could
be inserted.
* @return false The key
could
not be inserted.
* @return true The key
has
be
en
inserted.
* @return false The key
has
not be
en
inserted.
*/
bool
BPTree_insert
(
BPTreeNode
*
root
,
uint64_t
key
,
uint64_t
data
);
...
...
@@ -75,8 +75,8 @@ bool BPTree_insert(BPTreeNode *root, uint64_t key, uint64_t data);
*
* @param root The root of the B+ Tree.
* @param key The key to be deleted.
* @return true The key
could
be deleted.
* @return false The key
could
not be deleted.
* @return true The key
has
be
en
deleted.
* @return false The key
has
not be
en
deleted.
*/
bool
BPTree_delete
(
BPTreeNode
*
root
,
uint64_t
key
);
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment