mirror of
https://github.com/git/git.git
synced 2024-11-23 09:56:28 +08:00
51afc709dc
The tree interfaces of the reftable library handle both insertion and searching of tree nodes with a single function, where the behaviour is altered between the two via an `insert` bit. This makes it quit awkward to handle allocation failures because on inserting we'd have to check for `NULL` pointers and return an error, whereas on searching entries we don't have to handle it as an allocation error. Split up concerns of this function into two separate functions, one for inserting entries and one for searching entries. This makes it easy for us to check for allocation errors as `tree_insert()` should never return a `NULL` pointer now. Adapt callers accordingly. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
75 lines
1.4 KiB
C
75 lines
1.4 KiB
C
/*
|
|
Copyright 2020 Google LLC
|
|
|
|
Use of this source code is governed by a BSD-style
|
|
license that can be found in the LICENSE file or at
|
|
https://developers.google.com/open-source/licenses/bsd
|
|
*/
|
|
|
|
#include "system.h"
|
|
#include "tree.h"
|
|
|
|
#include "basics.h"
|
|
|
|
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) {
|
|
struct tree_node *n;
|
|
|
|
REFTABLE_CALLOC_ARRAY(n, 1);
|
|
if (!n)
|
|
return NULL;
|
|
|
|
n->key = key;
|
|
*rootp = n;
|
|
return *rootp;
|
|
}
|
|
|
|
res = compare(key, (*rootp)->key);
|
|
if (res < 0)
|
|
return tree_insert(&(*rootp)->left, key, compare);
|
|
else if (res > 0)
|
|
return tree_insert(&(*rootp)->right, key, compare);
|
|
return *rootp;
|
|
}
|
|
|
|
void infix_walk(struct tree_node *t, void (*action)(void *arg, void *key),
|
|
void *arg)
|
|
{
|
|
if (t->left)
|
|
infix_walk(t->left, action, arg);
|
|
action(arg, t->key);
|
|
if (t->right)
|
|
infix_walk(t->right, action, arg);
|
|
}
|
|
|
|
void tree_free(struct tree_node *t)
|
|
{
|
|
if (!t)
|
|
return;
|
|
if (t->left)
|
|
tree_free(t->left);
|
|
if (t->right)
|
|
tree_free(t->right);
|
|
reftable_free(t);
|
|
}
|