52 static int ldns_radix_find_prefix(
ldns_radix_t* tree, uint8_t* key,
59 uint8_t* longer_str,
radix_strlen_t longer_len, uint8_t** split_str,
63 static int ldns_radix_str_is_prefix(uint8_t* str1,
radix_strlen_t len1,
155 ldns_radix_node_free, NULL);
175 if (!tree || !key || !data) {
178 add = ldns_radix_new_node(data, key, len);
183 if (!ldns_radix_find_prefix(tree, key, len, &prefix, &pos)) {
185 assert(tree->
root == NULL);
197 prefix = ldns_radix_new_node(NULL, (uint8_t*)
"", 0);
203 if (!ldns_radix_array_space(prefix, key[0])) {
215 if (!ldns_radix_prefix_remainder(1, key,
226 }
else if (pos == len) {
238 uint8_t
byte = key[pos];
240 if (byte < prefix->offset ||
241 (
byte - prefix->
offset) >= prefix->
len) {
249 if (!ldns_radix_array_space(prefix,
byte)) {
253 assert(
byte >= prefix->
offset);
254 assert((
byte - prefix->
offset) <= prefix->
len);
258 if (!ldns_radix_str_create(
259 &prefix->
array[
byte], key, pos+1,
281 if (!ldns_radix_str_create(
282 &prefix->
array[
byte], key, pos+1,
297 if (!ldns_radix_array_split(&prefix->
array[
byte-(prefix->
offset)],
298 key, pos+1, len, add)) {
322 ldns_radix_del_fix(tree, del);
346 return node->
data?node:NULL;
349 if (byte < node->offset) {
353 if (
byte >= node->
len) {
359 if (pos + node->
array[
byte].
len > len) {
362 if (memcmp(&key[pos], node->
array[
byte].
str,
388 if (!tree || !tree->
root || !key) {
396 if (byte < node->offset) {
401 ldns_radix_self_or_prev(node, result);
405 if (
byte >= node->
len) {
410 *result = ldns_radix_last_in_subtree_incl_self(node);
411 if (*result == NULL) {
422 *result = ldns_radix_prev_from_index(node,
byte);
423 if (*result == NULL) {
424 ldns_radix_self_or_prev(node, result);
430 if (pos + node->
array[
byte].
len > len) {
432 if (memcmp(&key[pos], node->
array[
byte].
str,
439 *result = ldns_radix_last_in_subtree_incl_self(node->
array[
byte].
edge);
440 if (*result == NULL) {
446 memcmp_res = memcmp(&key[pos], node->
array[
byte].
str,
448 if (memcmp_res < 0) {
452 }
else if (memcmp_res > 0) {
453 *result = ldns_radix_last_in_subtree_incl_self(node->
array[
byte].
edge);
454 if (*result == NULL) {
483 if (!tree || !tree->
root) {
501 if (!tree || !tree->
root) {
504 return ldns_radix_last_in_subtree_incl_self(tree->
root);
530 for (; index < node->
len; index++) {
538 next = ldns_radix_next_in_subtree(node);
565 assert(node->
len > 0);
566 prev = ldns_radix_prev_from_index(node, index);
590 for (j = 0; j < d; j++) {
595 fprintf(fd,
"| [%u+", (
unsigned) i);
596 for (l=0; l < len; l++) {
597 fprintf(fd,
"%c", (
char) str[l]);
599 fprintf(fd,
"]%u", (
unsigned) len);
601 fprintf(fd,
"| [%u]", (
unsigned) i);
605 fprintf(fd,
" %s", (
char*) node->
data);
609 for (j = 0; j < node->
len; j++) {
611 ldns_radix_node_print(fd, node->
array[j].
edge, j,
630 fprintf(fd,
"; empty radix tree\n");
633 ldns_radix_node_print(fd, tree->
root, 0, NULL, 0, 0);
647 if (!tree2 || !tree2->
root) {
656 if (cur_node->
data) {
670 cur_node = next_node;
687 if (!tree1 || !tree1->
root || num == 0) {
700 while (count < num && cur_node) {
701 if (cur_node->
data) {
703 uint8_t* cur_key = cur_node->
key;
747 for (i=0; i < node->
len; i++) {
773 ldns_radix_find_prefix(
ldns_radix_t* tree, uint8_t* key,
793 if (byte < n->offset) {
798 if (
byte >= n->
len) {
806 if (pos + n->
array[
byte].
len > len) {
809 if (memcmp(&key[pos], n->
array[
byte].
str,
854 assert(node->
array != NULL);
857 if (node->
len == 0) {
861 }
else if (byte < node->offset) {
864 uint16_t need = node->
offset - byte;
868 if (!ldns_radix_array_grow(node,
869 (
unsigned) (node->
len + need))) {
877 for (index = 0; index < node->
len; index++) {
887 }
else if (
byte - node->
offset >= node->
len) {
889 uint16_t need = (
byte - node->
offset) - node->
len + 1;
893 if (!ldns_radix_array_grow(node,
894 (
unsigned) (node->
len + need))) {
918 unsigned size = ((unsigned)node->
capacity)*2;
957 memmove(array->
str, key+pos, len-pos);
958 array->
len = (len-pos);
978 *split_len = longer_len - prefix_len;
983 memmove(*split_str, longer_str+prefix_len, longer_len-prefix_len);
1002 uint8_t* str_to_add = key + pos;
1005 if (ldns_radix_str_is_prefix(str_to_add, strlen_to_add,
1006 array->
str, array->
len)) {
1008 uint8_t* split_str = NULL, *dup_str = NULL;
1018 assert(strlen_to_add < array->len);
1020 if (array->
len - strlen_to_add > 1) {
1021 if (!ldns_radix_prefix_remainder(strlen_to_add+1,
1022 array->
str, array->
len, &split_str,
1028 if (strlen_to_add != 0) {
1034 memcpy(dup_str, str_to_add, strlen_to_add);
1037 if (!ldns_radix_array_space(add,
1038 array->
str[strlen_to_add])) {
1056 array->
str = dup_str;
1057 array->
len = strlen_to_add;
1058 }
else if (ldns_radix_str_is_prefix(array->
str, array->
len,
1059 str_to_add, strlen_to_add)) {
1070 uint8_t* split_str = NULL;
1072 assert(array->
len < strlen_to_add);
1073 if (strlen_to_add - array->
len > 1) {
1074 if (!ldns_radix_prefix_remainder(array->
len+1,
1075 str_to_add, strlen_to_add, &split_str,
1081 if (!ldns_radix_array_space(array->
edge,
1082 str_to_add[array->
len])) {
1109 uint8_t* common_str = NULL, *s1 = NULL, *s2 = NULL;
1111 common_len = ldns_radix_str_common(array->
str, array->
len,
1112 str_to_add, strlen_to_add);
1113 assert(common_len < array->len);
1114 assert(common_len < strlen_to_add);
1116 common = ldns_radix_new_node(NULL, (uint8_t*)
"", 0);
1120 if (array->
len - common_len > 1) {
1121 if (!ldns_radix_prefix_remainder(common_len+1,
1122 array->
str, array->
len, &s1, &l1)) {
1127 if (strlen_to_add - common_len > 1) {
1128 if (!ldns_radix_prefix_remainder(common_len+1,
1129 str_to_add, strlen_to_add, &s2, &l2)) {
1136 if (common_len > 0) {
1144 memcpy(common_str, str_to_add, common_len);
1147 if (!ldns_radix_array_space(common, array->
str[common_len]) ||
1148 !ldns_radix_array_space(common, str_to_add[common_len])) {
1174 array->
edge = common;
1175 array->
str = common_str;
1176 array->
len = common_len;
1201 return (memcmp(str1, str2, len1) == 0);
1219 for (i=0; i<max; i++) {
1220 if (str1[i] != str2[i]) {
1240 for (i = 0; i < node->
len; i++) {
1247 next = ldns_radix_next_in_subtree(node->
array[i].
edge);
1272 ldns_radix_last_in_subtree_incl_self(node);
1294 }
else if (node->
data) {
1312 for (i=(
int)(node->
len)-1; i >= 0; i--) {
1317 ldns_radix_last_in_subtree(
1346 }
else if (node->
len == 1 && node->
parent) {
1348 ldns_radix_cleanup_onechild(node);
1350 }
else if (node->
len == 0) {
1355 ldns_radix_node_free(node, NULL);
1360 ldns_radix_cleanup_leaf(node);
1390 assert(parent_index < parent->len);
1403 memcpy(join_str, parent->
array[parent_index].
str,
1407 memmove(join_str + parent->
array[parent_index].
len+1,
1411 parent->
array[parent_index].
str = join_str;
1412 parent->
array[parent_index].
len = join_len;
1413 parent->
array[parent_index].
edge = child;
1416 ldns_radix_node_free(node, NULL);
1432 assert(parent_index < parent->len);
1433 ldns_radix_node_free(node, NULL);
1435 parent->
array[parent_index].
str = NULL;
1436 parent->
array[parent_index].
len = 0;
1437 parent->
array[parent_index].
edge = NULL;
1439 if (parent->
len == 1) {
1440 ldns_radix_node_array_free(parent);
1441 }
else if (parent_index == 0) {
1442 ldns_radix_node_array_free_front(parent);
1444 ldns_radix_node_array_free_end(parent);
1464 for (i=0; i < node->
len; i++) {
1502 while (n < node->len && node->
array[n].
edge == NULL) {
1508 if (n == node->
len) {
1509 ldns_radix_node_array_free(node);
1512 assert(n < node->len);
1513 assert((
int) n <= (255 - (
int) node->
offset));
1518 for (i=0; i < node->
len; i++) {
1523 ldns_radix_array_reduce(node);
1538 while (n < node->len && node->
array[node->
len-1-n].
edge == NULL) {
1544 if (n == node->
len) {
1545 ldns_radix_node_array_free(node);
1548 assert(n < node->len);
1550 ldns_radix_array_reduce(node);
enum ldns_enum_status ldns_status
ldns_radix_node_t * ldns_radix_prev(ldns_radix_node_t *node)
Previous element.
void ldns_radix_init(ldns_radix_t *tree)
Initialize radix tree.
void ldns_radix_traverse_postorder(ldns_radix_node_t *node, void(*func)(ldns_radix_node_t *, void *), void *arg)
Call function for all nodes in the tree, such that leaf nodes are called before parent nodes.
ldns_status ldns_radix_join(ldns_radix_t *tree1, ldns_radix_t *tree2)
Join two radix trees.
void ldns_radix_free(ldns_radix_t *tree)
Free radix tree.
ldns_status ldns_radix_split(ldns_radix_t *tree1, size_t num, ldns_radix_t **tree2)
Split a radix tree intwo.
ldns_radix_node_t * ldns_radix_last(const ldns_radix_t *tree)
Get the last element in the tree.
ldns_radix_t * ldns_radix_create(void)
Create a new radix tree.
ldns_radix_node_t * ldns_radix_search(ldns_radix_t *tree, const uint8_t *key, radix_strlen_t len)
Search data in the tree.
ldns_radix_node_t * ldns_radix_next(ldns_radix_node_t *node)
Next element.
ldns_status ldns_radix_insert(ldns_radix_t *tree, uint8_t *key, radix_strlen_t len, void *data)
Insert data into the tree.
ldns_radix_node_t * ldns_radix_first(const ldns_radix_t *tree)
Get the first element in the tree.
int ldns_radix_find_less_equal(ldns_radix_t *tree, const uint8_t *key, radix_strlen_t len, ldns_radix_node_t **result)
Search data in the tree, and if not found, find the closest smaller element in the tree.
void ldns_radix_printf(FILE *fd, const ldns_radix_t *tree)
Print radix tree.
void * ldns_radix_delete(ldns_radix_t *tree, const uint8_t *key, radix_strlen_t len)
Delete data from the tree.
Radix node select edge array.
ldns_radix_node_t * edge
Node that deals with byte+str.
radix_strlen_t len
Length of additional string for this edge.
uint8_t * str
Additional string after the selection byte for this edge.
ldns_radix_node_t * parent
Parent node.
uint16_t offset
Offset of the array.
radix_strlen_t klen
Key length corresponding to this node.
ldns_radix_array_t * array
Select edge array.
uint16_t len
Length of the array.
uint16_t capacity
Capacity of the array.
void * data
Data corresponding to this node.
uint8_t parent_index
Index in the parent node select edge array.
uint8_t * key
Key corresponding to this node.
ldns_radix_node_t * root
Root.
size_t count
Number of nodes in tree.
#define LDNS_MALLOC(type)
Memory management macros.
#define LDNS_XMALLOC(type, count)