libubox
C utility functions for OpenWrt.
avl.h File Reference
#include <stddef.h>
#include <stdbool.h>
#include "list.h"

Go to the source code of this file.

Data Structures

struct  avl_node
 
struct  avl_tree
 

Macros

#define EXPORT(sym)   sym
 
#define AVL_TREE_INIT(_name, _comp, _allow_dups, _cmp_ptr)
 
#define AVL_TREE(_name, _comp, _allow_dups, _cmp_ptr)
 
#define avl_find_element(tree, key, element, node_element)    ((__typeof__(*(element)) *)__avl_find_element(tree, key, offsetof(typeof(*(element)), node_element), AVL_FIND_EQUAL))
 
#define avl_find_le_element(tree, key, element, node_element)    ((__typeof__(*(element)) *)__avl_find_element(tree, key, offsetof(typeof(*(element)), node_element), AVL_FIND_LESSEQUAL))
 
#define avl_find_ge_element(tree, key, element, node_element)    ((__typeof__(*(element)) *)__avl_find_element(tree, key, offsetof(typeof(*(element)), node_element), AVL_FIND_GREATEREQUAL))
 
#define avl_first_element(tree, element, node_member)    container_of((tree)->list_head.next, __typeof__(*(element)), node_member.list)
 
#define avl_last_element(tree, element, node_member)    container_of((tree)->list_head.prev, __typeof__(*(element)), node_member.list)
 
#define avl_next_element(element, node_member)    container_of((&(element)->node_member.list)->next, __typeof__(*(element)), node_member.list)
 
#define avl_prev_element(element, node_member)    container_of((&(element)->node_member.list)->prev, __typeof__(*(element)), node_member.list)
 
#define avl_for_element_range(first, last, element, node_member)
 
#define avl_for_element_range_reverse(first, last, element, node_member)
 
#define avl_for_each_element(tree, element, node_member)
 
#define avl_for_each_element_reverse(tree, element, node_member)
 
#define avl_for_element_to_last(tree, first, element, node_member)    avl_for_element_range(first, avl_last_element(tree, element, node_member), element, node_member)
 
#define avl_for_element_to_last_reverse(tree, first, element, node_member)    avl_for_element_range_reverse(first, avl_last_element(tree, element, node_member), element, node_member)
 
#define avl_for_first_to_element(tree, last, element, node_member)    avl_for_element_range(avl_first_element(tree, element, node_member), last, element, node_member)
 
#define avl_for_first_to_element_reverse(tree, last, element, node_member)    avl_for_element_range_reverse(avl_first_element(tree, element, node_member), last, element, node_member)
 
#define avl_for_element_range_safe(first_element, last_element, element, node_member, ptr)
 
#define avl_for_element_range_reverse_safe(first_element, last_element, element, node_member, ptr)
 
#define avl_for_each_element_safe(tree, element, node_member, ptr)
 
#define avl_for_each_element_reverse_safe(tree, element, node_member, ptr)
 
#define avl_remove_all_elements(tree, element, node_member, ptr)
 

Typedefs

typedef int(* avl_tree_comp) (const void *k1, const void *k2, void *ptr)
 

Enumerations

enum  avl_find_mode { AVL_FIND_EQUAL , AVL_FIND_LESSEQUAL , AVL_FIND_GREATEREQUAL }
 

Functions

void avl_init (struct avl_tree *, avl_tree_comp, bool, void *)
 
struct avl_nodeavl_find (const struct avl_tree *, const void *)
 
struct avl_nodeavl_find_greaterequal (const struct avl_tree *tree, const void *key)
 
struct avl_nodeavl_find_lessequal (const struct avl_tree *tree, const void *key)
 
int avl_insert (struct avl_tree *, struct avl_node *)
 
void avl_delete (struct avl_tree *, struct avl_node *)
 
static bool avl_is_first (struct avl_tree *tree, struct avl_node *node)
 
static bool avl_is_last (struct avl_tree *tree, struct avl_node *node)
 
static bool avl_is_empty (struct avl_tree *tree)
 
static void * __avl_find_element (const struct avl_tree *tree, const void *key, size_t offset, enum avl_find_mode mode)
 

Macro Definition Documentation

◆ avl_find_element

#define avl_find_element (   tree,
  key,
  element,
  node_element 
)     ((__typeof__(*(element)) *)__avl_find_element(tree, key, offsetof(typeof(*(element)), node_element), AVL_FIND_EQUAL))
Parameters
treepointer to avl-tree
keypointer to key
elementpointer to a node element (don't need to be initialized)
node_elementname of the avl_node element inside the larger struct
Returns
pointer to tree element with the specified key, NULL if no element was found

Definition at line 240 of file avl.h.

◆ avl_find_ge_element

#define avl_find_ge_element (   tree,
  key,
  element,
  node_element 
)     ((__typeof__(*(element)) *)__avl_find_element(tree, key, offsetof(typeof(*(element)), node_element), AVL_FIND_GREATEREQUAL))
Parameters
treepointer to avl-tree
keypointer to specified key
elementpointer to a node element (don't need to be initialized)
node_elementname of the avl_node element inside the larger struct return pointer to first tree element with greater or equal key than specified key, NULL if no element was found

Definition at line 266 of file avl.h.

◆ avl_find_le_element

#define avl_find_le_element (   tree,
  key,
  element,
  node_element 
)     ((__typeof__(*(element)) *)__avl_find_element(tree, key, offsetof(typeof(*(element)), node_element), AVL_FIND_LESSEQUAL))
Parameters
treepointer to avl-tree
keypointer to specified key
elementpointer to a node element (don't need to be initialized)
node_elementname of the avl_node element inside the larger struct return pointer to last tree element with less or equal key than specified key, NULL if no element was found

Definition at line 253 of file avl.h.

◆ avl_first_element

#define avl_first_element (   tree,
  element,
  node_member 
)     container_of((tree)->list_head.next, __typeof__(*(element)), node_member.list)

This function must not be called for an empty tree

Parameters
treepointer to avl-tree
elementpointer to a node element (don't need to be initialized)
node_membername of the avl_node element inside the larger struct
Returns
pointer to the first element of the avl_tree (automatically converted to type 'element')

Definition at line 280 of file avl.h.

◆ avl_for_each_element

#define avl_for_each_element (   tree,
  element,
  node_member 
)
Value:
avl_for_element_range(avl_first_element(tree, element, node_member), \
avl_last_element(tree, element, node_member), \
element, node_member)
#define avl_for_element_range(first, last, element, node_member)
Definition: avl.h:333
#define avl_first_element(tree, element, node_member)
Definition: avl.h:280
#define avl_last_element(tree, element, node_member)
Definition: avl.h:292

Loop over all elements of an avl_tree, used similar to a for() command. This loop should not be used if elements are removed from the tree during the loop.

Parameters
treepointer to avl-tree
elementpointer to a node of the tree, this element will contain the current node of the tree during the loop
node_membername of the avl_node element inside the larger struct

Definition at line 366 of file avl.h.

◆ avl_for_each_element_reverse

#define avl_for_each_element_reverse (   tree,
  element,
  node_member 
)
Value:
avl_for_element_range_reverse(avl_first_element(tree, element, node_member), \
avl_last_element(tree, element, node_member), \
element, node_member)
#define avl_for_element_range_reverse(first, last, element, node_member)
Definition: avl.h:350

Loop over all elements of an avl_tree backwards, used similar to a for() command. This loop should not be used if elements are removed from the tree during the loop.

Parameters
treepointer to avl-tree
elementpointer to a node of the tree, this element will contain the current node of the tree during the loop
node_membername of the avl_node element inside the larger struct

Definition at line 382 of file avl.h.

◆ avl_for_each_element_reverse_safe

#define avl_for_each_element_reverse_safe (   tree,
  element,
  node_member,
  ptr 
)
Value:
avl_last_element(tree, element, node_member), \
element, node_member, ptr)
#define avl_for_element_range_reverse_safe(first_element, last_element, element, node_member, ptr)
Definition: avl.h:484

Loop over all elements of an avl_tree backwards, used similar to a for() command. This loop can be used if the current element might be removed from the tree during the loop. Other elements should not be removed during the loop.

Parameters
treepointer to avl-tree
elementpointer to a node of the tree, this element will contain the current node of the tree during the loop
node_membername of the avl_node element inside the larger struct
ptrpointer to a tree element which is used to store the next node during the loop

Definition at line 522 of file avl.h.

◆ avl_for_each_element_safe

#define avl_for_each_element_safe (   tree,
  element,
  node_member,
  ptr 
)
Value:
avl_for_element_range_safe(avl_first_element(tree, element, node_member), \
avl_last_element(tree, element, node_member), \
element, node_member, ptr)
#define avl_for_element_range_safe(first_element, last_element, element, node_member, ptr)
Definition: avl.h:466

Loop over all elements of an avl_tree, used similar to a for() command. This loop can be used if the current element might be removed from the tree during the loop. Other elements should not be removed during the loop.

Parameters
treepointer to avl-tree
elementpointer to a node of the tree, this element will contain the current node of the tree during the loop
node_membername of the avl_node element inside the larger struct
ptrpointer to a tree element which is used to store the next node during the loop

Definition at line 503 of file avl.h.

◆ avl_for_element_range

#define avl_for_element_range (   first,
  last,
  element,
  node_member 
)
Value:
for (element = (first); \
element->node_member.list.prev != &(last)->node_member.list; \
element = avl_next_element(element, node_member))
#define avl_next_element(element, node_member)
Definition: avl.h:305

Loop over a block of elements of a tree, used similar to a for() command. This loop should not be used if elements are removed from the tree during the loop.

Parameters
firstpointer to first element of loop
lastpointer to last element of loop
elementpointer to a node of the tree, this element will contain the current node of the list during the loop
node_membername of the avl_node element inside the larger struct

Definition at line 333 of file avl.h.

◆ avl_for_element_range_reverse

#define avl_for_element_range_reverse (   first,
  last,
  element,
  node_member 
)
Value:
for (element = (last); \
element->node_member.list.next != &(first)->node_member.list; \
element = avl_prev_element(element, node_member))
#define avl_prev_element(element, node_member)
Definition: avl.h:318

Loop over a block of elements of a tree backwards, used similar to a for() command. This loop should not be used if elements are removed from the tree during the loop.

Parameters
firstpointer to first element of loop
lastpointer to last element of loop
elementpointer to a node of the tree, this element will contain the current node of the list during the loop
node_membername of the avl_node element inside the larger struct

Definition at line 350 of file avl.h.

◆ avl_for_element_range_reverse_safe

#define avl_for_element_range_reverse_safe (   first_element,
  last_element,
  element,
  node_member,
  ptr 
)
Value:
for (element = (last_element), ptr = avl_prev_element(last_element, node_member); \
element->node_member.list.next != &(first_element)->node_member.list; \
element = ptr, ptr = avl_prev_element(ptr, node_member))

Loop over a block of elements of a tree backwards, used similar to a for() command. This loop can be used if the current element might be removed from the tree during the loop. Other elements should not be removed during the loop.

Parameters
first_elementfirst element of range (will be last returned by the loop)
last_elementlast element of range (will be first returned by the loop)
elementiterator pointer to node element struct
node_membername of avl_node within node element struct
ptrpointer to node element struct which is used to store the previous node during the loop

Definition at line 484 of file avl.h.

◆ avl_for_element_range_safe

#define avl_for_element_range_safe (   first_element,
  last_element,
  element,
  node_member,
  ptr 
)
Value:
for (element = (first_element), ptr = avl_next_element(first_element, node_member); \
element->node_member.list.prev != &(last_element)->node_member.list; \
element = ptr, ptr = avl_next_element(ptr, node_member))

Loop over a block of nodes of a tree, used similar to a for() command. This loop can be used if the current element might be removed from the tree during the loop. Other elements should not be removed during the loop.

Parameters
first_elementfirst element of loop
last_elementlast element of loop
elementiterator pointer to tree element struct
node_membername of avl_node within tree element struct
ptrpointer to tree element struct which is used to store the next node during the loop

Definition at line 466 of file avl.h.

◆ avl_for_element_to_last

#define avl_for_element_to_last (   tree,
  first,
  element,
  node_member 
)     avl_for_element_range(first, avl_last_element(tree, element, node_member), element, node_member)

Loop over a block of elements of a tree, used similar to a for() command. This loop should not be used if elements are removed from the tree during the loop. The loop runs from the element 'first' to the end of the tree.

Parameters
treepointer to avl-tree
firstpointer to first element of loop
elementpointer to a node of the tree, this element will contain the current node of the list during the loop
node_membername of the avl_node element inside the larger struct

Definition at line 400 of file avl.h.

◆ avl_for_element_to_last_reverse

#define avl_for_element_to_last_reverse (   tree,
  first,
  element,
  node_member 
)     avl_for_element_range_reverse(first, avl_last_element(tree, element, node_member), element, node_member)

Loop over a block of elements of a tree backwards, used similar to a for() command. This loop should not be used if elements are removed from the tree during the loop. The loop runs from the element 'first' to the end of the tree.

Parameters
treepointer to avl-tree
firstpointer to first element of loop
elementpointer to a node of the tree, this element will contain the current node of the list during the loop
node_membername of the avl_node element inside the larger struct

Definition at line 417 of file avl.h.

◆ avl_for_first_to_element

#define avl_for_first_to_element (   tree,
  last,
  element,
  node_member 
)     avl_for_element_range(avl_first_element(tree, element, node_member), last, element, node_member)

Loop over a block of elements of a tree, used similar to a for() command. This loop should not be used if elements are removed from the tree during the loop. The loop runs from the start of the tree to the element 'last'.

Parameters
treepointer to avl-tree
lastpointer to last element of loop
elementpointer to a node of the tree, this element will contain the current node of the list during the loop
node_membername of the avl_node element inside the larger struct

Definition at line 433 of file avl.h.

◆ avl_for_first_to_element_reverse

#define avl_for_first_to_element_reverse (   tree,
  last,
  element,
  node_member 
)     avl_for_element_range_reverse(avl_first_element(tree, element, node_member), last, element, node_member)

Loop over a block of elements of a tree backwards, used similar to a for() command. This loop should not be used if elements are removed from the tree during the loop. The loop runs from the start of the tree to the element 'last'.

Parameters
treepointer to avl-tree
lastpointer to last element of loop
elementpointer to a node of the tree, this element will contain the current node of the list during the loop
node_membername of the avl_node element inside the larger struct

Definition at line 450 of file avl.h.

◆ avl_last_element

#define avl_last_element (   tree,
  element,
  node_member 
)     container_of((tree)->list_head.prev, __typeof__(*(element)), node_member.list)
Parameters
treepointer to tree
elementpointer to a node struct that contains the avl_node (don't need to be initialized)
node_membername of the avl_node element inside the larger struct
Returns
pointer to the last element of the avl_tree (automatically converted to type 'element')

Definition at line 292 of file avl.h.

◆ avl_next_element

#define avl_next_element (   element,
  node_member 
)     container_of((&(element)->node_member.list)->next, __typeof__(*(element)), node_member.list)

This function must not be called for the last element of an avl tree

Parameters
elementpointer to a node of the tree
node_membername of the avl_node element inside the larger struct
Returns
pointer to the node after 'element' (automatically converted to type 'element')

Definition at line 305 of file avl.h.

◆ avl_prev_element

#define avl_prev_element (   element,
  node_member 
)     container_of((&(element)->node_member.list)->prev, __typeof__(*(element)), node_member.list)

This function must not be called for the first element of an avl tree

Parameters
elementpointer to a node of the tree
node_membername of the avl_node element inside the larger struct
Returns
pointer to the node before 'element' (automatically converted to type 'element')

Definition at line 318 of file avl.h.

◆ avl_remove_all_elements

#define avl_remove_all_elements (   tree,
  element,
  node_member,
  ptr 
)
Value:
for (element = avl_first_element(tree, element, node_member), \
ptr = avl_next_element(element, node_member), \
(tree)->root = NULL; \
(tree)->count > 0; \
element = ptr, ptr = avl_next_element(ptr, node_member), (tree)->count--)
static void INIT_LIST_HEAD(struct list_head *list)
Definition: list.h:63
Definition: list.h:53

A special loop that removes all elements of the tree and cleans up the tree root. The loop body is responsible to free the node elements of the tree.

This loop is much faster than a normal one for clearing the tree because it does not rebalance the tree after each removal. Do NOT use a break command inside. You can free the memory of the elements within the loop. Do NOT call avl_delete() on the elements within the loop,

Parameters
treepointer to avl-tree
elementpointer to a node of the tree, this element will contain the current node of the tree during the loop
node_membername of the avl_node element inside the larger struct
ptrpointer to a tree element which is used to store the next node during the loop

Definition at line 545 of file avl.h.

◆ AVL_TREE

#define AVL_TREE (   _name,
  _comp,
  _allow_dups,
  _cmp_ptr 
)
Value:
struct avl_tree _name = \
AVL_TREE_INIT(_name, _comp, _allow_dups, _cmp_ptr)
Definition: avl.h:110

Definition at line 164 of file avl.h.

◆ AVL_TREE_INIT

#define AVL_TREE_INIT (   _name,
  _comp,
  _allow_dups,
  _cmp_ptr 
)
Value:
{ \
.list_head = LIST_HEAD_INIT(_name.list_head), \
.comp = _comp, \
.allow_dups = _allow_dups, \
.cmp_ptr = _cmp_ptr \
}
#define LIST_HEAD_INIT(name)
Definition: list.h:58

Definition at line 156 of file avl.h.

◆ EXPORT

#define EXPORT (   sym)    sym

Definition at line 50 of file avl.h.

Typedef Documentation

◆ avl_tree_comp

typedef int(* avl_tree_comp) (const void *k1, const void *k2, void *ptr)

Prototype for avl comparators

Parameters
k1first key
k2second key
ptrcustom data for tree comparator
Returns
+1 if k1>k2, -1 if k1<k2, 0 if k1==k2

Definition at line 104 of file avl.h.

Enumeration Type Documentation

◆ avl_find_mode

internal enum for avl_find_... macros

Enumerator
AVL_FIND_EQUAL 
AVL_FIND_LESSEQUAL 
AVL_FIND_GREATEREQUAL 

Definition at line 150 of file avl.h.

150  {
154 };
@ AVL_FIND_EQUAL
Definition: avl.h:151
@ AVL_FIND_LESSEQUAL
Definition: avl.h:152
@ AVL_FIND_GREATEREQUAL
Definition: avl.h:153

Function Documentation

◆ __avl_find_element()

static void* __avl_find_element ( const struct avl_tree tree,
const void *  key,
size_t  offset,
enum avl_find_mode  mode 
)
inlinestatic

Internal function to support returning the element from a avl tree query

Parameters
treepointer to avl tree
keypointer to key
offsetoffset of node inside the embedded struct
modemode of lookup operation (less equal, equal or greater equal)
pointerto elemen, NULL if no fitting one was found

Definition at line 213 of file avl.h.

213  {
214  void *node = NULL;
215 
216  switch (mode) {
217  case AVL_FIND_EQUAL:
218  node = avl_find(tree, key);
219  break;
220  case AVL_FIND_LESSEQUAL:
221  node = avl_find_lessequal(tree, key);
222  break;
224  node = avl_find_greaterequal(tree, key);
225  break;
226  }
227  return node == NULL ? NULL : (((char *)node) - offset);
228 }
struct avl_node * avl_find_lessequal(const struct avl_tree *tree, const void *key)
Definition: avl.c:137
struct avl_node * avl_find(const struct avl_tree *, const void *)
Definition: avl.c:115
struct avl_node * avl_find_greaterequal(const struct avl_tree *tree, const void *key)
Definition: avl.c:179
Definition: test-avl.c:13

◆ avl_delete()

void avl_delete ( struct avl_tree tree,
struct avl_node node 
)

Remove a node from an avl tree

Parameters
treepointer to tree
nodepointer to node

Definition at line 307 of file avl.c.

308 {
309  struct avl_node *next;
310  struct avl_node *parent;
311  struct avl_node *left;
312  struct avl_node *right;
313  if (node->leader) {
314  if (tree->allow_dups
315  && !list_is_last(&node->list, &tree->list_head)
316  && !(next = avl_next(node))->leader) {
317  next->leader = true;
318  next->balance = node->balance;
319 
320  parent = node->parent;
321  left = node->left;
322  right = node->right;
323 
324  next->parent = parent;
325  next->left = left;
326  next->right = right;
327 
328  if (parent == NULL)
329  tree->root = next;
330 
331  else {
332  if (node == parent->left)
333  parent->left = next;
334 
335  else
336  parent->right = next;
337  }
338 
339  if (left != NULL)
340  left->parent = next;
341 
342  if (right != NULL)
343  right->parent = next;
344  }
345 
346  else
347  avl_delete_worker(tree, node);
348  }
349 
350  avl_remove(tree, node);
351 }
static void avl_remove(struct avl_tree *tree, struct avl_node *node)
Definition: avl.c:505
static struct avl_node * avl_next(struct avl_node *node)
Definition: avl.c:102
static void avl_delete_worker(struct avl_tree *tree, struct avl_node *node)
Definition: avl.c:594
static bool list_is_last(const struct list_head *list, const struct list_head *head)
Definition: list.h:82
Definition: avl.h:56
struct avl_node * left
Definition: avl.h:74
signed char balance
Definition: avl.h:89
bool leader
Definition: avl.h:94
struct avl_node * right
Definition: avl.h:79
struct avl_node * parent
Definition: avl.h:69
struct list_head list_head
Definition: avl.h:115
struct avl_node * root
Definition: avl.h:120
bool allow_dups
Definition: avl.h:131
Here is the call graph for this function:
Here is the caller graph for this function:

◆ avl_find()

struct avl_node* avl_find ( const struct avl_tree tree,
const void *  key 
)

Finds a node in an avl-tree with a certain key

Parameters
treepointer to avl-tree
keypointer to key
Returns
pointer to avl-node with key, NULL if no node with this key exists.

Definition at line 115 of file avl.c.

116 {
117  struct avl_node *node;
118  int diff;
119 
120  if (tree->root == NULL)
121  return NULL;
122 
123  node = avl_find_rec(tree->root, key, tree->comp, tree->cmp_ptr, &diff);
124 
125  return diff == 0 ? node : NULL;
126 }
static struct avl_node * avl_find_rec(struct avl_node *node, const void *key, avl_tree_comp comp, void *ptr, int *cmp_result)
Definition: avl.c:354
const void * key
Definition: avl.h:84
void * cmp_ptr
Definition: avl.h:144
avl_tree_comp comp
Definition: avl.h:139
Here is the call graph for this function:
Here is the caller graph for this function:

◆ avl_find_greaterequal()

struct avl_node* avl_find_greaterequal ( const struct avl_tree tree,
const void *  key 
)

Finds the first node in an avl-tree with a key greater or equal than the specified key

Parameters
treepointer to avl-tree
keypointer to specified key
Returns
pointer to avl-node, NULL if no node with key greater or equal specified key exists.

Definition at line 179 of file avl.c.

179  {
180  struct avl_node *node, *next;
181  int diff;
182 
183  if (tree->root == NULL)
184  return NULL;
185 
186  node = avl_find_rec(tree->root, key, tree->comp, tree->cmp_ptr, &diff);
187 
188  /* go right as long as key>node.key */
189  while (diff > 0) {
190  if (list_is_last(&node->list, &tree->list_head)) {
191  return NULL;
192  }
193 
194  node = (struct avl_node *)node->list.next;
195  diff = (*tree->comp) (key, node->key, tree->cmp_ptr);
196  }
197 
198  /* go left as long as key<=next_node.key */
199  next = node;
200  while (diff <= 0) {
201  node = next;
202  if (list_is_first(&node->list, &tree->list_head)) {
203  break;
204  }
205 
206  next = (struct avl_node *)node->list.prev;
207  diff = (*tree->comp) (key, next->key, tree->cmp_ptr);
208  }
209  return node;
210 }
static bool list_is_first(const struct list_head *list, const struct list_head *head)
Definition: list.h:75
Here is the call graph for this function:

◆ avl_find_lessequal()

struct avl_node* avl_find_lessequal ( const struct avl_tree tree,
const void *  key 
)

Finds the last node in an avl-tree with a key less or equal than the specified key

Parameters
treepointer to avl-tree
keypointer to specified key
Returns
pointer to avl-node, NULL if no node with key less or equal specified key exists.

Definition at line 137 of file avl.c.

137  {
138  struct avl_node *node, *next;
139  int diff;
140 
141  if (tree->root == NULL)
142  return NULL;
143 
144  node = avl_find_rec(tree->root, key, tree->comp, tree->cmp_ptr, &diff);
145 
146  /* go left as long as key<node.key */
147  while (diff < 0) {
148  if (list_is_first(&node->list, &tree->list_head)) {
149  return NULL;
150  }
151 
152  node = (struct avl_node *)node->list.prev;
153  diff = (*tree->comp) (key, node->key, tree->cmp_ptr);
154  }
155 
156  /* go right as long as key>=next_node.key */
157  next = node;
158  while (diff >= 0) {
159  node = next;
160  if (list_is_last(&node->list, &tree->list_head)) {
161  break;
162  }
163 
164  next = (struct avl_node *)node->list.next;
165  diff = (*tree->comp) (key, next->key, tree->cmp_ptr);
166  }
167  return node;
168 }
Here is the call graph for this function:

◆ avl_init()

void avl_init ( struct avl_tree tree,
avl_tree_comp  comp,
bool  allow_dups,
void *  ptr 
)

Initialize a new avl_tree struct

Parameters
treepointer to avl-tree
comppointer to comparator for the tree
allow_dupstrue if the tree allows multiple elements with the same
ptrcustom parameter for comparator

Definition at line 92 of file avl.c.

93 {
94  INIT_LIST_HEAD(&tree->list_head);
95  tree->root = NULL;
96  tree->count = 0;
97  tree->comp = comp;
98  tree->allow_dups = allow_dups;
99  tree->cmp_ptr = ptr;
100 }
unsigned int count
Definition: avl.h:125
Here is the call graph for this function:
Here is the caller graph for this function:

◆ avl_insert()

int avl_insert ( struct avl_tree tree,
struct avl_node new 
)

Inserts an avl_node into a tree

Parameters
treepointer to tree
newpointer to node
Returns
0 if node was inserted successfully, -1 if it was not inserted because of a key collision

Definition at line 220 of file avl.c.

221 {
222  struct avl_node *node, *next, *last;
223  int diff;
224 
225  new->parent = NULL;
226 
227  new->left = NULL;
228  new->right = NULL;
229 
230  new->balance = 0;
231  new->leader = true;
232 
233  if (tree->root == NULL) {
234  list_add(&new->list, &tree->list_head);
235  tree->root = new;
236  tree->count = 1;
237  return 0;
238  }
239 
240  node = avl_find_rec(tree->root, new->key, tree->comp, tree->cmp_ptr, &diff);
241 
242  last = node;
243 
244  while (!list_is_last(&last->list, &tree->list_head)) {
245  next = avl_next(last);
246  if (next->leader) {
247  break;
248  }
249  last = next;
250  }
251 
252  diff = (*tree->comp) (new->key, node->key, tree->cmp_ptr);
253 
254  if (diff == 0) {
255  if (!tree->allow_dups)
256  return -1;
257 
258  new->leader = 0;
259 
260  avl_insert_after(tree, last, new);
261  return 0;
262  }
263 
264  if (node->balance == 1) {
265  avl_insert_before(tree, node, new);
266 
267  node->balance = 0;
268  new->parent = node;
269  node->left = new;
270  return 0;
271  }
272 
273  if (node->balance == -1) {
274  avl_insert_after(tree, last, new);
275 
276  node->balance = 0;
277  new->parent = node;
278  node->right = new;
279  return 0;
280  }
281 
282  if (diff < 0) {
283  avl_insert_before(tree, node, new);
284 
285  node->balance = -1;
286  new->parent = node;
287  node->left = new;
288  post_insert(tree, node);
289  return 0;
290  }
291 
292  avl_insert_after(tree, last, new);
293 
294  node->balance = 1;
295  new->parent = node;
296  node->right = new;
297  post_insert(tree, node);
298  return 0;
299 }
static void post_insert(struct avl_tree *tree, struct avl_node *node)
Definition: avl.c:443
static void avl_insert_before(struct avl_tree *tree, struct avl_node *pos_node, struct avl_node *node)
Definition: avl.c:491
static void avl_insert_after(struct avl_tree *tree, struct avl_node *pos_node, struct avl_node *node)
Definition: avl.c:498
static void list_add(struct list_head *_new, struct list_head *head)
Definition: list.h:159
struct list_head list
Definition: avl.h:64
Here is the call graph for this function:
Here is the caller graph for this function:

◆ avl_is_empty()

static bool avl_is_empty ( struct avl_tree tree)
inlinestatic
Parameters
treepointer to avl-tree
Returns
true if the tree is empty, false otherwise

Definition at line 200 of file avl.h.

200  {
201  return tree->count == 0;
202 }

◆ avl_is_first()

static bool avl_is_first ( struct avl_tree tree,
struct avl_node node 
)
inlinestatic
Parameters
treepointer to avl-tree
nodepointer to node of the tree
Returns
true if node is the first one of the tree, false otherwise

Definition at line 181 of file avl.h.

181  {
182  return tree->list_head.next == &node->list;
183 }
struct list_head * next
Definition: list.h:54

◆ avl_is_last()

static bool avl_is_last ( struct avl_tree tree,
struct avl_node node 
)
inlinestatic
Parameters
treepointer to avl-tree
nodepointer to node of the tree
Returns
true if node is the last one of the tree, false otherwise

Definition at line 191 of file avl.h.

191  {
192  return tree->list_head.prev == &node->list;
193 }
struct list_head * prev
Definition: list.h:55