52static 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,
 
   63static 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++) {
 
 
  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_t * ldns_radix_create(void)
Create a new radix tree.
void ldns_radix_init(ldns_radix_t *tree)
Initialize radix tree.
ldns_radix_node_t * ldns_radix_next(ldns_radix_node_t *node)
Next element.
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.
ldns_radix_node_t * ldns_radix_first(const ldns_radix_t *tree)
Get the first element in the tree.
void * ldns_radix_delete(ldns_radix_t *tree, const uint8_t *key, radix_strlen_t len)
Delete data from the tree.
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_search(ldns_radix_t *tree, const uint8_t *key, radix_strlen_t len)
Search data in the tree.
ldns_radix_node_t * ldns_radix_last(const ldns_radix_t *tree)
Get the last element in the tree.
ldns_status ldns_radix_insert(ldns_radix_t *tree, uint8_t *key, radix_strlen_t len, void *data)
Insert data into 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.
ldns_radix_node_t * ldns_radix_prev(ldns_radix_node_t *node)
Previous element.
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)