OLSRd commons library
Copyright (c) 2004-2011 the olsr.org team
Cleaned up and extracted into this form by Henning Rogge in 2011

The OLSRd commons library is a collection of helper functions
that are used through the whole OSLRd for list/tree handling,
string management and other things.

=============================
    OLSRd commons avl API
=============================

The avl API provides a generic binary tree library with iteration
and custom comparator support

The API use two structs to define AVL trees, the avl_tree struct
which is a handler for the whole key, and the avl_node struct,
which has to be included into every tree node object.

The AVL nodes do not contain a pointer to the value of the node.
Instead of this the avl_node must be put into a larger datastructure
and the API calculates the pointer to this struct by the known
offset of the avl_node inside it.

For a full documentation of all helper macros and inline functions
look into the avl.h header file.



==================================
    OLSRd commons avl overview
==================================

1) avl lifecycle
2) defining a comparator
3) adding/removing elements to a tree
4) look for tree elements
5) iterator macros



1) avl lifecycle
****************

Each avl_tree must be initialized with the avl_init() function, which
needs a pointer to the avl_tree and a comparator of the tree. The third
parameter controls if the tree supports multiple elements with the
same key and the last one is a user defined pointer that will be
provided to the comparator.

The avl API does not allocate memory at all. Both the avl_tree and
the avl_node structs have to be allocated by the user. Because of this
the API does NOT contain a avl_free() operation.



2) defining a comparator
************************

Each AVL tree needs a comparator for it keys. The comparator is a
function with three elements, first the two keys and last the custom
data pointer from the avl_tree.

The comparator has to return 0 if both keys are equal (for the avl tree),
a number smaller than zero if key1 is smaller than key2 and a number
larger than zero if key1 is larger than key2.

The avl_comp.c file contains a number of predefined comparators.

int
avl_comp_strcasecmp(const void *txt1, const void *txt2,
    void *ptr __attribute__ ((unused))) {
  return strcasecmp(txt1, txt2);
}



3) adding/removing elements to a tree
*************************************

avl_insert() adds a node to an avl_tree. If the node does not allow
duplicate keys and a node with the same key is already present,
avl_insert will return an error.

The avl_node key variable MUST BE INITIALIZED before the node can be
added to the avl_tree. All other node fields will be initialized by
the API. 

Each avl_node can only be in one avl_tree at once.

The avl_remove() function removes a node from an avl_tree. It is not
allowed to call the function for a node which is not a member of the
tree.

struct my_node {
    int i;
    struct avl_node node
};

void add(struct avl_tree *tree, struct my_node *n)
{
    /* use the integer as the key */
    n->node.key = &m->i;
    avl_insert(tree, &n->node);
}



4) look for tree elements
*************************

There are three functions to look for avl_nodes in a tree. All of
them return NULL if they find no matching node or a pointer to
the avl_node.

avl_find() is the simplest lookup function, which searchs for an
avl_node within a tree with a certain key.

avl_find_lessequal() looks for the 'largest' key that is less or
equal compared to the parameter of the lookup function.

avl_find_greaterequal() does the same, it just searchs for the
'smallest' key larger or equal to the parameter.

Because all these functions return only the avl_node pointer and
not the struct it is embedded into, there are three corresponding
macros that do this translation automatically.

The macros are avl_find_element(), avl_find_le_element() and
avl_find_ge_element().

Each of this functions needs four parameters. The first and second
are the same as the lookup functions, a pointer to the avl_tree and
a pointer to a key.

The third parameter is a pointer to a struct, in which the avl_node
is embedded into. The fourth one is the NAME of the avl_node inside
the struct.

struct my_node {
    int i;
    struct avl_node node
};

void find(struct avl_tree *tree)
{
    struct my_node *my;
    int key = 1;
    
    my = avl_find_element(tree, &key, my, node);
    if (my) {
        ....
    }
}



5) iterator macros
******************

avl.h contains a series of iterator macros, which can be each used
similar to a normal C for-loop statement. They are usually prefixed
with "avl_for_".

Most of the macros exist twice, once 'normal' and once with the suffix
"_safe". The safe macros can be used even if the current iterated
node will be removed inside the loop, but they need an additional
pointer to the iterated objects to store the next element.

struct my_node {
    int i;
    struct avl_node node
};

void iterate(struct avl_tree *tree)
{
    struct my_node *my, *safe;
    
    avl_for_each_element(tree, my, node) {
        ....
    }
    
    avl_for_each_element_safe(tree, my, node, safe) {
        if ( ... ) {
            avl_remove(tree, my);
        }
    }
}
 