#include "basics.h"
-struct tree_node *tree_search(void *key, struct tree_node **rootp,
- int (*compare)(const void *, const void *),
- int insert)
+struct tree_node *tree_search(struct tree_node *tree,
+ void *key,
+ int (*compare)(const void *, const void *))
{
int res;
+ if (!tree)
+ return NULL;
+ res = compare(key, tree->key);
+ if (res < 0)
+ return tree_search(tree->left, key, compare);
+ else if (res > 0)
+ return tree_search(tree->right, key, compare);
+ return tree;
+}
+
+struct tree_node *tree_insert(struct tree_node **rootp,
+ void *key,
+ int (*compare)(const void *, const void *))
+{
+ int res;
+
if (!*rootp) {
- if (!insert) {
+ struct tree_node *n;
+
+ REFTABLE_CALLOC_ARRAY(n, 1);
+ if (!n)
return NULL;
- } else {
- struct tree_node *n;
- REFTABLE_CALLOC_ARRAY(n, 1);
- n->key = key;
- *rootp = n;
- return *rootp;
- }
+
+ n->key = key;
+ *rootp = n;
+ return *rootp;
}
res = compare(key, (*rootp)->key);
if (res < 0)
- return tree_search(key, &(*rootp)->left, compare, insert);
+ return tree_insert(&(*rootp)->left, key, compare);
else if (res > 0)
- return tree_search(key, &(*rootp)->right, compare, insert);
+ return tree_insert(&(*rootp)->right, key, compare);
return *rootp;
}
struct tree_node *left, *right;
};
-/* looks for `key` in `rootp` using `compare` as comparison function. If insert
- * is set, insert the key if it's not found. Else, return NULL.
+/*
+ * Search the tree for the node matching the given key using `compare` as
+ * comparison function. Returns the node whose key matches or `NULL` in case
+ * the key does not exist in the tree.
+ */
+struct tree_node *tree_search(struct tree_node *tree,
+ void *key,
+ int (*compare)(const void *, const void *));
+
+/*
+ * Insert a node into the tree. Returns the newly inserted node if the key does
+ * not yet exist. Otherwise it returns the preexisting node. Returns `NULL`
+ * when allocating the new node fails.
*/
-struct tree_node *tree_search(void *key, struct tree_node **rootp,
- int (*compare)(const void *, const void *),
- int insert);
+struct tree_node *tree_insert(struct tree_node **rootp,
+ void *key,
+ int (*compare)(const void *, const void *));
/* performs an infix walk of the tree. */
void infix_walk(struct tree_node *t, void (*action)(void *arg, void *key),
struct obj_index_tree_node *key;
struct tree_node *node;
- node = tree_search(&want, &w->obj_index_tree,
- &obj_index_tree_node_compare, 0);
+ node = tree_search(w->obj_index_tree, &want, &obj_index_tree_node_compare);
if (!node) {
struct obj_index_tree_node empty = OBJ_INDEX_TREE_NODE_INIT;
strbuf_reset(&key->hash);
strbuf_addbuf(&key->hash, hash);
- tree_search((void *)key, &w->obj_index_tree,
- &obj_index_tree_node_compare, 1);
+ tree_insert(&w->obj_index_tree, key,
+ &obj_index_tree_node_compare);
} else {
key = node->key;
}
* values[1] and values[10] (inclusive) in the tree.
*/
do {
- nodes[i] = tree_search(&values[i], &root, &t_compare, 1);
+ nodes[i] = tree_insert(&root, &values[i], &t_compare);
+ check(nodes[i] != NULL);
i = (i * 7) % 11;
} while (i != 1);
for (i = 1; i < ARRAY_SIZE(nodes); i++) {
check_pointer_eq(&values[i], nodes[i]->key);
- check_pointer_eq(nodes[i], tree_search(&values[i], &root, &t_compare, 0));
+ check_pointer_eq(nodes[i], tree_search(root, &values[i], &t_compare));
}
- check(!tree_search(values, &root, t_compare, 0));
+ check(!tree_search(root, values, t_compare));
tree_free(root);
}
size_t count = 0;
do {
- tree_search(&values[i], &root, t_compare, 1);
+ struct tree_node *node = tree_insert(&root, &values[i], t_compare);
+ check(node != NULL);
i = (i * 7) % 11;
count++;
} while (i != 1);