Add the ability to copy a ref trie.

This commit is contained in:
Danila Fedorin 2018-05-11 14:40:01 -07:00
parent 92186911ad
commit 8f48a16a25
2 changed files with 64 additions and 9 deletions

View File

@ -53,6 +53,14 @@ typedef struct libab_ref_trie_s libab_ref_trie;
* @param trie the trie to initialize. * @param trie the trie to initialize.
*/ */
void libab_ref_trie_init(libab_ref_trie* trie); void libab_ref_trie_init(libab_ref_trie* trie);
/**
* Initializes a new trie with a shallow copy of another.
* @param trie the trie to initialize.
* @param copy_of the trie to copy.
* @return the result of the initialization.
*/
libab_result libab_ref_trie_init_copy(libab_ref_trie* trie,
const libab_ref_trie* copy_of);
/** /**
* Stores a reference counted value into the trie. * Stores a reference counted value into the trie.
* This releases the reference for the given key, if one * This releases the reference for the given key, if one

View File

@ -6,6 +6,62 @@ void libab_ref_trie_init(libab_ref_trie* trie) {
trie->head = NULL; trie->head = NULL;
} }
void _libab_ref_trie_free(libab_ref_trie_node* node) {
if (node == NULL)
return;
_libab_ref_trie_free(node->next);
_libab_ref_trie_free(node->child);
libab_ref_free(&node->ref);
free(node);
}
libab_result _libab_ref_trie_copy(const libab_ref_trie_node* copy_of,
libab_ref_trie_node** copy_into) {
libab_result result = LIBAB_SUCCESS;
if(copy_of == NULL) {
*copy_into = NULL;
} else if(((*copy_into) = malloc(sizeof(**copy_into)))) {
(*copy_into)->child = NULL;
(*copy_into)->next = NULL;
result = _libab_ref_trie_copy(copy_of->next, &(*copy_into)->next);
if(result == LIBAB_SUCCESS) {
result = _libab_ref_trie_copy(copy_of->child, &(*copy_into)->child);
}
if(result == LIBAB_SUCCESS) {
(*copy_into)->key = copy_of->key;
libab_ref_copy(&copy_of->ref, &(*copy_into)->ref);
}
} else {
result = LIBAB_MALLOC;
}
if(result != LIBAB_SUCCESS && *copy_into) {
_libab_ref_trie_free((*copy_into)->next);
_libab_ref_trie_free((*copy_into)->child);
free(*copy_into);
*copy_into = NULL;
}
return result;
}
libab_result libab_ref_trie_init_copy(libab_ref_trie* trie,
const libab_ref_trie* copy_of) {
libab_result result = LIBAB_SUCCESS;
libab_ref_trie_init(trie);
result = _libab_ref_trie_copy(copy_of->head, &trie->head);
if(result != LIBAB_SUCCESS) {
libab_ref_trie_free(trie);
}
return result;
}
libab_result _libab_ref_trie_put(libab_ref_trie_node** node, const char* key, libab_result _libab_ref_trie_put(libab_ref_trie_node** node, const char* key,
libab_ref* ref) { libab_ref* ref) {
libab_result result = LIBAB_SUCCESS; libab_result result = LIBAB_SUCCESS;
@ -80,15 +136,6 @@ const libab_ref* libab_ref_trie_get(const libab_ref_trie* trie,
return &trie->null_ref; return &trie->null_ref;
} }
void _libab_ref_trie_free(libab_ref_trie_node* node) {
if (node == NULL)
return;
_libab_ref_trie_free(node->next);
_libab_ref_trie_free(node->child);
libab_ref_free(&node->ref);
free(node);
}
void libab_ref_trie_free(libab_ref_trie* trie) { void libab_ref_trie_free(libab_ref_trie* trie) {
_libab_ref_trie_free(trie->head); _libab_ref_trie_free(trie->head);
libab_ref_free(&trie->null_ref); libab_ref_free(&trie->null_ref);