/*
* Copyright (c) 2002, 2004 Sendmail, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the sendmail distribution.
*
* $Id: tree.h,v 1.17 2005/06/16 00:09:35 ca Exp $
*/
#ifndef SM_TREE_H
#define SM_TREE_H 1
#include "sm/generic.h"
#include "sm/error.h"
#include "sm/rpool.h"
/*
** Balanced tree data structure
*/
/* default data types, can be overridden */
#ifndef Tree_Key
# define Tree_Key const char *
#endif
#ifndef Tree_Data
# define Tree_Data void *
#endif
typedef Tree_Data sm_tree_data_T;
typedef Tree_Key sm_tree_key_T;
typedef int (*sm_tree_compare_T)(sm_tree_key_T, sm_tree_key_T, uint);
typedef struct sm_tree_node_S sm_tree_node_T, *sm_tree_node_P;
struct sm_tree_node_S
{
sm_tree_node_P sm_tree_parent;
sm_tree_node_P sm_tree_left;
sm_tree_node_P sm_tree_right;
int sm_tree_balance;
sm_tree_key_T sm_tree_key;
uint sm_tree_key_len;
sm_tree_data_T sm_tree_data;
};
typedef struct sm_tree sm_tree_T, *sm_tree_P;
struct sm_tree
{
sm_tree_node_P sm_tree_root;
sm_tree_compare_T sm_tree_compare;
sm_rpool_P sm_tree_rpool;
uint sm_tree_limit; /* max # of entries */
uint sm_tree_used; /* current # of entries */
#if SM_TREE_STAT
unsigned long sm_tree_rotates;
#endif
};
typedef sm_ret_T (*sm_tree_walk_F)(sm_tree_P, sm_tree_node_P, void *);
/*
** Implementation note:
** if we want to limit the size of the tree, then we may also want to
** reuse nodes: we can put them into a list in the tree structure,
** and get them from there if we need to allocate one.
** We could also create a fixed size tree with an array of nodes
** that are "just" properly linked (in that case, the pointers could
** be "reduced" to indices, but that's probably not worth the extra
** coding effort).
*/
/*
** this function must be provided externally, results:
** == 0: keys are identical
** < 0: first key less than second key
** > 0: first key greather than second key
** the function must implement a transitive relation.
*/
/* internal */
int sm_tree_insert2(sm_tree_P _tree, sm_tree_node_P *_node, sm_tree_node_P _recn, sm_tree_key_T _key, uint _len, sm_tree_data_T _data);
int sm_tree_remove2(sm_tree_P _tree, sm_tree_node_P *_node, sm_tree_node_P, sm_tree_key_T _key, uint _len);
/* available functions */
sm_tree_P sm_tree_create(sm_rpool_P _rpool, uint _limit, sm_tree_compare_T _tree_compare);
sm_ret_T sm_tree_destroy(sm_tree_P _tree);
sm_ret_T sm_tree_node_alloc(sm_tree_P _tree, sm_tree_node_P *_n, sm_tree_key_T _key, uint _len, sm_tree_data_T _data);
sm_ret_T sm_tree_node_free(sm_tree_P _tree, sm_tree_node_P _n);
int sm_tree_add(sm_tree_P _tree, sm_tree_key_T _key, uint _len, sm_tree_data_T _data);
int sm_tree_rm(sm_tree_P _tree, sm_tree_key_T _key, uint _len);
sm_tree_node_P sm_tree_first(sm_tree_P _tree);
sm_tree_node_P sm_tree_next(sm_tree_P _tree, sm_tree_node_P _node);
sm_tree_node_P sm_tree_lookup(sm_tree_P _tree, sm_tree_key_T _key, uint _len);
uint sm_tree_depth(sm_tree_node_P);
sm_ret_T sm_tree_walk(sm_tree_P _tree, sm_tree_walk_F _fct, void *_ctx);
#define sm_tree_assign_key(dst, src) (dst) = (src)
#define sm_tree_assign_data(dst, src) (dst) = (src)
#endif /* SM_TREE_H */
syntax highlighted by Code2HTML, v. 0.9.1