diff --git a/src/Directory.c b/src/Directory.c index 9bcc2049bfb403e0e743753283a7ad7de55402ce..a4b701348a1415cc2a2d25138d6ae972cd2b1d78 100644 --- a/src/Directory.c +++ b/src/Directory.c @@ -57,11 +57,11 @@ static void rebuild_index(Directory *directory) { if ((bool)is_deleted) { fseek(fp, DirectoryRecord_size_on_disk() - 1, SEEK_CUR); } else { - char phone_number[PHONE_NUMBER_MAX_LENGTH]; - phone_number[PHONE_NUMBER_MAX_LENGTH - 1] = '\0'; - fread(phone_number, 1, PHONE_NUMBER_MAX_LENGTH_WITHOUT_NULL_CHARACTER, fp); + char phone_number[PHONE_NUMBER_MAXLEN]; + phone_number[PHONE_NUMBER_MAXLEN - 1] = '\0'; + fread(phone_number, 1, PHONE_NUMBER_MAXLEN_WITHOUT_NULL_CHARACTER, fp); BPTree_insert(directory->index, hash_string(phone_number), data_ptr); - fseek(fp, DirectoryRecord_size_on_disk() - 1 - PHONE_NUMBER_MAX_LENGTH_WITHOUT_NULL_CHARACTER, SEEK_CUR); + fseek(fp, DirectoryRecord_size_on_disk() - 1 - PHONE_NUMBER_MAXLEN_WITHOUT_NULL_CHARACTER, SEEK_CUR); } if (ftell(fp) == file_size) { @@ -72,7 +72,7 @@ static void rebuild_index(Directory *directory) { fclose(fp); } -Directory *Directory_init(char database_filename[FILENAME_MAX_LENGTH]) { +Directory *Directory_init(char database_filename[FILENAME_MAXLEN]) { Directory *directory = (Directory *)malloc(sizeof(Directory)); strcpy(directory->database_filename, database_filename); directory->index = BPTree_init(DEFAULT_ORDER); @@ -152,7 +152,7 @@ bool Directory_append(Directory *directory, DirectoryRecord *record) { return true; } -DirectoryRecord *Directory_search(Directory *directory, char phone_number[11]) { +DirectoryRecord *Directory_search(Directory *directory, char phone_number[PHONE_NUMBER_MAXLEN]) { uint64_t data_ptr; if (BPTree_search(directory->index, hash_string(phone_number), &data_ptr)) { FILE *fp; @@ -176,7 +176,7 @@ DirectoryRecord *Directory_search(Directory *directory, char phone_number[11]) { return NULL; } -bool Directory_delete(Directory *directory, char phone_number[11]) { +bool Directory_delete(Directory *directory, char phone_number[PHONE_NUMBER_MAXLEN]) { uint64_t data_ptr; if (BPTree_search(directory->index, hash_string(phone_number), &data_ptr)) { FILE *fp; diff --git a/src/Directory.h b/src/Directory.h index 5b30b2514c2d23e3cb267244b8819262f8cddc70..e72efc63b102244f0a8dce7822cf5d56a4dd599c 100644 --- a/src/Directory.h +++ b/src/Directory.h @@ -1,22 +1,24 @@ #ifndef DIRECTORY_H #define DIRECTORY_H -#include "DirectoryRecord.h" +#include <stdbool.h> + #include "BPTree.h" +#include "DirectoryRecord.h" #define DEFAULT_ORDER 2 -#define FILENAME_MAX_LENGTH 100 +#define FILENAME_MAXLEN 100 typedef struct Directory { - char database_filename[FILENAME_MAX_LENGTH]; + char database_filename[FILENAME_MAXLEN]; BPTreeNode *index; } Directory; -Directory *Directory_init(char database_filename[FILENAME_MAX_LENGTH]); +Directory *Directory_init(char database_filename[FILENAME_MAXLEN]); void Directory_destroy(Directory **directory); void Directory_print(Directory *directory); bool Directory_append(Directory *directory, DirectoryRecord *record); -DirectoryRecord *Directory_search(Directory *directory, char phone_number[11]); -bool Directory_delete(Directory *directory, char phone_number[11]); +DirectoryRecord *Directory_search(Directory *directory, char phone_number[PHONE_NUMBER_MAXLEN]); +bool Directory_delete(Directory *directory, char phone_number[PHONE_NUMBER_MAXLEN]); #endif diff --git a/src/DirectoryRecord.c b/src/DirectoryRecord.c index bc3b558f7260e4e820b38c708cf7d5d29f0dd345..594b9b99f2301932b11700d2a9d589ee17067501 100644 --- a/src/DirectoryRecord.c +++ b/src/DirectoryRecord.c @@ -10,21 +10,21 @@ int DirectoryRecord_size_on_disk() { int size = 1; - size += PHONE_NUMBER_MAX_LENGTH_WITHOUT_NULL_CHARACTER; - size += NAME_MAX_LENGTH_WITHOUT_NULL_CHARACTER; - size += SURNAME_MAX_LENGTH_WITHOUT_NULL_CHARACTER; + size += PHONE_NUMBER_MAXLEN_WITHOUT_NULL_CHARACTER; + size += NAME_MAXLEN_WITHOUT_NULL_CHARACTER; + size += SURNAME_MAXLEN_WITHOUT_NULL_CHARACTER; size += BIRTH_DATE_SIZE_IN_BYTES; return size; } -DirectoryRecord *DirectoryRecord_init(bool is_deleted, char phone_number[PHONE_NUMBER_MAX_LENGTH], char name[NAME_MAX_LENGTH], char surname[SURNAME_MAX_LENGTH], int birth_date_year, int birth_date_month, int birth_date_day) { +DirectoryRecord *DirectoryRecord_init(bool is_deleted, char phone_number[PHONE_NUMBER_MAXLEN], char name[NAME_MAXLEN], char surname[SURNAME_MAXLEN], int birth_date_year, int birth_date_month, int birth_date_day) { DirectoryRecord *record = (DirectoryRecord *)malloc(sizeof(DirectoryRecord)); record->is_deleted = is_deleted; - memset(record->phone_number, 0, PHONE_NUMBER_MAX_LENGTH); + memset(record->phone_number, 0, PHONE_NUMBER_MAXLEN); strcpy(record->phone_number, phone_number); - memset(record->name, 0, NAME_MAX_LENGTH); + memset(record->name, 0, NAME_MAXLEN); strcpy(record->name, name); - memset(record->surname, 0, SURNAME_MAX_LENGTH); + memset(record->surname, 0, SURNAME_MAXLEN); strcpy(record->surname, surname); record->birth_date_year = birth_date_year; record->birth_date_month = birth_date_month; @@ -49,15 +49,15 @@ ByteArray *DirectoryRecord_to_ByteArray(DirectoryRecord *record) { ByteArray *array = ByteArray_init(capacity); ByteArray_append(array, (uint8_t)record->is_deleted); - for (int j = 0; j < PHONE_NUMBER_MAX_LENGTH_WITHOUT_NULL_CHARACTER; j++) { + for (int j = 0; j < PHONE_NUMBER_MAXLEN_WITHOUT_NULL_CHARACTER; j++) { ByteArray_append(array, (uint8_t)record->phone_number[j]); } - for (int j = 0; j < NAME_MAX_LENGTH_WITHOUT_NULL_CHARACTER; j++) { + for (int j = 0; j < NAME_MAXLEN_WITHOUT_NULL_CHARACTER; j++) { ByteArray_append(array, (uint8_t)record->name[j]); } - for (int j = 0; j < SURNAME_MAX_LENGTH_WITHOUT_NULL_CHARACTER; j++) { + for (int j = 0; j < SURNAME_MAXLEN_WITHOUT_NULL_CHARACTER; j++) { ByteArray_append(array, (uint8_t)record->surname[j]); } @@ -77,26 +77,26 @@ DirectoryRecord *ByteArray_to_DirectoryRecord(ByteArray *byte_array) { bool is_deleted = (bool)byte_array->items[i]; i++; - char phone_number[PHONE_NUMBER_MAX_LENGTH]; - phone_number[PHONE_NUMBER_MAX_LENGTH - 1] = '\0'; + char phone_number[PHONE_NUMBER_MAXLEN]; + phone_number[PHONE_NUMBER_MAXLEN - 1] = '\0'; - for (int j = 0; j < PHONE_NUMBER_MAX_LENGTH_WITHOUT_NULL_CHARACTER; j++) { + for (int j = 0; j < PHONE_NUMBER_MAXLEN_WITHOUT_NULL_CHARACTER; j++) { phone_number[j] = (char)byte_array->items[i]; i++; } - char name[NAME_MAX_LENGTH]; - name[NAME_MAX_LENGTH - 1] = '\0'; + char name[NAME_MAXLEN]; + name[NAME_MAXLEN - 1] = '\0'; - for (int j = 0; j < NAME_MAX_LENGTH_WITHOUT_NULL_CHARACTER; j++) { + for (int j = 0; j < NAME_MAXLEN_WITHOUT_NULL_CHARACTER; j++) { name[j] = (char)byte_array->items[i]; i++; } - char surname[SURNAME_MAX_LENGTH]; - surname[SURNAME_MAX_LENGTH - 1] = '\0'; + char surname[SURNAME_MAXLEN]; + surname[SURNAME_MAXLEN - 1] = '\0'; - for (int j = 0; j < SURNAME_MAX_LENGTH_WITHOUT_NULL_CHARACTER; j++) { + for (int j = 0; j < SURNAME_MAXLEN_WITHOUT_NULL_CHARACTER; j++) { surname[j] = (char)byte_array->items[i]; i++; } diff --git a/src/DirectoryRecord.h b/src/DirectoryRecord.h index 9f148ab77c21d5921da9055be41a0b64507e8f84..4909e36252bfb764bde91a787acafea740c4f533 100644 --- a/src/DirectoryRecord.h +++ b/src/DirectoryRecord.h @@ -2,26 +2,25 @@ #define DIRECTORY_RECORD_H #include <stdbool.h> -#include <stdint.h> #include "Array.h" -#define PHONE_NUMBER_MAX_LENGTH_WITHOUT_NULL_CHARACTER 10 -#define PHONE_NUMBER_MAX_LENGTH 1 + PHONE_NUMBER_MAX_LENGTH_WITHOUT_NULL_CHARACTER +#define PHONE_NUMBER_MAXLEN_WITHOUT_NULL_CHARACTER 10 +#define PHONE_NUMBER_MAXLEN 1 + PHONE_NUMBER_MAXLEN_WITHOUT_NULL_CHARACTER -#define NAME_MAX_LENGTH_WITHOUT_NULL_CHARACTER 20 -#define NAME_MAX_LENGTH 1 + NAME_MAX_LENGTH_WITHOUT_NULL_CHARACTER +#define NAME_MAXLEN_WITHOUT_NULL_CHARACTER 20 +#define NAME_MAXLEN 1 + NAME_MAXLEN_WITHOUT_NULL_CHARACTER -#define SURNAME_MAX_LENGTH_WITHOUT_NULL_CHARACTER 20 -#define SURNAME_MAX_LENGTH 1 + SURNAME_MAX_LENGTH_WITHOUT_NULL_CHARACTER +#define SURNAME_MAXLEN_WITHOUT_NULL_CHARACTER 20 +#define SURNAME_MAXLEN 1 + SURNAME_MAXLEN_WITHOUT_NULL_CHARACTER #define BIRTH_DATE_SIZE_IN_BYTES 4 typedef struct DirectoryRecord { bool is_deleted; - char phone_number[PHONE_NUMBER_MAX_LENGTH]; - char name[NAME_MAX_LENGTH]; - char surname[SURNAME_MAX_LENGTH]; + char phone_number[PHONE_NUMBER_MAXLEN]; + char name[NAME_MAXLEN]; + char surname[SURNAME_MAXLEN]; int birth_date_year; int birth_date_month; int birth_date_day; @@ -29,11 +28,11 @@ typedef struct DirectoryRecord { int DirectoryRecord_size_on_disk(); -DirectoryRecord *DirectoryRecord_init(bool is_deleted, char phone_number[PHONE_NUMBER_MAX_LENGTH], char name[NAME_MAX_LENGTH], char surname[SURNAME_MAX_LENGTH], int birth_date_year, int birth_date_month, int birth_date_day); +DirectoryRecord *DirectoryRecord_init(bool is_deleted, char phone_number[PHONE_NUMBER_MAXLEN], char name[NAME_MAXLEN], char surname[SURNAME_MAXLEN], int birth_date_year, int birth_date_month, int birth_date_day); void DirectoryRecord_destroy(DirectoryRecord **record); void DirectoryRecord_print(DirectoryRecord *record); ByteArray *DirectoryRecord_to_ByteArray(DirectoryRecord *record); -DirectoryRecord *ByteArray_to_DirectoryRecord(ByteArray* byte_array); +DirectoryRecord *ByteArray_to_DirectoryRecord(ByteArray *byte_array); #endif diff --git a/src/Makefile b/src/Makefile index 04628dbb0588d1ca47ee98d85768c998da8490e6..15bfd4dfc47e979a1c818d1009ba31acde28ee57 100644 --- a/src/Makefile +++ b/src/Makefile @@ -20,7 +20,7 @@ HEADERS = $(wildcard *.h) $(TARGET): $(OBJECTS) $(CC) $(OBJECTS) $(CFLAGS) $(LIBS) -o $@ -# TESTS_BEGIN +# BEGIN : Tests Unity.o: tests/Unity/unity.c tests/Unity/unity.h $(CC) $(CFLAGS) -c $< -o $@ @@ -34,7 +34,7 @@ make_run_tests: Unity.o BPTreeTests.o Array.o BPTree.o run_tests: make_run_tests clean -# TESTS_END +# END : Tests clean: rm -f *.o ${TARGET}* tests_exec diff --git a/src/main.c b/src/main.c index 817db1ef3cdbb7045e9fa3d23d4c71098dd2d689..3d06a977a6157fa1876e319bbd047339f7b1133c 100644 --- a/src/main.c +++ b/src/main.c @@ -1,4 +1,3 @@ -// TODO : replace 11 with pseudo variable #include <stdio.h> #include <stdlib.h> @@ -12,24 +11,23 @@ void clear_buffer() { } void append_record(Directory *directory) { - char phone_number[11]; + char phone_number[PHONE_NUMBER_MAXLEN]; printf("Enter the phone number: "); scanf("%10s", phone_number); clear_buffer(); - char name[21]; + char name[NAME_MAXLEN]; printf("Enter the name: "); scanf("%20s", name); clear_buffer(); - char surname[21]; + char surname[SURNAME_MAXLEN]; printf("Enter the surname: "); scanf("%20s", surname); clear_buffer(); int birth_date_year, birth_date_month, birth_date_day; - do - { + do { printf("Enter the birth date (Y-m-d): "); } while (scanf("%d-%d-%d", &birth_date_year, &birth_date_month, &birth_date_day) != 3); @@ -58,7 +56,7 @@ void append_record(Directory *directory) { void search_record(Directory *directory) { printf("Enter the phone number that corresponds to the record you are looking for: "); - char phone_number[11]; + char phone_number[PHONE_NUMBER_MAXLEN]; scanf("%10s", phone_number); clear_buffer(); DirectoryRecord *record = Directory_search(directory, phone_number); @@ -77,7 +75,7 @@ void search_record(Directory *directory) { void delete_record(Directory *directory) { printf("Enter the phone number that corresponds to the record you wish to delete: "); - char phone_number[11]; + char phone_number[PHONE_NUMBER_MAXLEN]; scanf("%10s", phone_number); clear_buffer(); DirectoryRecord *record = Directory_search(directory, phone_number); diff --git a/src/tests/BPTreeTests.c b/src/tests/BPTreeTests.c index 54ba8e30fa6342217f8da7dff7935577fc640ab3..6c04c650a87caa6eb3b9721945c37be5edea2fe9 100644 --- a/src/tests/BPTreeTests.c +++ b/src/tests/BPTreeTests.c @@ -23,6 +23,42 @@ void tearDown(void) { // BEGIN : Compliance with B+ Tree rules +static BPTreeNode *find_first_leaf(BPTreeNode *root) { + if (root->is_leaf) { + return root; + } + + return find_first_leaf(root->children->items[0]); +} + +static bool check_if_the_leaf_nodes_are_correctly_chained(BPTreeNode *root) { + BPTreeNode *current = find_first_leaf(root); + + while (current->next != NULL) { + if (current->keys->items[current->keys->size - 1] >= current->next->keys->items[0]) { + return false; + } + + current = current->next; + } + + return true; +} + +static bool check_if_all_leaf_nodes_have_as_many_keys_as_data(BPTreeNode *root) { + if (root->is_leaf) { + return root->keys->size == root->data->size; + } + + for (int i = 0; i < root->children->size; i++) { + if (!check_if_all_leaf_nodes_have_as_many_keys_as_data(root->children->items[i])) { + return false; + } + } + + return true; +} + static int compute_first_leaf_depth(BPTreeNode *root) { if (root->is_leaf) { return 0; @@ -31,13 +67,13 @@ static int compute_first_leaf_depth(BPTreeNode *root) { return compute_first_leaf_depth(root->children->items[0]) + 1; } -static bool check_if_the_leaves_are_all_at_the_same_depth(BPTreeNode *root, int expected_depth, int depth) { +static bool check_if_all_leaf_nodes_are_at_the_same_depth(BPTreeNode *root, int expected_depth, int depth) { if (root->is_leaf) { return depth == expected_depth; } for (int i = 0; i < root->children->size; i++) { - if (!check_if_the_leaves_are_all_at_the_same_depth(root->children->items[i], expected_depth, depth + 1)) { + if (!check_if_all_leaf_nodes_are_at_the_same_depth(root->children->items[i], expected_depth, depth + 1)) { return false; } } @@ -59,18 +95,18 @@ static bool check_if_all_internal_nodes_have_no_data(BPTreeNode *root) { return root->data->size == 0; } -static bool check_if_all_leaf_nodes_have_as_much_data_as_keys(BPTreeNode *root) { +static bool check_if_all_internal_nodes_have_always_1_child_more_than_the_number_of_keys(BPTreeNode *root) { if (root->is_leaf) { - return root->keys->size == root->data->size; + return true; } for (int i = 0; i < root->children->size; i++) { - if (!check_if_all_leaf_nodes_have_as_much_data_as_keys(root->children->items[i])) { + if (!check_if_all_internal_nodes_have_always_1_child_more_than_the_number_of_keys(root->children->items[i])) { return false; } } - return true; + return root->children->size == root->keys->size + 1; } static bool check_if_the_array_is_sorted(IntegerArray *array) { @@ -83,9 +119,9 @@ static bool check_if_the_array_is_sorted(IntegerArray *array) { return true; } -static bool check_if_the_keys_are_sorted_in_all_nodes(BPTreeNode *root) { +static bool check_if_all_nodes_have_their_keys_sorted(BPTreeNode *root) { for (int i = 0; i < root->children->size; i++) { - if (!check_if_the_keys_are_sorted_in_all_nodes(root->children->items[i])) { + if (!check_if_all_nodes_have_their_keys_sorted(root->children->items[i])) { return false; } } @@ -93,45 +129,31 @@ static bool check_if_the_keys_are_sorted_in_all_nodes(BPTreeNode *root) { return check_if_the_array_is_sorted(root->keys); } -static bool check_if_all_nodes_except_the_root_have_not_less_keys_than_the_minimum(BPTreeNode *root, BPTreeNode *parent) { +static bool check_if_all_nodes_have_no_more_keys_than_the_maximum_allowed(BPTreeNode *root) { for (int i = 0; i < root->children->size; i++) { - if (!check_if_all_nodes_except_the_root_have_not_less_keys_than_the_minimum(root->children->items[i], root)) { + if (!check_if_all_nodes_have_no_more_keys_than_the_maximum_allowed(root->children->items[i])) { return false; } } - if (parent == NULL) { - return true; - } - - return root->keys->size >= root->order; + return root->keys->size <= 2 * root->order; } -static bool check_if_all_nodes_have_no_more_keys_than_the_maximum(BPTreeNode *root) { +static bool check_if_all_nodes_except_the_root_node_have_not_less_keys_than_the_minimum_required(BPTreeNode *root, BPTreeNode *parent) { for (int i = 0; i < root->children->size; i++) { - if (!check_if_all_nodes_have_no_more_keys_than_the_maximum(root->children->items[i])) { + if (!check_if_all_nodes_except_the_root_node_have_not_less_keys_than_the_minimum_required(root->children->items[i], root)) { return false; } } - return root->keys->size <= 2 * root->order; -} - -static bool check_in_all_internal_nodes_there_is_1_child_more_than_the_number_of_keys(BPTreeNode *root) { - if (root->is_leaf) { + if (parent == NULL) { return true; } - for (int i = 0; i < root->children->size; i++) { - if (!check_in_all_internal_nodes_there_is_1_child_more_than_the_number_of_keys(root->children->items[i])) { - return false; - } - } - - return root->children->size == root->keys->size + 1; + return root->keys->size >= root->order; } -static bool check_if_the_keys_are_inserted_in_the_right_place_with_range(BPTreeNode *root, uint64_t left, uint64_t right) { +static bool check_if_the_keys_have_been_correctly_inserted_within_range(BPTreeNode *root, uint64_t left, uint64_t right) { for (int i = 0; i < root->keys->size; i++) { if (root->keys->items[i] < left || root->keys->items[i] >= right) { return false; @@ -139,7 +161,7 @@ static bool check_if_the_keys_are_inserted_in_the_right_place_with_range(BPTreeN } for (int i = 0; i < root->children->size; i++) { - if (!check_if_the_keys_are_inserted_in_the_right_place_with_range(root->children->items[i], left, right)) { + if (!check_if_the_keys_have_been_correctly_inserted_within_range(root->children->items[i], left, right)) { return false; } } @@ -147,29 +169,29 @@ static bool check_if_the_keys_are_inserted_in_the_right_place_with_range(BPTreeN return true; } -static bool check_if_the_keys_are_inserted_in_the_right_place(BPTreeNode *root) { +static bool check_if_the_keys_have_been_correctly_inserted(BPTreeNode *root) { if (root->is_leaf) { return true; } for (int i = 0; i < root->children->size; i++) { if (i == 0) { - if (!check_if_the_keys_are_inserted_in_the_right_place_with_range(root->children->items[i], 0, root->keys->items[i])) { + if (!check_if_the_keys_have_been_correctly_inserted_within_range(root->children->items[i], 0, root->keys->items[i])) { return false; } } else if (i == root->children->size - 1) { - if (!check_if_the_keys_are_inserted_in_the_right_place_with_range(root->children->items[i], root->keys->items[i - 1], 18446744073709551615LLU)) { + if (!check_if_the_keys_have_been_correctly_inserted_within_range(root->children->items[i], root->keys->items[i - 1], 18446744073709551615LLU)) { return false; } } else { - if (!check_if_the_keys_are_inserted_in_the_right_place_with_range(root->children->items[i], root->keys->items[i - 1], root->keys->items[i])) { + if (!check_if_the_keys_have_been_correctly_inserted_within_range(root->children->items[i], root->keys->items[i - 1], root->keys->items[i])) { return false; } } } for (int i = 0; i < root->children->size; i++) { - if (!check_if_the_keys_are_inserted_in_the_right_place(root->children->items[i])) { + if (!check_if_the_keys_have_been_correctly_inserted(root->children->items[i])) { return false; } } @@ -179,15 +201,20 @@ static bool check_if_the_keys_are_inserted_in_the_right_place(BPTreeNode *root) static bool check_BPTree_compliance(BPTreeNode *root) { bool is_compliant = true; - is_compliant &= check_if_the_leaves_are_all_at_the_same_depth(root, compute_first_leaf_depth(root), 0); + + is_compliant &= check_if_the_leaf_nodes_are_correctly_chained(root); + is_compliant &= check_if_all_leaf_nodes_have_as_many_keys_as_data(root); + is_compliant &= check_if_all_leaf_nodes_are_at_the_same_depth(root, compute_first_leaf_depth(root), 0); + is_compliant &= check_if_all_internal_nodes_have_no_data(root); - is_compliant &= check_if_all_leaf_nodes_have_as_much_data_as_keys(root); - is_compliant &= check_if_the_keys_are_sorted_in_all_nodes(root); - is_compliant &= check_if_all_nodes_except_the_root_have_not_less_keys_than_the_minimum(root, NULL); - is_compliant &= check_if_all_nodes_have_no_more_keys_than_the_maximum(root); - is_compliant &= check_in_all_internal_nodes_there_is_1_child_more_than_the_number_of_keys(root); - is_compliant &= check_if_the_keys_are_inserted_in_the_right_place(root); - // TODO : check if linked list is ok + is_compliant &= check_if_all_internal_nodes_have_always_1_child_more_than_the_number_of_keys(root); + + is_compliant &= check_if_all_nodes_have_their_keys_sorted(root); + is_compliant &= check_if_all_nodes_have_no_more_keys_than_the_maximum_allowed(root); + is_compliant &= check_if_all_nodes_except_the_root_node_have_not_less_keys_than_the_minimum_required(root, NULL); + + is_compliant &= check_if_the_keys_have_been_correctly_inserted(root); + return is_compliant; } @@ -325,7 +352,7 @@ void test_BPTree_delete_should_comply_with_BPTree_rules_using_BPTree_of_given_or } IntegerArray_destroy(&keys); - BPTree_destroy(&(*root)); + BPTree_destroy(root); size *= 2; } @@ -360,6 +387,61 @@ void test_BPTree_delete_should_comply_with_BPTree_rules_using_BPTree_of_order_16 // **** END : test_BPTree_delete +// **** BEGIN : test_BPTree_search + +void test_BPTree_search_should_find_the_keys_that_exist_in_the_BPTree_using_BPTree_of_given_order(BPTreeNode **root, int order) { + int size = 256; + + // Test 10 times, variable i being the seed. + for (int i = 0; i < 1; i++) { + srand(i); + + IntegerArray *keys = generate_random_numbers_array(size, RANDOM_MIN, RANDOM_MAX); + *root = BPTree_init(order); + + for (int i = 0; i < keys->size; i++) { + BPTree_insert(*root, keys->items[i], transform_key_to_data(keys->items[i])); + } + + for (int i = 0; i < keys->size; i++) { + uint64_t data; + bool is_found = BPTree_search(*root, keys->items[i], &data); + + TEST_ASSERT(is_found); + TEST_ASSERT_EQUAL_UINT64(transform_key_to_data(keys->items[i]), data); + } + + IntegerArray_destroy(&keys); + BPTree_destroy(root); + } +} + +void test_BPTree_search_should_find_the_keys_that_exist_in_the_BPTree_using_BPTree_of_order_1() { + test_BPTree_search_should_find_the_keys_that_exist_in_the_BPTree_using_BPTree_of_given_order(&tree, 1); +} + +void test_BPTree_search_should_find_the_keys_that_exist_in_the_BPTree_using_BPTree_of_order_2() { + test_BPTree_search_should_find_the_keys_that_exist_in_the_BPTree_using_BPTree_of_given_order(&tree, 2); +} + +void test_BPTree_search_should_find_the_keys_that_exist_in_the_BPTree_using_BPTree_of_order_3() { + test_BPTree_search_should_find_the_keys_that_exist_in_the_BPTree_using_BPTree_of_given_order(&tree, 3); +} + +void test_BPTree_search_should_find_the_keys_that_exist_in_the_BPTree_using_BPTree_of_order_4() { + test_BPTree_search_should_find_the_keys_that_exist_in_the_BPTree_using_BPTree_of_given_order(&tree, 4); +} + +void test_BPTree_search_should_find_the_keys_that_exist_in_the_BPTree_using_BPTree_of_order_8() { + test_BPTree_search_should_find_the_keys_that_exist_in_the_BPTree_using_BPTree_of_given_order(&tree, 8); +} + +void test_BPTree_search_should_find_the_keys_that_exist_in_the_BPTree_using_BPTree_of_order_16() { + test_BPTree_search_should_find_the_keys_that_exist_in_the_BPTree_using_BPTree_of_given_order(&tree, 16); +} + +// **** END : test_BPTree_search + // END : Tests int main(void) { @@ -379,5 +461,12 @@ int main(void) { RUN_TEST(test_BPTree_delete_should_comply_with_BPTree_rules_using_BPTree_of_order_8); RUN_TEST(test_BPTree_delete_should_comply_with_BPTree_rules_using_BPTree_of_order_16); + RUN_TEST(test_BPTree_search_should_find_the_keys_that_exist_in_the_BPTree_using_BPTree_of_order_1); + RUN_TEST(test_BPTree_search_should_find_the_keys_that_exist_in_the_BPTree_using_BPTree_of_order_2); + RUN_TEST(test_BPTree_search_should_find_the_keys_that_exist_in_the_BPTree_using_BPTree_of_order_3); + RUN_TEST(test_BPTree_search_should_find_the_keys_that_exist_in_the_BPTree_using_BPTree_of_order_4); + RUN_TEST(test_BPTree_search_should_find_the_keys_that_exist_in_the_BPTree_using_BPTree_of_order_8); + RUN_TEST(test_BPTree_search_should_find_the_keys_that_exist_in_the_BPTree_using_BPTree_of_order_16); + return UNITY_END(); }