2018-04-06 23:55:56 -07:00
|
|
|
#include "ref_trie.h"
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
void libab_ref_trie_init(libab_ref_trie* trie) {
|
|
|
|
libab_ref_null(&trie->null_ref);
|
|
|
|
trie->head = NULL;
|
|
|
|
}
|
|
|
|
|
2018-04-21 14:09:01 -07:00
|
|
|
libab_result _libab_ref_trie_put(libab_ref_trie_node** node, const char* key,
|
|
|
|
libab_ref* ref) {
|
2018-04-06 23:55:56 -07:00
|
|
|
libab_result result = LIBAB_SUCCESS;
|
2018-04-21 14:09:01 -07:00
|
|
|
if ((*node = malloc(sizeof(**node)))) {
|
2018-04-06 23:55:56 -07:00
|
|
|
(*node)->key = *key;
|
|
|
|
(*node)->next = NULL;
|
|
|
|
|
2018-04-21 14:09:01 -07:00
|
|
|
if (*(key + 1)) {
|
2018-04-06 23:55:56 -07:00
|
|
|
libab_ref_null(&(*node)->ref);
|
|
|
|
result = _libab_ref_trie_put(&(*node)->child, key + 1, ref);
|
|
|
|
} else {
|
|
|
|
libab_ref_copy(ref, &(*node)->ref);
|
|
|
|
(*node)->child = NULL;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
result = LIBAB_MALLOC;
|
|
|
|
}
|
|
|
|
|
2018-04-21 14:09:01 -07:00
|
|
|
if (result != LIBAB_SUCCESS) {
|
|
|
|
if (*node)
|
|
|
|
libab_ref_free(&(*node)->ref);
|
2018-04-06 23:55:56 -07:00
|
|
|
free(*node);
|
|
|
|
*node = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2018-04-21 14:09:01 -07:00
|
|
|
libab_result libab_ref_trie_put(libab_ref_trie* trie, const char* key,
|
|
|
|
libab_ref* ref) {
|
2018-04-06 23:55:56 -07:00
|
|
|
libab_result result = LIBAB_SUCCESS;
|
|
|
|
libab_ref_trie_node** current = &trie->head;
|
|
|
|
char search;
|
2018-04-21 14:09:01 -07:00
|
|
|
while (*key) {
|
2018-04-06 23:55:56 -07:00
|
|
|
search = *key;
|
2018-04-21 14:09:01 -07:00
|
|
|
while (*current && (*current)->key != search) {
|
2018-04-06 23:55:56 -07:00
|
|
|
current = &(*current)->next;
|
|
|
|
}
|
2018-04-21 14:09:01 -07:00
|
|
|
if (*current) {
|
|
|
|
if (*(key + 1)) {
|
2018-04-06 23:55:56 -07:00
|
|
|
current = &(*current)->child;
|
|
|
|
} else {
|
|
|
|
libab_ref_free(&(*current)->ref);
|
|
|
|
libab_ref_copy(ref, &(*current)->ref);
|
|
|
|
}
|
|
|
|
key++;
|
|
|
|
} else {
|
|
|
|
result = _libab_ref_trie_put(current, key, ref);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2018-04-21 14:09:01 -07:00
|
|
|
const libab_ref* libab_ref_trie_get(const libab_ref_trie* trie,
|
|
|
|
const char* key) {
|
2018-04-06 23:55:56 -07:00
|
|
|
libab_ref_trie_node* current = trie->head;
|
2018-04-21 14:09:01 -07:00
|
|
|
while (current && *key) {
|
|
|
|
while (current && current->key != *key) {
|
2018-04-06 23:55:56 -07:00
|
|
|
current = current->next;
|
|
|
|
}
|
2018-04-21 14:09:01 -07:00
|
|
|
if (current == NULL)
|
|
|
|
break;
|
2018-04-06 23:55:56 -07:00
|
|
|
|
2018-04-21 14:09:01 -07:00
|
|
|
if (*(key + 1)) {
|
2018-04-06 23:55:56 -07:00
|
|
|
current = current->child;
|
|
|
|
key++;
|
|
|
|
} else {
|
|
|
|
return ¤t->ref;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return &trie->null_ref;
|
|
|
|
}
|
|
|
|
|
|
|
|
void _libab_ref_trie_free(libab_ref_trie_node* node) {
|
2018-04-21 14:09:01 -07:00
|
|
|
if (node == NULL)
|
|
|
|
return;
|
2018-04-06 23:55:56 -07:00
|
|
|
_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) {
|
|
|
|
_libab_ref_trie_free(trie->head);
|
|
|
|
libab_ref_free(&trie->null_ref);
|
|
|
|
}
|