libabacus/src/trie.c

122 lines
3.2 KiB
C
Raw Normal View History

2018-03-24 02:01:39 -07:00
#include "trie.h"
#include "util.h"
2018-04-21 14:09:01 -07:00
#include <stdlib.h>
2018-03-24 02:01:39 -07:00
void libab_trie_init(libab_trie* trie) {
trie->head = NULL;
ll_init(&trie->empty_list);
}
void _libab_trie_free(libab_trie_node* to_free) {
2018-04-21 14:09:01 -07:00
if (to_free == NULL)
return;
2018-03-24 02:01:39 -07:00
_libab_trie_free(to_free->next);
_libab_trie_free(to_free->child);
ll_free(&to_free->values);
free(to_free);
}
2018-04-21 14:09:01 -07:00
libab_result _libab_trie_put(libab_trie_node** node, const char* key,
void* value) {
2018-03-24 02:01:39 -07:00
libab_result result = LIBAB_SUCCESS;
2018-04-21 14:09:01 -07:00
if ((*node = malloc(sizeof(**node)))) {
2018-03-24 02:01:39 -07:00
(*node)->key = *key;
(*node)->next = NULL;
ll_init(&(*node)->values);
2018-04-21 14:09:01 -07:00
if (*(key + 1)) {
2018-03-24 02:01:39 -07:00
result = _libab_trie_put(&(*node)->child, key + 1, value);
} else {
(*node)->child = NULL;
2018-04-21 14:09:01 -07:00
result =
libab_convert_ds_result(ll_append(&(*node)->values, value));
2018-03-24 02:01:39 -07:00
}
} else {
result = LIBAB_MALLOC;
}
2018-04-21 14:09:01 -07:00
if (result != LIBAB_SUCCESS) {
2018-03-24 02:01:39 -07:00
free(*node);
*node = NULL;
}
return result;
}
libab_result _libab_trie_add(libab_trie_node* node, void* value) {
return libab_convert_ds_result(ll_append(&node->values, value));
}
libab_result libab_trie_put(libab_trie* trie, const char* key, void* value) {
libab_result result = LIBAB_SUCCESS;
libab_trie_node** current = &trie->head;
char search;
2018-04-21 14:09:01 -07:00
while (*key) {
2018-03-24 02:01:39 -07:00
search = *key;
2018-04-21 14:09:01 -07:00
while (*current && (*current)->key != search) {
2018-03-24 02:01:39 -07:00
current = &(*current)->next;
}
2018-04-21 14:09:01 -07:00
if (*current) {
if (*(key + 1)) {
2018-03-24 02:01:39 -07:00
current = &(*current)->child;
} else {
result = _libab_trie_add(*current, value);
}
key++;
} else {
result = _libab_trie_put(current, key, value);
break;
}
}
return result;
}
2018-03-24 20:40:42 -07:00
const ll* libab_trie_get(const libab_trie* trie, const char* key) {
2018-03-24 02:01:39 -07:00
libab_trie_node* current = trie->head;
2018-04-21 14:09:01 -07:00
while (current && *key) {
while (current && current->key != *key) {
2018-03-24 02:01:39 -07:00
current = current->next;
}
2018-04-21 14:09:01 -07:00
if (current == NULL)
break;
if (*(key + 1)) {
2018-03-24 02:01:39 -07:00
current = current->child;
key++;
} else {
return &current->values;
}
}
return &trie->empty_list;
}
2018-04-21 14:09:01 -07:00
int _libab_trie_foreach(libab_trie_node* node, void* data, compare_func compare,
foreach_func foreach) {
2018-03-24 20:40:42 -07:00
int return_code;
2018-04-21 14:09:01 -07:00
if (node == NULL)
return 0;
2018-03-24 20:40:42 -07:00
return_code = ll_foreach(&node->values, data, compare, foreach);
2018-04-21 14:09:01 -07:00
if (return_code == 0) {
return_code = _libab_trie_foreach(node->child, data, compare, foreach);
2018-03-24 20:40:42 -07:00
}
2018-04-21 14:09:01 -07:00
if (return_code == 0) {
2018-03-24 20:40:42 -07:00
return_code = _libab_trie_foreach(node->next, data, compare, foreach);
}
return return_code;
}
2018-04-21 14:09:01 -07:00
int libab_trie_foreach(const libab_trie* trie, void* data, compare_func compare,
foreach_func foreach) {
2018-03-24 20:40:42 -07:00
return _libab_trie_foreach(trie->head, data, compare, foreach);
}
2018-05-31 19:29:14 -07:00
void libab_trie_clear(libab_trie* trie) {
libab_trie_free(trie);
libab_trie_init(trie);
}
2018-03-24 02:01:39 -07:00
void libab_trie_free(libab_trie* trie) {
2018-04-21 14:09:01 -07:00
_libab_trie_free(trie->head);
2018-03-24 02:01:39 -07:00
trie->head = NULL;
}