#include "toy_table.h" #include "toy_console_colors.h" #include int test_table_allocation() { //allocate and free a table { //setup Toy_Table* table = Toy_allocateTable(); //check if (table == NULL) { fprintf(stderr, TOY_CC_ERROR "ERROR: Failed to allocate a table\n" TOY_CC_RESET); Toy_freeTable(table); return -1; } //free Toy_freeTable(table); } return 0; } int test_table_simple_insert_lookup_and_remove() { //simple insert { //setup Toy_Table* table = Toy_allocateTable(); Toy_Value key = TOY_VALUE_TO_INTEGER(1); Toy_Value value = TOY_VALUE_TO_INTEGER(42); //insert Toy_insertTable(&table, key, value); if (table == NULL || table->capacity != 16 || table->count != 1) { fprintf(stderr, TOY_CC_ERROR "ERROR: Failed to insert into a table\n" TOY_CC_RESET); Toy_freeTable(table); return -1; } //lookup Toy_Value result = Toy_lookupTable(&table, TOY_VALUE_TO_INTEGER(1)); //check lookup if (table == NULL || table->capacity != 16 || table->count != 1 || TOY_VALUE_AS_INTEGER(result) != 42) { fprintf(stderr, TOY_CC_ERROR "ERROR: Failed to lookup from a table\n" TOY_CC_RESET); Toy_freeTable(table); return -1; } //remove Toy_removeTable(&table, TOY_VALUE_TO_INTEGER(1)); //check remove if (table == NULL || table->capacity != 16 || table->count != 0) { fprintf(stderr, TOY_CC_ERROR "ERROR: Failed to remove from a table\n" TOY_CC_RESET); Toy_freeTable(table); return -1; } //free Toy_freeTable(table); } return 0; } //macros are a godsend #define TEST_ENTRY_STATE(i, k, v, p) \ TOY_VALUE_IS_INTEGER(table->data[i].key) != true || \ TOY_VALUE_AS_INTEGER(table->data[i].key) != k || \ TOY_VALUE_IS_INTEGER(table->data[i].value) != true || \ TOY_VALUE_AS_INTEGER(table->data[i].value) != v || \ table->data[i].psl != p int test_table_contents_no_expansion() { //single insert { //setup Toy_Table* table = Toy_allocateTable(); //insert a key and value Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(1), TOY_VALUE_TO_INTEGER(42)); //check the state if (table == NULL || table->capacity != 16 || table->count != 1 || TEST_ENTRY_STATE(7, 1, 42, 0) ) { fprintf(stderr, TOY_CC_ERROR "ERROR: Unrecognized state from table data, single insert {1:42}\n" TOY_CC_RESET); Toy_freeTable(table); return -1; } //free Toy_freeTable(table); } //multiple inserts, no collisions { //setup Toy_Table* table = Toy_allocateTable(); //inserts Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(1), TOY_VALUE_TO_INTEGER(42)); //hash: 7 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(2), TOY_VALUE_TO_INTEGER(69)); //hash: 8 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(3), TOY_VALUE_TO_INTEGER(420)); //hash: 5 //check the state if (table == NULL || table->capacity != 16 || table->count != 3 || TEST_ENTRY_STATE(7, 1, 42, 0) || TEST_ENTRY_STATE(8, 2, 69, 0) || TEST_ENTRY_STATE(5, 3, 420, 0) ) { fprintf(stderr, TOY_CC_ERROR "ERROR: Unrecognized state from table data, multiple inserts, no collisions {1:42},{2:69},{3:420}\n" TOY_CC_RESET); Toy_freeTable(table); return -1; } //free Toy_freeTable(table); } //multiple inserts, with collisions { //setup Toy_Table* table = Toy_allocateTable(); //inserts Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(1), TOY_VALUE_TO_INTEGER(42)); //hash: 7 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(14), TOY_VALUE_TO_INTEGER(69)); //hash: 7 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(76), TOY_VALUE_TO_INTEGER(420)); //hash: 7 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(80), TOY_VALUE_TO_INTEGER(8891)); //hash: 7 //check the state if (table == NULL || table->capacity != 16 || table->count != 4 || TEST_ENTRY_STATE(7, 1, 42, 0) || TEST_ENTRY_STATE(8, 14, 69, 1) || TEST_ENTRY_STATE(9, 76, 420, 2) || TEST_ENTRY_STATE(10, 80, 8891, 3) ) { fprintf(stderr, TOY_CC_ERROR "ERROR: Unrecognized state from table data, muiltiple inserts, with collisions {1:42},{14:69},{76:420},{80:8891}\n" TOY_CC_RESET); Toy_freeTable(table); return -1; } //free Toy_freeTable(table); } //multiple inserts, with collisions, modulo wrap { //setup Toy_Table* table = Toy_allocateTable(); //inserts Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(17), TOY_VALUE_TO_INTEGER(42)); //hash: 15 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(33), TOY_VALUE_TO_INTEGER(69)); //hash: 15 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(70), TOY_VALUE_TO_INTEGER(420)); //hash: 15 //check the state if (table == NULL || table->capacity != 16 || table->count != 3 || TEST_ENTRY_STATE(15, 17, 42, 0) || TEST_ENTRY_STATE(0, 33, 69, 1) || TEST_ENTRY_STATE(1, 70, 420, 2) ) { fprintf(stderr, TOY_CC_ERROR "ERROR: Unrecognized state from table data, muiltiple inserts, with collisions, modulo wrap {17:42},{33:69},{70:420}\n" TOY_CC_RESET); Toy_freeTable(table); return -1; } //free Toy_freeTable(table); } //lookup, with collisions, modulo wrap { //setup Toy_Table* table = Toy_allocateTable(); //inserts Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(17), TOY_VALUE_TO_INTEGER(42)); //hash: 15 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(33), TOY_VALUE_TO_INTEGER(69)); //hash: 15 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(70), TOY_VALUE_TO_INTEGER(420)); //hash: 15 //lookup Toy_Value result = Toy_lookupTable(&table, TOY_VALUE_TO_INTEGER(33)); //check the state if (table == NULL || table->capacity != 16 || table->count != 3 || TOY_VALUE_IS_INTEGER(result) != true || TOY_VALUE_AS_INTEGER(result) != 69 ) { fprintf(stderr, TOY_CC_ERROR "ERROR: Bad result from table lookup with collisions and modulo wrap\n" TOY_CC_RESET); Toy_freeTable(table); return -1; } //free Toy_freeTable(table); } //multiple inserts, with collisions, modulo wrap, psl overlap { //setup Toy_Table* table = Toy_allocateTable(); //inserts Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(17), TOY_VALUE_TO_INTEGER(42)); //hash: 15 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(33), TOY_VALUE_TO_INTEGER(69)); //hash: 15 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(70), TOY_VALUE_TO_INTEGER(420)); //hash: 15 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(35), TOY_VALUE_TO_INTEGER(8891)); //hash: 1 //check the state if (table == NULL || table->capacity != 16 || table->count != 4 || TEST_ENTRY_STATE(15, 17, 42, 0) || TEST_ENTRY_STATE(0, 33, 69, 1) || TEST_ENTRY_STATE(1, 70, 420, 2) || TEST_ENTRY_STATE(2, 35, 8891, 1) ) { fprintf(stderr, TOY_CC_ERROR "ERROR: Unrecognized state from table data, muiltiple inserts, with collisions, modulo wrap, psl overlap {17:42},{33:69},{70:420},{35:8891}\n" TOY_CC_RESET); Toy_freeTable(table); return -1; } //free Toy_freeTable(table); } //multiple inserts, with collisions, modulo wrap, psl overlap, psl shift { //setup Toy_Table* table = Toy_allocateTable(); //inserts Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(17), TOY_VALUE_TO_INTEGER(42)); //hash: 15 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(33), TOY_VALUE_TO_INTEGER(69)); //hash: 15 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(70), TOY_VALUE_TO_INTEGER(420)); //hash: 15 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(35), TOY_VALUE_TO_INTEGER(8891)); //hash: 1 //remove Toy_removeTable(&table, TOY_VALUE_TO_INTEGER(33)); //check the state if (table == NULL || table->capacity != 16 || table->count != 3 || TEST_ENTRY_STATE(15, 17, 42, 0) || TEST_ENTRY_STATE(0, 70, 420, 1) || TEST_ENTRY_STATE(1, 35, 8891, 0) ) { fprintf(stderr, TOY_CC_ERROR "ERROR: Unrecognized state from table data, muiltiple inserts, with collisions, modulo wrap, psl overlap, psl shift {17:42},{*33:69},{70:420},{35:8891}\n" TOY_CC_RESET); Toy_freeTable(table); return -1; } //free Toy_freeTable(table); } return 0; } int test_table_contents_with_expansions() { //simple expansion { //setup Toy_Table* table = Toy_allocateTable(); //insert a key and value for (int i = 0; i < 20; i++) { Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(i), TOY_VALUE_TO_INTEGER(42)); } //check the state if (table == NULL || table->capacity != 32 || table->count != 20 ) { fprintf(stderr, TOY_CC_ERROR "ERROR: Failed to expand table capacity\n" TOY_CC_RESET); Toy_freeTable(table); return -1; } //free Toy_freeTable(table); } //expansion, multiple inserts, no collisions { //setup Toy_Table* table = Toy_allocateTable(); //inserts Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(0), TOY_VALUE_TO_INTEGER(42)); //hash: 0 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(35), TOY_VALUE_TO_INTEGER(42)); //hash: 1 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(19), TOY_VALUE_TO_INTEGER(42)); //hash: 2 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(8), TOY_VALUE_TO_INTEGER(42)); //hash: 3 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(10), TOY_VALUE_TO_INTEGER(42)); //hash: 4 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(3), TOY_VALUE_TO_INTEGER(42)); //hash: 5 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(28), TOY_VALUE_TO_INTEGER(42)); //hash: 6 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(1), TOY_VALUE_TO_INTEGER(42)); //hash: 7 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(6), TOY_VALUE_TO_INTEGER(42)); //hash: 8 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(93), TOY_VALUE_TO_INTEGER(42)); //hash: 9 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(85), TOY_VALUE_TO_INTEGER(42)); //hash: 10 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(9), TOY_VALUE_TO_INTEGER(42)); //hash: 11 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(11), TOY_VALUE_TO_INTEGER(42)); //hash: 12 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(22), TOY_VALUE_TO_INTEGER(42)); //hash: 13 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(13), TOY_VALUE_TO_INTEGER(42)); //hash: 14 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(17), TOY_VALUE_TO_INTEGER(42)); //hash: 15 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(43), TOY_VALUE_TO_INTEGER(42)); //hash: 16 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(4), TOY_VALUE_TO_INTEGER(42)); //hash: 17 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(5), TOY_VALUE_TO_INTEGER(42)); //hash: 18 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(7), TOY_VALUE_TO_INTEGER(42)); //hash: 19 //check the state if (table == NULL || table->capacity != 32 || table->count != 20 || //effectively, check that each key was placed in the correct position after the expansion TEST_ENTRY_STATE(0, 0, 42, 0) || TEST_ENTRY_STATE(1, 35, 42, 0) || TEST_ENTRY_STATE(2, 19, 42, 0) || TEST_ENTRY_STATE(3, 8, 42, 0) || TEST_ENTRY_STATE(4, 10, 42, 0) || TEST_ENTRY_STATE(5, 3, 42, 0) || TEST_ENTRY_STATE(6, 28, 42, 0) || TEST_ENTRY_STATE(7, 1, 42, 0) || TEST_ENTRY_STATE(8, 6, 42, 0) || TEST_ENTRY_STATE(9, 93, 42, 0) || TEST_ENTRY_STATE(10, 85, 42, 0) || TEST_ENTRY_STATE(11, 9, 42, 0) || TEST_ENTRY_STATE(12, 11, 42, 0) || TEST_ENTRY_STATE(13, 22, 42, 0) || TEST_ENTRY_STATE(14, 13, 42, 0) || TEST_ENTRY_STATE(15, 17, 42, 0) || TEST_ENTRY_STATE(16, 43, 42, 0) || TEST_ENTRY_STATE(17, 4, 42, 0) || TEST_ENTRY_STATE(18, 5, 42, 0) || TEST_ENTRY_STATE(19, 7, 42, 0) ) { fprintf(stderr, TOY_CC_ERROR "ERROR: Unrecognized state from table data after expansion, multiple inserts, no collisions\n" TOY_CC_RESET); Toy_freeTable(table); return -1; } //free Toy_freeTable(table); } //multiple inserts, with collisions { //setup Toy_Table* table = Toy_allocateTable(); //inserts Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(0), TOY_VALUE_TO_INTEGER(42)); //hash: 0 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(35), TOY_VALUE_TO_INTEGER(42)); //hash: 1 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(19), TOY_VALUE_TO_INTEGER(42)); //hash: 2 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(8), TOY_VALUE_TO_INTEGER(42)); //hash: 3 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(10), TOY_VALUE_TO_INTEGER(42)); //hash: 4 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(3), TOY_VALUE_TO_INTEGER(42)); //hash: 5 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(28), TOY_VALUE_TO_INTEGER(42)); //hash: 6 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(1), TOY_VALUE_TO_INTEGER(42)); //hash: 7 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(6), TOY_VALUE_TO_INTEGER(42)); //hash: 8 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(93), TOY_VALUE_TO_INTEGER(42)); //hash: 9 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(85), TOY_VALUE_TO_INTEGER(42)); //hash: 10 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(9), TOY_VALUE_TO_INTEGER(42)); //hash: 11 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(11), TOY_VALUE_TO_INTEGER(42)); //hash: 12 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(22), TOY_VALUE_TO_INTEGER(42)); //hash: 13 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(13), TOY_VALUE_TO_INTEGER(42)); //hash: 14 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(17), TOY_VALUE_TO_INTEGER(42)); //hash: 15 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(43), TOY_VALUE_TO_INTEGER(42)); //hash: 16 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(4), TOY_VALUE_TO_INTEGER(42)); //hash: 17 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(5), TOY_VALUE_TO_INTEGER(42)); //hash: 18 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(7), TOY_VALUE_TO_INTEGER(42)); //hash: 19 //insert one more Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(70), TOY_VALUE_TO_INTEGER(42)); //hash: 15 //check the state if (table == NULL || table->capacity != 32 || table->count != 21 || TEST_ENTRY_STATE(0, 0, 42, 0) || TEST_ENTRY_STATE(1, 35, 42, 0) || TEST_ENTRY_STATE(2, 19, 42, 0) || TEST_ENTRY_STATE(3, 8, 42, 0) || TEST_ENTRY_STATE(4, 10, 42, 0) || TEST_ENTRY_STATE(5, 3, 42, 0) || TEST_ENTRY_STATE(6, 28, 42, 0) || TEST_ENTRY_STATE(7, 1, 42, 0) || TEST_ENTRY_STATE(8, 6, 42, 0) || TEST_ENTRY_STATE(9, 93, 42, 0) || TEST_ENTRY_STATE(10, 85, 42, 0) || TEST_ENTRY_STATE(11, 9, 42, 0) || TEST_ENTRY_STATE(12, 11, 42, 0) || TEST_ENTRY_STATE(13, 22, 42, 0) || TEST_ENTRY_STATE(14, 13, 42, 0) || TEST_ENTRY_STATE(15, 17, 42, 0) || TEST_ENTRY_STATE(16, 70, 42, 1) || //the collision TEST_ENTRY_STATE(17, 43, 42, 1) || TEST_ENTRY_STATE(18, 4, 42, 1) || TEST_ENTRY_STATE(19, 5, 42, 1) || TEST_ENTRY_STATE(20, 7, 42, 1) ) { fprintf(stderr, TOY_CC_ERROR "ERROR: Unrecognized state from table data after expansion, muiltiple inserts, with collisions\n" TOY_CC_RESET); Toy_freeTable(table); return -1; } //free Toy_freeTable(table); } //multiple inserts, with collisions, modulo wrap { //setup Toy_Table* table = Toy_allocateTable(); //inserts Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(123), TOY_VALUE_TO_INTEGER(42)); //hash: 20 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(42), TOY_VALUE_TO_INTEGER(42)); //hash: 21 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(132), TOY_VALUE_TO_INTEGER(42)); //hash: 22 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(34), TOY_VALUE_TO_INTEGER(42)); //hash: 23 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(2), TOY_VALUE_TO_INTEGER(42)); //hash: 24 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(32), TOY_VALUE_TO_INTEGER(42)); //hash: 25 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(21), TOY_VALUE_TO_INTEGER(42)); //hash: 26 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(44), TOY_VALUE_TO_INTEGER(42)); //hash: 27 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(104), TOY_VALUE_TO_INTEGER(42)); //hash: 28 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(15), TOY_VALUE_TO_INTEGER(42)); //hash: 29 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(57), TOY_VALUE_TO_INTEGER(42)); //hash: 30 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(33), TOY_VALUE_TO_INTEGER(42)); //hash: 31 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(0), TOY_VALUE_TO_INTEGER(42)); //hash: 32 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(35), TOY_VALUE_TO_INTEGER(42)); //hash: 33 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(19), TOY_VALUE_TO_INTEGER(42)); //hash: 34 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(8), TOY_VALUE_TO_INTEGER(42)); //hash: 35 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(10), TOY_VALUE_TO_INTEGER(42)); //hash: 36 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(3), TOY_VALUE_TO_INTEGER(42)); //hash: 37 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(28), TOY_VALUE_TO_INTEGER(42)); //hash: 38 Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(1), TOY_VALUE_TO_INTEGER(42)); //hash: 39 //insert one more Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(79), TOY_VALUE_TO_INTEGER(42)); //hash: 23 //check the state if (table == NULL || table->capacity != 32 || table->count != 21 || TEST_ENTRY_STATE(20, 123, 42, 0) || TEST_ENTRY_STATE(21, 42, 42, 0) || TEST_ENTRY_STATE(22, 132, 42, 0) || TEST_ENTRY_STATE(23, 34, 42, 0) || TEST_ENTRY_STATE(24, 79, 42, 1) || //the collision TEST_ENTRY_STATE(25, 2, 42, 1) || TEST_ENTRY_STATE(26, 32, 42, 1) || TEST_ENTRY_STATE(27, 21, 42, 1) || TEST_ENTRY_STATE(28, 44, 42, 1) || TEST_ENTRY_STATE(29, 104, 42, 1) || TEST_ENTRY_STATE(30, 15, 42, 1) || TEST_ENTRY_STATE(31, 57, 42, 1) || TEST_ENTRY_STATE(0, 33, 42, 1) || TEST_ENTRY_STATE(1, 0, 42, 1) || TEST_ENTRY_STATE(2, 35, 42, 1) || TEST_ENTRY_STATE(3, 19, 42, 1) || TEST_ENTRY_STATE(4, 8, 42, 1) || TEST_ENTRY_STATE(5, 10, 42, 1) || TEST_ENTRY_STATE(6, 3, 42, 1) || TEST_ENTRY_STATE(7, 28, 42, 1) || TEST_ENTRY_STATE(8, 1, 42, 1) ) { fprintf(stderr, TOY_CC_ERROR "ERROR: Unrecognized state from table data after expansion, muiltiple inserts, with collisions, modulo wrap\n" TOY_CC_RESET); Toy_freeTable(table); return -1; } //free Toy_freeTable(table); } //lookup, with collisions, modulo wrap { //setup Toy_Table* table = Toy_allocateTable(); //inserts for (int i = 0; i < 20; i++) { //enough to expand Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(i), TOY_VALUE_TO_INTEGER(100 - i)); } //lookup Toy_Value result = Toy_lookupTable(&table, TOY_VALUE_TO_INTEGER(15)); //check the state if (table == NULL || table->capacity != 32 || table->count != 20 || TOY_VALUE_IS_INTEGER(result) != true || TOY_VALUE_AS_INTEGER(result) != 85 ) { fprintf(stderr, TOY_CC_ERROR "ERROR: Bad result from table lookup after expansion, with collisions and modulo wrap\n" TOY_CC_RESET); Toy_freeTable(table); return -1; } //free Toy_freeTable(table); } //Skipped: multiple inserts, with collisions, modulo wrap, psl overlap //Skipped: multiple inserts, with collisions, modulo wrap, psl overlap, psl shift //Note: since psl overlap and psl shift both work without expansion, I'm leaving these tests unimplemented due to exhaustion. return 0; } int test_table_expansions_under_stress() { //multiple expansions, find one value { //setup Toy_Table* table = Toy_allocateTable(); int top = 300; //insert keys and values for (int i = 0; i < 300; i++) { Toy_insertTable(&table, TOY_VALUE_TO_INTEGER(i), TOY_VALUE_TO_INTEGER(top - i)); } Toy_Value result = Toy_lookupTable(&table, TOY_VALUE_TO_INTEGER(265)); //check the state if (table == NULL || table->capacity != 512 || table->count != 300 || TOY_VALUE_IS_INTEGER(result) != true || TOY_VALUE_AS_INTEGER(result) != 35 ) { fprintf(stderr, TOY_CC_ERROR "ERROR: Table expansions under stress failed\n" TOY_CC_RESET); Toy_freeTable(table); return -1; } //free Toy_freeTable(table); } return 0; } int main() { //run each test set, returning the total errors given int total = 0, res = 0; //Note: there's some utility c programs in .notes called "hash_generator" that can help { res = test_table_allocation(); if (res == 0) { printf(TOY_CC_NOTICE "All good\n" TOY_CC_RESET); } total += res; } { res = test_table_simple_insert_lookup_and_remove(); if (res == 0) { printf(TOY_CC_NOTICE "All good\n" TOY_CC_RESET); } total += res; } { res = test_table_contents_no_expansion(); if (res == 0) { printf(TOY_CC_NOTICE "All good\n" TOY_CC_RESET); } total += res; } { res = test_table_contents_with_expansions(); if (res == 0) { printf(TOY_CC_NOTICE "All good\n" TOY_CC_RESET); } total += res; } { res = test_table_expansions_under_stress(); if (res == 0) { printf(TOY_CC_NOTICE "All good\n" TOY_CC_RESET); } total += res; } return total; }