I am trying to implement a BTree. As far as I understand the lower the height of the Tree the faster the search (This could be wrong, please correct me if it is).
Is pre-emptive split with non-pre-emptive merge the best or non-pre-emptive split with pre-emptive merge or the other 2 combinations left? Which offers better performance and why? I search online I could not find any article that discussed anything regarding this.
After this I need to implement insert. So, I hoping someone can impart some knowledge on which is better?
So, far I do not have much code except the following because I cannot decide which method I should choose and Why? I want fast insertion deletion and search.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
static enum TreeProperties {
MIN_CHILDREN = 2,
MAX_CHILDREN = 6,
MAX_KEYS = MAX_CHILDREN - 1,
MIN_KEYS = MIN_CHILDREN - 1, // except root
SPLIT_KEYS = MAX_KEYS - MIN_CHILDREN,
SPLIT_KEY_INDEX = MIN_CHILDREN,
SPLIT_LINKS = SPLIT_KEYS + 1,
SPLIT_LINK_INDEX = SPLIT_KEY_INDEX + 1,
MAX_LINKS = MAX_CHILDREN
};
typedef struct BTreeNode {
struct BTreeNode *links[MAX_LINKS];
int keys[MAX_KEYS];
size_t keyCount;
}BTreeNode;
#define firstLink links[0]
/* New node allocation */
static inline size_t childrenNum(BTreeNode *node) {
return node->keyCount + 1;
}
static inline BTreeNode _createNode() {
BTreeNode newNode = (BTreeNode)malloc(sizeof(BTreeNode));
if(!newNode) {
fprintf(stderr, "New node init failed: out of memory\n");
exit(EXIT_FAILURE);
}
memset(newNode->links, 0, sizeof(BTreeNode)MAX_CHILDREN);
return newNode;
}
BTreeNode BTree_createEmptyNode() {
BTreeNode newNode = _createNode();
newNode->keyCount = 0;
return newNode;
}
BTreeNode BTree_createRightSplitNode(BTreeNode nodeToSplit) {
BTreeNode newNode = _createNode();
memcpy(newNode->keys, nodeToSplit->keys + SPLIT_KEY_INDEX, sizeof(newNode->keys[0]) SPLIT_KEYS);
if(nodeToSplit->firstLink) {
memcpy(newNode->links, nodeToSplit->links + SPLIT_LINK_INDEX, sizeof(BTreeNode) (SPLIT_LINKS));
memset(nodeToSplit->links + SPLIT_LINK_INDEX, 0, sizeof(BTreeNode) SPLIT_LINKS);
}
newNode->keyCount = SPLIT_KEYS;
nodeToSplit->keyCount = MIN_KEYS;
}
/* End new node allocation */
/* Search /
static bool isKeyInNodeOrGiveNextLink(int key, BTreeNode current, size_t idx /, size_t * parentLinkIdxToKeyNode/) {
idx = 0;
while (idx < current->keyCount && key > current->keys[idx]) {
if(current->keys[*idx] == key ) {
return true;
}
//parentLinkIdxToKeyNode = linkIdx;
(*idx)++;
}
return false;
}
BTreeNode* BTree_search(int key, BTreeNode *current) {
size_t i;
while(current) {
if(isKeyInNodeOrGiveNextLink(key, current, &i)) return current;
current = current->links[i];
}
return NULL;
}