From 35b5c6f9db7406ba7ce759229670949d0225454a Mon Sep 17 00:00:00 2001 From: Andreas Schmidt Date: Thu, 17 Mar 2016 15:03:50 +0100 Subject: [PATCH] BPTree now supports larger keys. Extract dataPacketStore. --- src/cython/cprrt.pxd | 2 +- src/prrt/CMakeLists.txt | 2 +- src/prrt/processes/dataReceiver.c | 12 +-- src/prrt/socket.c | 16 +-- src/prrt/socket.h | 4 +- src/prrt/stores/dataPacketStore.c | 72 ++++++++++++++ src/prrt/stores/dataPacketStore.h | 19 ++++ src/prrt/stores/packetTimeoutTable.c | 2 +- src/prrt/stores/repairBlockStore.c | 3 +- src/util/bptree.c | 140 ++++++++++++++------------- src/util/bptree.h | 16 +-- 11 files changed, 185 insertions(+), 103 deletions(-) create mode 100644 src/prrt/stores/dataPacketStore.c create mode 100644 src/prrt/stores/dataPacketStore.h diff --git a/src/cython/cprrt.pxd b/src/cython/cprrt.pxd index 03d1bd9b..6b384f39 100644 --- a/src/cython/cprrt.pxd +++ b/src/cython/cprrt.pxd @@ -107,7 +107,7 @@ cdef extern from "prrt/socket.h": BPTreeNode* dataStore - BPTreeNode* blockStore + PrrtRepairBlockStore* repairBlockStore PrrtForwardPacketTable* forwardPacketTable diff --git a/src/prrt/CMakeLists.txt b/src/prrt/CMakeLists.txt index e78d5fc7..cf6ba260 100644 --- a/src/prrt/CMakeLists.txt +++ b/src/prrt/CMakeLists.txt @@ -12,6 +12,6 @@ add_library(PRRT ../defines.h stores/lossGatherer.c stores/lossGatherer.h processes/dataReceiver.c processes/dataReceiver.h processes/feedbackReceiver.c processes/feedbackReceiver.h - processes/dataTransmitter.c processes/dataTransmitter.h processes/cleaner.c processes/cleaner.h stores/repairBlockStore.c stores/repairBlockStore.h stores/packetTimeoutTable.c stores/packetTimeoutTable.h) + processes/dataTransmitter.c processes/dataTransmitter.h processes/cleaner.c processes/cleaner.h stores/repairBlockStore.c stores/repairBlockStore.h stores/packetTimeoutTable.c stores/packetTimeoutTable.h stores/dataPacketStore.c stores/dataPacketStore.h) set_property(TARGET PRRT PROPERTY C_STANDARD 99) \ No newline at end of file diff --git a/src/prrt/processes/dataReceiver.c b/src/prrt/processes/dataReceiver.c index 4bfae552..ef051765 100644 --- a/src/prrt/processes/dataReceiver.c +++ b/src/prrt/processes/dataReceiver.c @@ -12,13 +12,14 @@ void retrieve_data_blocks(PrrtSocket *sock_ptr, prrtSequenceNumber_t base_seqno, uint8_t k, const PrrtBlock *block) { List *res = List_create(); - BPTree_get_range(sock_ptr->dataStore, res, base_seqno, base_seqno + k - 1); + + PrrtDataPacketStore_remove_range(sock_ptr->dataPacketStore, res, base_seqno, (prrtSequenceNumber_t) (base_seqno + k - 1)); LIST_FOREACH(res, first, next, cur) { PrrtPacket *packetPtr = cur->value; check(PrrtBlock_insert_data_packet((PrrtBlock *) block, packetPtr), "Insert failed!") - sock_ptr->dataStore = BPTree_delete(sock_ptr->dataStore, packetPtr->sequenceNumber); } + error: List_destroy(res); } @@ -122,10 +123,7 @@ void handle_data_packet(PrrtSocket *sock_ptr, PrrtPacket *packet, struct sockadd check(PrrtBlock_insert_data_packet(block, reference), "Inserting failed"); decode_block(sock_ptr, block); } else { - // Check for duplicate data packet. - if(BPTree_get(sock_ptr->dataStore, packet->sequenceNumber) == NULL) { - sock_ptr->dataStore = BPTree_insert(sock_ptr->dataStore, packet->sequenceNumber, reference); - } else { + if(PrrtDataStore_insert(sock_ptr->dataPacketStore, reference) == false) { PrrtPacket_destroy(reference); } } @@ -207,8 +205,6 @@ void *receive_data_loop(void *ptr) } } - // TODO: occasionally clean up dataStore !!! - error: PNOTIMPLEMENTED("SHOULD IMPLEMENT ERROR HANDLER HERE"); } diff --git a/src/prrt/socket.c b/src/prrt/socket.c index 6d4e909d..32e8a141 100644 --- a/src/prrt/socket.c +++ b/src/prrt/socket.c @@ -38,7 +38,7 @@ PrrtSocket *PrrtSocket_create(const bool is_sender) sock_ptr->packetTimeoutTable = PrrtPacketTimeoutTable_create(); - sock_ptr->dataStore = NULL; + sock_ptr->dataPacketStore = PrrtDataPacketStore_create(); check(sock_ptr->dataSocketFd = socket(AF_INET, SOCK_DGRAM, 0), "Cannot create data socket.") check(sock_ptr->feedbackSocketFd = socket(AF_INET, SOCK_DGRAM, 0), "Cannot create feedback socket."); @@ -215,17 +215,9 @@ int PrrtSocket_close(PrrtSocket *sock_ptr) { check(pthread_mutex_unlock(&sock_ptr->closingMutex) == 0, "Unlock failed."); } - if (sock_ptr->dataStore != NULL) { - List *dataList = List_create(); - BPTree_get_range(sock_ptr->dataStore, dataList, 0, SEQNO_SPACE - 1); - while (List_count(dataList) > 0) { - PrrtPacket *packet = List_shift(dataList); - PrrtPacket_destroy(packet); - } - - List_destroy(dataList); - - sock_ptr->dataStore = BPTree_destroy(sock_ptr->dataStore); + if(sock_ptr->dataPacketStore != NULL) { + check(PrrtDataPacketStore_destroy(sock_ptr->dataPacketStore), "Destroy failed."); + sock_ptr->dataPacketStore = NULL; } if(sock_ptr->repairBlockStore != NULL) { diff --git a/src/prrt/socket.h b/src/prrt/socket.h index bafb31a7..2aa51b2b 100644 --- a/src/prrt/socket.h +++ b/src/prrt/socket.h @@ -8,6 +8,7 @@ #include "../util/bptree.h" #include "channelStateInformation.h" #include "applicationConstraints.h" +#include "stores/dataPacketStore.h" #include "stores/packetTimeoutTable.h" #include "stores/repairBlockStore.h" #include "clock.h" @@ -35,10 +36,7 @@ typedef struct prrtSocket { pthread_t cleanupThread; - BPTreeNode* dataStore; - PrrtPacketTimeoutTable* packetTimeoutTable; - PrrtDataPacketStore* dataPacketStore; PrrtRepairBlockStore* repairBlockStore; diff --git a/src/prrt/stores/dataPacketStore.c b/src/prrt/stores/dataPacketStore.c new file mode 100644 index 00000000..3457f3dc --- /dev/null +++ b/src/prrt/stores/dataPacketStore.c @@ -0,0 +1,72 @@ +#include +#include +#include "../../util/common.h" +#include "../../util/bptree.h" +#include "../../util/dbg.h" +#include "../packet.h" +#include "dataPacketStore.h" + + +PrrtDataPacketStore *PrrtDataPacketStore_create(void) +{ + PrrtDataPacketStore* store = calloc(1, sizeof(PrrtDataPacketStore)); + check_mem(store); + check(pthread_mutex_init(&store->lock, NULL) == EXIT_SUCCESS, "Init mutex failed.") + + return store; + error: + PERROR("Out of memory%s.",""); + return NULL; +} + +uint32_t PrrtDataPacketStore_size(PrrtDataPacketStore *store) +{ + check(pthread_mutex_lock(&store->lock) == EXIT_SUCCESS, "Lock failed."); + uint32_t res = BPTree_size(store->dataStore); + check(pthread_mutex_unlock(&store->lock) == EXIT_SUCCESS, "Unlock failed."); + return res; + error: + PERROR("Getting size failed%s.", ""); + return 0; +} + +bool PrrtDataPacketStore_destroy(PrrtDataPacketStore *store) +{ + List *dataList = List_create(); + BPTree_get_range(store->dataStore, dataList, 0, SEQNO_SPACE - 1); + while(List_count(dataList) > 0) { + PrrtPacket *packet = List_shift(dataList); + PrrtPacket_destroy(packet); + } + + List_destroy(dataList); + + check(pthread_mutex_destroy(&store->lock) == EXIT_SUCCESS, "Destroy failed."); + + store->dataStore = BPTree_destroy(store->dataStore); + + free(store); + return true; + error: + PERROR("Could not destroy%s.",""); + return false; +} + +void PrrtDataPacketStore_remove_range(PrrtDataPacketStore *store, List *res, prrtSequenceNumber_t start, prrtSequenceNumber_t stop) +{ + // TODO: handle if start > stop + BPTree_get_range(store->dataStore, res, start, stop); + LIST_FOREACH(res, first, next, current) { + PrrtPacket *packet = current->value; + store->dataStore = BPTree_delete(store->dataStore, packet->sequenceNumber); + } +} + +bool PrrtDataStore_insert(PrrtDataPacketStore *store, PrrtPacket *packet) +{ + if(BPTree_get(store->dataStore, packet->sequenceNumber) == NULL) { + store->dataStore = BPTree_insert(store->dataStore, packet->sequenceNumber, packet); + return true; + } + return false; +} diff --git a/src/prrt/stores/dataPacketStore.h b/src/prrt/stores/dataPacketStore.h new file mode 100644 index 00000000..a7770ea0 --- /dev/null +++ b/src/prrt/stores/dataPacketStore.h @@ -0,0 +1,19 @@ +#include +#include +#include + +#ifndef PRRT_DATAPACKETSTORE_H +#define PRRT_DATAPACKETSTORE_H + +typedef struct prrtDataPacketStore { + pthread_mutex_t lock; + BPTreeNode* dataStore; +} PrrtDataPacketStore; + +PrrtDataPacketStore* PrrtDataPacketStore_create(void); +uint32_t PrrtDataPacketStore_size(PrrtDataPacketStore* store); +void PrrtDataPacketStore_remove_range(PrrtDataPacketStore *store, List *res, prrtSequenceNumber_t start, prrtSequenceNumber_t stop); +bool PrrtDataPacketStore_destroy(PrrtDataPacketStore* store); +bool PrrtDataStore_insert(PrrtDataPacketStore *store, PrrtPacket *packet); + +#endif //PRRT_DATAPACKETSTORE_H diff --git a/src/prrt/stores/packetTimeoutTable.c b/src/prrt/stores/packetTimeoutTable.c index 81b1d36b..6a1042c1 100644 --- a/src/prrt/stores/packetTimeoutTable.c +++ b/src/prrt/stores/packetTimeoutTable.c @@ -10,7 +10,7 @@ PrrtPacketTimeoutTable *PrrtPacketTimeoutTable_create(void) table->packetList = NULL; - pthread_mutex_init(&table->lock, NULL); + check(pthread_mutex_init(&table->lock, NULL) == EXIT_SUCCESS, "Init mutex failed."); return table; error: diff --git a/src/prrt/stores/repairBlockStore.c b/src/prrt/stores/repairBlockStore.c index 3e8bd223..30d82d71 100644 --- a/src/prrt/stores/repairBlockStore.c +++ b/src/prrt/stores/repairBlockStore.c @@ -8,7 +8,7 @@ PrrtRepairBlockStore *PrrtRepairBlockStore_create(void) PrrtRepairBlockStore *store = (PrrtRepairBlockStore *) calloc(1, sizeof(PrrtRepairBlockStore)); check_mem(store); - pthread_mutex_init(&store->lock, NULL); + check(pthread_mutex_init(&store->lock, NULL) == EXIT_SUCCESS, "Init mutex failed."); store->blockTree = NULL; return store; @@ -86,7 +86,6 @@ bool PrrtRepairBlockStore_expire_block_range(PrrtRepairBlockStore *store, prrtSe check(pthread_mutex_lock(&store->lock) == EXIT_SUCCESS, "Lock failed."); while(start != stop) { store->blockTree = BPTree_delete(store->blockTree, start); - debug("EXPIRE BLOCK: %d", start); start++; } check(pthread_mutex_unlock(&store->lock) == EXIT_SUCCESS, "Unlock failed."); diff --git a/src/util/bptree.c b/src/util/bptree.c index 3f865f85..a34bd4f7 100644 --- a/src/util/bptree.c +++ b/src/util/bptree.c @@ -47,7 +47,6 @@ typedef struct { void *value; } BPTreeRecord; - // GLOBALS. /* The order determines the maximum and minimum number of entries (keys and pointers) in any node. Every node has at @@ -72,15 +71,15 @@ void enqueue(BPTreeNode *new_node); BPTreeNode *dequeue(void); -int path_to_root(BPTreeNode *root, BPTreeNode *child); +BPTreeKey_t path_to_root(BPTreeNode *root, BPTreeNode *child); -int find_range(BPTreeNode *root, int key_start, int key_end, int returned_keys[], void *returned_pointers[]); +BPTreeKey_t find_range(BPTreeNode *root, BPTreeKey_t key_start, BPTreeKey_t key_end, BPTreeKey_t *returned_keys, void **returned_pointers); -BPTreeNode *find_leaf(BPTreeNode *root, int key); +BPTreeNode *find_leaf(BPTreeNode *root, BPTreeKey_t key); -BPTreeRecord *find(BPTreeNode *root, int key); +BPTreeRecord *find(BPTreeNode *root, BPTreeKey_t key); -int cut(int length); +BPTreeKey_t cut(BPTreeKey_t length); // Insertion. @@ -90,36 +89,36 @@ BPTreeNode *make_node(void); BPTreeNode *make_leaf(void); -int get_left_index(BPTreeNode *parent, BPTreeNode *left); +BPTreeKey_t get_left_index(BPTreeNode *parent, BPTreeNode *left); -BPTreeNode *insert_into_leaf(BPTreeNode *leaf, int key, BPTreeRecord *pointer); +BPTreeNode *insert_into_leaf(BPTreeNode *leaf, BPTreeKey_t key, BPTreeRecord *pointer); -BPTreeNode *insert_into_leaf_after_splitting(BPTreeNode *root, BPTreeNode *leaf, int key, BPTreeRecord *pointer); +BPTreeNode *insert_into_leaf_after_splitting(BPTreeNode *root, BPTreeNode *leaf, BPTreeKey_t key, BPTreeRecord *pointer); BPTreeNode *insert_into_node(BPTreeNode *root, BPTreeNode *parent, - int left_index, int key, BPTreeNode *right); + BPTreeKey_t left_index, BPTreeKey_t key, BPTreeNode *right); -BPTreeNode *insert_into_node_after_splitting(BPTreeNode *root, BPTreeNode *parent, int left_index, - int key, BPTreeNode *right); +BPTreeNode *insert_into_node_after_splitting(BPTreeNode *root, BPTreeNode *parent, BPTreeKey_t left_index, + BPTreeKey_t key, BPTreeNode *right); -BPTreeNode *insert_into_parent(BPTreeNode *root, BPTreeNode *left, int key, BPTreeNode *right); +BPTreeNode *insert_into_parent(BPTreeNode *root, BPTreeNode *left, BPTreeKey_t key, BPTreeNode *right); -BPTreeNode *insert_into_new_root(BPTreeNode *left, int key, BPTreeNode *right); +BPTreeNode *insert_into_new_root(BPTreeNode *left, BPTreeKey_t key, BPTreeNode *right); -BPTreeNode *start_new_tree(int key, BPTreeRecord *pointer); +BPTreeNode *start_new_tree(BPTreeKey_t key, BPTreeRecord *pointer); // Deletion. -int get_neighbor_index(BPTreeNode *n); +BPTreeKey_t get_neighbor_index(BPTreeNode *n); BPTreeNode *adjust_root(BPTreeNode *root); -BPTreeNode *coalesce_nodes(BPTreeNode *root, BPTreeNode *n, BPTreeNode *neighbor, int neighbor_index, int k_prime); +BPTreeNode *coalesce_nodes(BPTreeNode *root, BPTreeNode *n, BPTreeNode *neighbor, BPTreeKey_t neighbor_index, BPTreeKey_t k_prime); -BPTreeNode *redistribute_nodes(BPTreeNode *root, BPTreeNode *n, BPTreeNode *neighbor, int neighbor_index, - int k_prime_index, int k_prime); +BPTreeNode *redistribute_nodes(BPTreeNode *root, BPTreeNode *n, BPTreeNode *neighbor, BPTreeKey_t neighbor_index, + BPTreeKey_t k_prime_index, BPTreeKey_t k_prime); -BPTreeNode *delete_entry(BPTreeNode *root, BPTreeNode *n, int key, void *pointer); +BPTreeNode *delete_entry(BPTreeNode *root, BPTreeNode *n, BPTreeKey_t key, void *pointer); // FUNCTION DEFINITIONS. @@ -173,8 +172,8 @@ int BPTree_height(BPTreeNode *root) { /* Utility function to give the length in edges * of the path from any node to the root. */ -int path_to_root(BPTreeNode *root, BPTreeNode *child) { - int length = 0; +BPTreeKey_t path_to_root(BPTreeNode *root, BPTreeNode *child) { + BPTreeKey_t length = 0; BPTreeNode *c = child; while (c != root) { c = c->parent; @@ -189,9 +188,9 @@ int path_to_root(BPTreeNode *root, BPTreeNode *child) { */ void BPTree_print(BPTreeNode *root) { BPTreeNode *n = NULL; - int i = 0; - int rank = 0; - int new_rank = 0; + BPTreeKey_t i = 0; + BPTreeKey_t rank = 0; + BPTreeKey_t new_rank = 0; if (root == NULL) { printf("Empty tree.\n"); @@ -209,7 +208,7 @@ void BPTree_print(BPTreeNode *root) { } } for (i = 0; i < n->num_keys; i++) { - printf("%d ", n->keys[i]); + printf("%ld ", n->keys[i]); } if (!n->is_leaf) for (i = 0; i <= n->num_keys; i++) @@ -224,8 +223,8 @@ void BPTree_print(BPTreeNode *root) { * returned_keys and returned_pointers, and returns the number of * entries found. */ -int find_range(BPTreeNode *root, int key_start, int key_end, int returned_keys[], void *returned_pointers[]) { - int i, num_found; +BPTreeKey_t find_range(BPTreeNode *root, BPTreeKey_t key_start, BPTreeKey_t key_end, BPTreeKey_t *returned_keys, void **returned_pointers) { + BPTreeKey_t i, num_found; num_found = 0; BPTreeNode *n = find_leaf(root, key_start); if (n == NULL) return 0; @@ -246,7 +245,7 @@ int find_range(BPTreeNode *root, int key_start, int key_end, int returned_keys[] /* Traces the path from the root to a leaf, searching by key. Returns the leaf containing the given key. */ -BPTreeNode *find_leaf(BPTreeNode *root, int key) { +BPTreeNode *find_leaf(BPTreeNode *root, BPTreeKey_t key) { int i = 0; BPTreeNode *c = root; if (c == NULL) { @@ -266,7 +265,7 @@ BPTreeNode *find_leaf(BPTreeNode *root, int key) { /* Finds and returns the BPTreeRecord to which a key refers. */ -BPTreeRecord *find(BPTreeNode *root, int key) { +BPTreeRecord *find(BPTreeNode *root, BPTreeKey_t key) { int i = 0; BPTreeNode *c = find_leaf(root, key); if (c == NULL) return NULL; @@ -280,7 +279,7 @@ BPTreeRecord *find(BPTreeNode *root, int key) { /* Finds the appropriate place to split a node that is too big into two. */ -int cut(int length) { +BPTreeKey_t cut(BPTreeKey_t length) { if (length % 2 == 0) return length / 2; else @@ -314,7 +313,7 @@ BPTreeNode *make_node(void) { perror("Node creation."); exit(EXIT_FAILURE); } - new_node->keys = calloc((size_t) (order - 1), sizeof(int)); + new_node->keys = calloc((size_t) (order - 1), sizeof(BPTreeKey_t)); if (new_node->keys == NULL) { perror("New node keys array."); exit(EXIT_FAILURE); @@ -345,9 +344,9 @@ BPTreeNode *make_leaf(void) { * to find the index of the parent's pointer to * the node to the left of the key to be inserted. */ -int get_left_index(BPTreeNode *parent, BPTreeNode *left) { +BPTreeKey_t get_left_index(BPTreeNode *parent, BPTreeNode *left) { - int left_index = 0; + BPTreeKey_t left_index = 0; while (left_index <= parent->num_keys && parent->pointers[left_index] != left) left_index++; @@ -358,7 +357,7 @@ int get_left_index(BPTreeNode *parent, BPTreeNode *left) { * key into a leaf. * Returns the altered leaf. */ -BPTreeNode *insert_into_leaf(BPTreeNode *leaf, int key, BPTreeRecord *pointer) { +BPTreeNode *insert_into_leaf(BPTreeNode *leaf, BPTreeKey_t key, BPTreeRecord *pointer) { int i, insertion_point; @@ -382,16 +381,16 @@ BPTreeNode *insert_into_leaf(BPTreeNode *leaf, int key, BPTreeRecord *pointer) { * the tree's order, causing the leaf to be split * in half. */ -BPTreeNode *insert_into_leaf_after_splitting(BPTreeNode *root, BPTreeNode *leaf, int key, BPTreeRecord *pointer) { +BPTreeNode *insert_into_leaf_after_splitting(BPTreeNode *root, BPTreeNode *leaf, BPTreeKey_t key, BPTreeRecord *pointer) { BPTreeNode *new_leaf; - int *temp_keys; + BPTreeKey_t *temp_keys; void **temp_pointers; int insertion_index, split, new_key, i, j; new_leaf = make_leaf(); - temp_keys = calloc((size_t) order, sizeof(int)); + temp_keys = calloc((size_t) order, sizeof(BPTreeKey_t)); if (temp_keys == NULL) { perror("Temporary keys array."); exit(EXIT_FAILURE); @@ -455,8 +454,8 @@ BPTreeNode *insert_into_leaf_after_splitting(BPTreeNode *root, BPTreeNode *leaf, * without violating the B+ tree properties. */ BPTreeNode *insert_into_node(BPTreeNode *root, BPTreeNode *n, - int left_index, int key, BPTreeNode *right) { - int i; + BPTreeKey_t left_index, BPTreeKey_t key, BPTreeNode *right) { + BPTreeKey_t i; for (i = n->num_keys; i > left_index; i--) { n->pointers[i + 1] = n->pointers[i]; @@ -473,12 +472,12 @@ BPTreeNode *insert_into_node(BPTreeNode *root, BPTreeNode *n, * into a node, causing the node's size to exceed * the order, and causing the node to split into two. */ -BPTreeNode *insert_into_node_after_splitting(BPTreeNode *root, BPTreeNode *old_node, int left_index, - int key, BPTreeNode *right) { +BPTreeNode *insert_into_node_after_splitting(BPTreeNode *root, BPTreeNode *old_node, BPTreeKey_t left_index, + BPTreeKey_t key, BPTreeNode *right) { - int i, j, split, k_prime; + BPTreeKey_t i, j, split, k_prime; BPTreeNode *new_node, *child; - int *temp_keys; + BPTreeKey_t *temp_keys; BPTreeNode **temp_pointers; /* First create a temporary set of keys and pointers @@ -495,7 +494,7 @@ BPTreeNode *insert_into_node_after_splitting(BPTreeNode *root, BPTreeNode *old_n perror("Temporary pointers array for splitting nodes."); exit(EXIT_FAILURE); } - temp_keys = calloc((size_t) order, sizeof(int)); + temp_keys = calloc((size_t) order, sizeof(BPTreeKey_t)); if (temp_keys == NULL) { perror("Temporary keys array for splitting nodes."); exit(EXIT_FAILURE); @@ -554,7 +553,7 @@ BPTreeNode *insert_into_node_after_splitting(BPTreeNode *root, BPTreeNode *old_n /* Inserts a new node (leaf or internal node) into the B+ tree. * Returns the root of the tree after insertion. */ -BPTreeNode *insert_into_parent(BPTreeNode *root, BPTreeNode *left, int key, BPTreeNode *right) { +BPTreeNode *insert_into_parent(BPTreeNode *root, BPTreeNode *left, BPTreeKey_t key, BPTreeNode *right) { int left_index; BPTreeNode *parent; @@ -595,7 +594,7 @@ BPTreeNode *insert_into_parent(BPTreeNode *root, BPTreeNode *left, int key, BPTr * and inserts the appropriate key into * the new root. */ -BPTreeNode *insert_into_new_root(BPTreeNode *left, int key, BPTreeNode *right) { +BPTreeNode *insert_into_new_root(BPTreeNode *left, BPTreeKey_t key, BPTreeNode *right) { BPTreeNode *root = make_node(); root->keys[0] = key; @@ -612,7 +611,7 @@ BPTreeNode *insert_into_new_root(BPTreeNode *left, int key, BPTreeNode *right) { /* First insertion: * start a new tree. */ -BPTreeNode *start_new_tree(int key, BPTreeRecord *pointer) { +BPTreeNode *start_new_tree(BPTreeKey_t key, BPTreeRecord *pointer) { BPTreeNode *root = make_leaf(); root->keys[0] = key; @@ -630,7 +629,7 @@ BPTreeNode *start_new_tree(int key, BPTreeRecord *pointer) { * however necessary to maintain the B+ tree * properties. */ -BPTreeNode *BPTree_insert(BPTreeNode *root, int key, void *value) { +BPTreeNode *BPTree_insert(BPTreeNode *root, BPTreeKey_t key, void *value) { BPTreeRecord *pointer; BPTreeNode *leaf; @@ -686,9 +685,9 @@ BPTreeNode *BPTree_insert(BPTreeNode *root, int key, void *value) { * is the leftmost child), returns -1 to signify * this special case. */ -int get_neighbor_index(BPTreeNode *n) { +BPTreeKey_t get_neighbor_index(BPTreeNode *n) { - int i; + BPTreeKey_t i; /* Return the index of the key to the left * of the pointer in the parent pointing @@ -707,7 +706,7 @@ int get_neighbor_index(BPTreeNode *n) { } -BPTreeNode *remove_entry_from_node(BPTreeNode *n, int key, BPTreeNode *pointer) { +BPTreeNode *remove_entry_from_node(BPTreeNode *n, BPTreeKey_t key, BPTreeNode *pointer) { int i, num_pointers; @@ -788,9 +787,9 @@ BPTreeNode *adjust_root(BPTreeNode *root) { * can accept the additional entries * without exceeding the maximum. */ -BPTreeNode *coalesce_nodes(BPTreeNode *root, BPTreeNode *n, BPTreeNode *neighbor, int neighbor_index, int k_prime) { +BPTreeNode *coalesce_nodes(BPTreeNode *root, BPTreeNode *n, BPTreeNode *neighbor, BPTreeKey_t neighbor_index, BPTreeKey_t k_prime) { - int i, j, neighbor_insertion_index, n_end; + BPTreeKey_t i, j, neighbor_insertion_index, n_end; BPTreeNode *tmp; /* Swap neighbor with node if node is on the @@ -878,10 +877,10 @@ BPTreeNode *coalesce_nodes(BPTreeNode *root, BPTreeNode *n, BPTreeNode *neighbor * small node's entries without exceeding the * maximum */ -BPTreeNode *redistribute_nodes(BPTreeNode *root, BPTreeNode *n, BPTreeNode *neighbor, int neighbor_index, - int k_prime_index, int k_prime) { +BPTreeNode *redistribute_nodes(BPTreeNode *root, BPTreeNode *n, BPTreeNode *neighbor, BPTreeKey_t neighbor_index, + BPTreeKey_t k_prime_index, BPTreeKey_t k_prime) { - int i; + BPTreeKey_t i; BPTreeNode *tmp; /* Case: n has a neighbor to the left. @@ -955,7 +954,7 @@ BPTreeNode *redistribute_nodes(BPTreeNode *root, BPTreeNode *n, BPTreeNode *neig * from the leaf, and then makes all appropriate * changes to preserve the B+ tree properties. */ -BPTreeNode *delete_entry(BPTreeNode *root, BPTreeNode *n, int key, void *pointer) { +BPTreeNode *delete_entry(BPTreeNode *root, BPTreeNode *n, BPTreeKey_t key, void *pointer) { int min_keys; BPTreeNode *neighbor; @@ -1025,7 +1024,7 @@ BPTreeNode *delete_entry(BPTreeNode *root, BPTreeNode *n, int key, void *pointer /* Master deletion function. */ -BPTreeNode *BPTree_delete(BPTreeNode *root, int key) { +BPTreeNode *BPTree_delete(BPTreeNode *root, BPTreeKey_t key) { BPTreeNode *key_leaf; BPTreeRecord *key_record; @@ -1059,7 +1058,7 @@ BPTreeNode *BPTree_destroy(BPTreeNode *root) { return NULL; } -void *BPTree_get(BPTreeNode *root, int key) { +void *BPTree_get(BPTreeNode *root, BPTreeKey_t key) { BPTreeRecord *rec = find(root, key); if (rec == NULL) { return NULL; @@ -1068,15 +1067,18 @@ void *BPTree_get(BPTreeNode *root, int key) { } } -void BPTree_get_range(BPTreeNode *root, List *list, int key_start, int key_end) { - int i; - int array_size = key_end - key_start + 1; - int returned_keys[array_size]; - void *returned_pointers[array_size]; - int num_found = find_range(root, key_start, key_end, returned_keys, returned_pointers); - - for (i = 0; i < num_found; i++) { - List_push(list, ((BPTreeRecord *) returned_pointers[i])->value); +void BPTree_get_range(BPTreeNode *root, List *list, BPTreeKey_t key_start, BPTreeKey_t key_end) { + BPTreeKey_t i; + BPTreeNode *n = find_leaf(root, key_start); + if (n == NULL) return; + for (i = 0; i < n->num_keys && n->keys[i] < key_start; i++); + if (i == n->num_keys) return; + while (n != NULL) { + for (; i < n->num_keys && n->keys[i] <= key_end; i++) { + List_push(list, ((BPTreeRecord *) n->pointers[i])->value); + } + n = n->pointers[order - 1]; + i = 0; } } diff --git a/src/util/bptree.h b/src/util/bptree.h index edac7cf5..4152d8d3 100644 --- a/src/util/bptree.h +++ b/src/util/bptree.h @@ -43,6 +43,10 @@ #ifndef PRRT_BPTREE_H #define PRRT_BPTREE_H +#include + +typedef uint64_t BPTreeKey_t; + #include "../defines.h" #include "list.h" @@ -58,19 +62,19 @@ */ typedef struct BPTreeNode { void ** pointers; - int * keys; + BPTreeKey_t * keys; struct BPTreeNode * parent; bool is_leaf; - int num_keys; + BPTreeKey_t num_keys; struct BPTreeNode * next; // Used for queue. } BPTreeNode; // Operations -BPTreeNode *BPTree_insert(BPTreeNode *root, int key, void *value); -BPTreeNode *BPTree_delete(BPTreeNode *root, int key); +BPTreeNode *BPTree_insert(BPTreeNode *root, BPTreeKey_t key, void *value); +BPTreeNode *BPTree_delete(BPTreeNode *root, BPTreeKey_t key); BPTreeNode *BPTree_destroy(BPTreeNode *root); -void *BPTree_get(BPTreeNode *root, int key); -void BPTree_get_range(BPTreeNode *root, List *list, int key_start, int key_end); +void *BPTree_get(BPTreeNode *root, BPTreeKey_t key); +void BPTree_get_range(BPTreeNode *root, List *list, BPTreeKey_t key_start, BPTreeKey_t key_end); // Helpers void BPTree_print(BPTreeNode *root); -- GitLab