diff --git a/trie/include/trie.h b/trie/include/trie.h index 1574fa9..bb3dccb 100644 --- a/trie/include/trie.h +++ b/trie/include/trie.h @@ -81,6 +81,18 @@ TrieExitCode trie_search(Trie *trie, void **data_ptr, const char *key); TrieExitCode trie_add(Trie *trie, const char *key, void *data, uint64_t data_len); +/** + * Same as trie_add, but copy the data instead of taking over ownership of the + * pointer. + * + * @param trie + * @param key key to represent entry with + * @param entry entry to add + * @return 0 if added, 1 if already in trie, something else if other errors + */ +TrieExitCode trie_add_copy(Trie *trie, const char *key, void *data, + uint64_t data_len); + /** * Add an entry by generating a random string as the key. * diff --git a/trie/src/trie.c b/trie/src/trie.c index 57a3b0e..8c424c4 100644 --- a/trie/src/trie.c +++ b/trie/src/trie.c @@ -339,6 +339,20 @@ TrieExitCode trie_add_random(Trie *trie, char **key_ptr, void *data, return return_value; } +TrieExitCode trie_add_copy(Trie *trie, const char *key, void *data, + uint64_t data_len) { + void *owned_data = malloc(data_len); + memcpy(owned_data, data, data_len); + + TrieExitCode result = trie_add(trie, key, owned_data, data_len); + + if (result != Ok) { + free(owned_data); + } + + return result; +} + /** * Remove the given string from a Trie. * diff --git a/trie/test/fuzzy.h b/trie/test/fuzzy.h index 00dc386..805ac82 100644 --- a/trie/test/fuzzy.h +++ b/trie/test/fuzzy.h @@ -114,9 +114,10 @@ int fuzzy_test_trie_seed(FuzzyConfig conf) { // 4: bad size after removes int exit_code = 0; + char payload[1] = ""; // Add all strings to trie, checking for duplicates for (int i = 0; i < conf.word_count; i++) { - status = trie_add(ct, matrix[i], NULL); + status = trie_add_copy(ct, matrix[i], &payload, 1); // if changed is false, *contains_dedupped[i] should be true, as changed // can only be false if the string is already contained in the trie. if @@ -135,7 +136,7 @@ int fuzzy_test_trie_seed(FuzzyConfig conf) { // Ensure size is correct if (trie_size(ct) != size) { - printf("%i %i\n", trie_size(ct), size); + printf("%lu %lu\n", trie_size(ct), size); exit_code = 3; goto END; } diff --git a/trie/test/test_trie.c b/trie/test/test_trie.c index 1cd376a..ad28748 100644 --- a/trie/test/test_trie.c +++ b/trie/test/test_trie.c @@ -6,7 +6,7 @@ TEST_CHECK(trie_size(ct) == size); \ TEST_MSG("Size: %zu", trie_size(ct)) -# define TRIE_INIT() \ +#define TRIE_INIT() \ Trie *ct; \ trie_init(&ct, NULL); \ TEST_CHECK(ct != NULL) @@ -20,16 +20,14 @@ void test_init() { void test_add_one() { TRIE_INIT(); - Entry *entry = entry_new(Redirect, ""); const char* string = "this is a test"; - TEST_CHECK(trie_add(ct, string, entry) == Ok); - Entry *entry2; - TEST_CHECK(trie_search(ct, &entry2, string) == Ok); - TEST_CHECK(entry == entry2); + TEST_CHECK(trie_add_copy(ct, string, "", 1) == Ok); + void *data; + TEST_CHECK(trie_search(ct, &data, string) == Ok); + TEST_CHECK(memcmp(data, "", 1) == 0); TEST_SIZE(ct, 1); - entry_free(entry); trie_free(ct); } @@ -39,32 +37,27 @@ void test_add_prefix() { const char *s1 = "halloween-2022"; const char *s2 = "halloween-202"; - Entry *entry1 = entry_new(Redirect, ""); - Entry *entry2 = entry_new(Redirect, ""); + TEST_CHECK(trie_add_copy(ct, s1, "a", 2) == Ok); + TEST_CHECK(trie_add_copy(ct, s2, "b", 2) == Ok); - TEST_CHECK(trie_add(ct, s1, entry1) == Ok); - TEST_CHECK(trie_add(ct, s2, entry2) == Ok); + void *data; - Entry *entry3; + TEST_CHECK(trie_search(ct, &data, s1) == Ok); + TEST_CHECK(memcmp(data, "a", 2) == 0); + data = NULL; - TEST_CHECK(trie_search(ct, &entry3, s1) == Ok); - TEST_CHECK(entry3 == entry1); - entry2 = NULL; + TEST_CHECK(trie_search(ct, &data, s2) == Ok); + TEST_CHECK(memcmp(data, "b", 2) == 0); - TEST_CHECK(trie_search(ct, &entry3, s2) == Ok); - TEST_CHECK(entry3 == entry2); - - entry_free(entry1); - entry_free(entry2); trie_free(ct); } void test_search_not_present() { TRIE_INIT(); - TEST_CHECK(trie_add(ct, "this string exists", NULL) == Ok); - Entry *entry; - TEST_CHECK(trie_search(ct, &entry, "this string does not exist") == NotFound); + TEST_CHECK(trie_add_copy(ct, "this string exists", "", 1) == Ok); + void *data; + TEST_CHECK(trie_search(ct, &data, "this string does not exist") == NotFound); trie_free(ct); } @@ -77,38 +70,34 @@ void test_add_more() { const char* twenty = "twenty"; const char* twentytwo = "twentytwo"; - Entry *entry = entry_new(Redirect, ""); - - TEST_CHECK(trie_add(ct, one, entry) == Ok); - TEST_CHECK(trie_add(ct, two, entry) == Ok); - TEST_CHECK(trie_add(ct, twenty, entry) == Ok); - TEST_CHECK(trie_add(ct, twentytwo, entry) == Ok); + TEST_CHECK(trie_add_copy(ct, one, "a", 2) == Ok); + TEST_CHECK(trie_add_copy(ct, two, "b", 2) == Ok); + TEST_CHECK(trie_add_copy(ct, twenty, "c", 2) == Ok); + TEST_CHECK(trie_add_copy(ct, twentytwo, "d", 2) == Ok); TEST_SIZE(ct, 4); - Entry *entry2; - TEST_CHECK(trie_search(ct, &entry2, one) == Ok); - TEST_CHECK(entry2 == entry); - entry2 = NULL; + void *data; + TEST_CHECK(trie_search(ct, &data, one) == Ok); + TEST_CHECK(memcmp(data, "a", 2) == 0); + data = NULL; - TEST_CHECK(trie_search(ct, &entry2, two) == Ok); - TEST_CHECK(entry2 == entry); - entry2 = NULL; + TEST_CHECK(trie_search(ct, &data, two) == Ok); + TEST_CHECK(memcmp(data, "b", 2) == 0); + data = NULL; - TEST_CHECK(trie_search(ct, &entry2, twenty) == Ok); - TEST_CHECK(entry2 == entry); - entry2 = NULL; + TEST_CHECK(trie_search(ct, &data, twenty) == Ok); + TEST_CHECK(memcmp(data, "c", 2) == 0); + data = NULL; - TEST_CHECK(trie_search(ct, &entry2, twentytwo) == Ok); - TEST_CHECK(entry2 == entry); - entry2 = NULL; + TEST_CHECK(trie_search(ct, &data, twentytwo) == Ok); + TEST_CHECK(memcmp(data, "d", 2) == 0); - TEST_CHECK(trie_add(ct, one, NULL) == AlreadyPresent); - TEST_CHECK(trie_add(ct, two, NULL) == AlreadyPresent); - TEST_CHECK(trie_add(ct, twenty, NULL) == AlreadyPresent); - TEST_CHECK(trie_add(ct, twentytwo, NULL) == AlreadyPresent); + TEST_CHECK(trie_add_copy(ct, one, "", 2) == AlreadyPresent); + TEST_CHECK(trie_add_copy(ct, two, "", 2) == AlreadyPresent); + TEST_CHECK(trie_add_copy(ct, twenty, "", 2) == AlreadyPresent); + TEST_CHECK(trie_add_copy(ct, twentytwo, "", 2) == AlreadyPresent); - entry_free(entry); trie_free(ct); } @@ -117,7 +106,7 @@ void test_add_more() { /* TEST_CHECK(ct != NULL); */ /* const char* string = "this is a test"; */ -/* TEST_CHECK(trie_add(ct, string, NULL)); */ +/* TEST_CHECK(trie_add_copy(ct, string, NULL)); */ /* TEST_SIZE(ct, 1); */ /* TEST_CHECK(trie_remove(ct, string)); */ @@ -134,10 +123,10 @@ void test_add_more() { /* const char* two = "two"; */ /* const char* twenty = "twenty"; */ /* const char* twentytwo = "twentytwo"; */ -/* TEST_CHECK(trie_add(ct, one, NULL)); */ -/* TEST_CHECK(trie_add(ct, two, NULL)); */ -/* TEST_CHECK(trie_add(ct, twenty, NULL)); */ -/* TEST_CHECK(trie_add(ct, twentytwo, NULL)); */ +/* TEST_CHECK(trie_add_copy(ct, one, NULL)); */ +/* TEST_CHECK(trie_add_copy(ct, two, NULL)); */ +/* TEST_CHECK(trie_add_copy(ct, twenty, NULL)); */ +/* TEST_CHECK(trie_add_copy(ct, twentytwo, NULL)); */ /* TEST_SIZE(ct, 4); */ @@ -155,7 +144,7 @@ void test_add_more() { /* Trie* ct = trie_init(); */ /* TEST_CHECK(ct != NULL); */ -/* TEST_CHECK(trie_add(ct, "this string exists", NULL)); */ +/* TEST_CHECK(trie_add_copy(ct, "this string exists", NULL)); */ /* TEST_CHECK(!trie_remove(ct, "this string does not exist")); */ /* trie_free(ct); */