#include "avl.h"
#include "list.h"
-#define list_merge(_head, _list) list_merge(_list, _head)
-#define list_is_last(_head, _list) list_is_last(_list, _head)
-#define list_is_first(_head, _list) list_is_first(_list, _head)
-
/**
* internal type save inline function to calculate the maximum of
* to integers without macro implementation.
void
avl_init(struct avl_tree *tree, avl_tree_comp comp, bool allow_dups, void *ptr)
{
- list_init_head(&tree->list_head);
+ INIT_LIST_HEAD(&tree->list_head);
tree->root = NULL;
tree->count = 0;
tree->comp = comp;
tree->cmp_ptr = ptr;
}
-/**
- * Internal function to support returning the element from a avl tree query
- * @param tree pointer to avl tree
- * @param key pointer to key
- * @param offset offset of node inside the embedded struct
- * @param mode mode of lookup operation (less equal, equal or greater equal)
- * @param pointer to elemen, NULL if no fitting one was found
- */
-void *
-__avl_find_element(struct avl_tree *tree, const void *key, size_t offset, enum avl_find_mode mode) {
- void *node = NULL;
-
- switch (mode) {
- case AVL_FIND_EQUAL:
- node = avl_find(tree, key);
- break;
- case AVL_FIND_LESSEQUAL:
- node = avl_find_lessequal(tree, key);
- break;
- case AVL_FIND_GREATEREQUAL:
- node = avl_find_greaterequal(tree, key);
- break;
- }
- return node == NULL ? NULL : (((char *)node) - offset);
+static inline struct avl_node *avl_next(struct avl_node *node)
+{
+ return list_entry(node->list.next, struct avl_node, list);
}
/**
* this key exists.
*/
struct avl_node *
-avl_find(struct avl_tree *tree, const void *key)
+avl_find(const struct avl_tree *tree, const void *key)
{
struct avl_node *node;
int diff;
* key less or equal specified key exists.
*/
struct avl_node *
-avl_find_lessequal(struct avl_tree *tree, const void *key) {
+avl_find_lessequal(const struct avl_tree *tree, const void *key) {
struct avl_node *node, *next;
int diff;
/* go left as long as key<node.key */
while (diff < 0) {
- if (list_is_first(&tree->list_head, &node->list)) {
+ if (list_is_first(&node->list, &tree->list_head)) {
return NULL;
}
next = node;
while (diff >= 0) {
node = next;
- if (list_is_last(&tree->list_head, &node->list)) {
+ if (list_is_last(&node->list, &tree->list_head)) {
break;
}
* key greater or equal specified key exists.
*/
struct avl_node *
-avl_find_greaterequal(struct avl_tree *tree, const void *key) {
+avl_find_greaterequal(const struct avl_tree *tree, const void *key) {
struct avl_node *node, *next;
int diff;
/* go right as long as key>node.key */
while (diff > 0) {
- if (list_is_last(&tree->list_head, &node->list)) {
+ if (list_is_last(&node->list, &tree->list_head)) {
return NULL;
}
next = node;
while (diff <= 0) {
node = next;
- if (list_is_first(&tree->list_head, &node->list)) {
+ if (list_is_first(&node->list, &tree->list_head)) {
break;
}
new->leader = true;
if (tree->root == NULL) {
- list_add_head(&tree->list_head, &new->list);
+ list_add(&new->list, &tree->list_head);
tree->root = new;
tree->count = 1;
return 0;
last = node;
- while (!list_is_last(&tree->list_head, &last->list)) {
- next = list_next_element(last, list);
+ while (!list_is_last(&last->list, &tree->list_head)) {
+ next = avl_next(last);
if (next->leader) {
break;
}
struct avl_node *right;
if (node->leader) {
if (tree->allow_dups
- && !list_is_last(&tree->list_head, &node->list)
- && !(next = list_next_element(node, list))->leader) {
+ && !list_is_last(&node->list, &tree->list_head)
+ && !(next = avl_next(node))->leader) {
next->leader = true;
next->balance = node->balance;
static void
avl_insert_before(struct avl_tree *tree, struct avl_node *pos_node, struct avl_node *node)
{
- list_add_before(&pos_node->list, &node->list);
+ list_add_tail(&node->list, &pos_node->list);
tree->count++;
}
static void
avl_insert_after(struct avl_tree *tree, struct avl_node *pos_node, struct avl_node *node)
{
- list_add_after(&pos_node->list, &node->list);
+ list_add(&node->list, &pos_node->list);
tree->count++;
}
static void
avl_remove(struct avl_tree *tree, struct avl_node *node)
{
- list_remove(&node->list);
+ list_del(&node->list);
tree->count--;
}