/* Find entry */
void *silc_avl_tree_find(SilcTree *tree, void *entry,
- SilcTreeCompare compare, void *context)
+ SilcCompare compare, void *context)
{
SilcTreeHeader *h;
- SilcTreeCompare cmp = compare ? compare : tree->compare;
+ SilcCompare cmp = compare ? compare : tree->compare;
void *cmp_context = compare ? context : tree->context;
int ret;
h = tree->root;
while (h) {
ret = cmp(entry, SILC_TREE_GET_ENTRY(tree, h), cmp_context);
- if (!ret) {
+ if (ret == SILC_COMPARE_EQUAL_TO) {
SILC_LOG_DEBUG(("Found %p", SILC_TREE_GET_ENTRY(tree, h)));
return SILC_TREE_GET_ENTRY(tree, h);
}
+ if (ret == SILC_COMPARE_STOP)
+ return NULL;
h = ret > 0 ? h->right : h->left;
}
}
ret = tree->compare(entry, SILC_TREE_GET_ENTRY(tree, h), tree->context);
- if (!tree->duplicates && ret == 0) {
+ if (!tree->duplicates && ret == SILC_COMPARE_EQUAL_TO) {
silc_set_errno(SILC_ERR_ALREADY_EXISTS);
return FALSE;
}
/* Duplicate entry, add to list */
- if (ret == 0) {
+ if (ret == SILC_COMPARE_EQUAL_TO) {
q = SILC_TREE_GET_HEADER(tree, entry);
q->duplicate = TRUE;
q->parent = h;
***/
typedef struct SilcTreeHeaderStruct SilcTreeHeader;
-/****f* silcutil/SilcTreeCompare
- *
- * SYNOPSIS
- *
- * typedef int (*SilcTreeCompare)(void *entry1, void *entry2,
- * void *context);
- *
- * DESCRIPTION
- *
- * Callback function of this type is called to compare values in the
- * tree. If the `entry1' is smaller, equal to or greater than `entry2'
- * this function must return less than, equal to, or greater than zero,
- * respectively.
- *
- ***/
-typedef int (*SilcTreeCompare)(void *entry1, void *entry2, void *context);
-
/****d* silcutil/SilcTreeType
*
* NAME
* SYNOPSIS
*
* SilcBool silc_tree_init(SilcTree tree, SilcTreeType type,
- * SilcTreeCompare compare, void *context,
+ * SilcCompare compare, void *context,
* SilcUInt16 offset, SilcBool duplicates);
*
* DESCRIPTION
__silc_tree_init(&(tree), type, compare, context, offset, d)
static inline
SilcBool __silc_tree_init(SilcTree *tree,
- SilcTreeType type, SilcTreeCompare compare,
+ SilcTreeType type, SilcCompare compare,
void *context, SilcUInt32 offset,
SilcBool duplicates)
{
* DESCRIPTION
*
* Add `entry' to the `tree'. Returns TRUE after the entry has been
- * added to the tree. If the `tree' does not allocate duplicate entries
+ * added to the tree. If the `tree' does not allow duplicate entries
* this will return FALSE if same value as `entry' is already in the
* tree.
*
* SYNOPSIS
*
* void *silc_tree_find_ext(SilcTree *tree, void *entry,
- * SilcTreeCompare compare, void *context);
+ * SilcCompare compare, void *context);
*
* DESCRIPTION
*
struct SilcTreeOpsStruct {
SilcBool (*add)(SilcTree *tree, void *entry);
SilcBool (*del)(SilcTree *tree, void *entry);
- void *(*find)(SilcTree *tree, void *entry, SilcTreeCompare compare,
+ void *(*find)(SilcTree *tree, void *entry, SilcCompare compare,
void *context);
};
/* Generic tree header, present in each entry in tree */
struct SilcTreeHeaderStruct {
- struct SilcTreeHeaderStruct *parent;
- struct SilcTreeHeaderStruct *left;
- struct SilcTreeHeaderStruct *right;
- struct SilcTreeHeaderStruct *dup;
+ struct SilcTreeHeaderStruct *parent; /* Parent of this node */
+ struct SilcTreeHeaderStruct *left; /* Left leaft */
+ struct SilcTreeHeaderStruct *right; /* Right leaft */
+ struct SilcTreeHeaderStruct *dup; /* Duplicates, middle leaf, etc. */
SilcInt16 t;
unsigned int duplicate : 1;
};
struct SilcTreeStruct {
const struct SilcTreeOpsStruct *ops;
SilcTreeHeader *root;
- SilcTreeCompare compare;
+ SilcCompare compare;
void *context;
SilcUInt32 count;
unsigned int offset : 31;
#define SILC_TREE_GET_ENTRY(tree, pos) \
((void *)((unsigned char *)(pos) - tree->offset))
+/* Low level undocumented macro API for creating three-leaf binary trees. */
+
+#define silc_tree_set_root(tree, root) \
+ (tree).root = SILC_TREE_GET_HEADER(&(tree), (root))
+#define silc_tree_set_parent(tree, at, parent) \
+ (at)->parent = SILC_TREE_GET_HEADER(&(tree), (parent))
+#define silc_tree_set_left(tree, at, left) \
+ (at)->left = SILC_TREE_GET_HEADER(&(tree), (left))
+#define silc_tree_set_middle(tree, at, middle) \
+ (at)->dup = SILC_TREE_GET_HEADER(&(tree), (middle))
+#define silc_tree_set_right(tree, at, right) \
+ (at)->right = SILC_TREE_GET_HEADER(&(tree), (right))
+
+#define silc_tree_get_root(tree) \
+ SILC_TREE_GET_ENTRY(&(tree), (tree).root)
+#define silc_tree_get_parent(tree, at) \
+ SILC_TREE_GET_ENTRY(&(tree), (at)->parent)
+#define silc_tree_get_left(tree, at) \
+ SILC_TREE_GET_ENTRY(&(tree), (at)->left)
+#define silc_tree_get_middle(tree, at) \
+ SILC_TREE_GET_ENTRY(&(tree), (at)->middle)
+#define silc_tree_get_right(tree, at) \
+ SILC_TREE_GET_ENTRY(&(tree), (at)->right)
+
#endif /* SILCTREE_I_H */