parent
99167100db
commit
ca4fa3936a
|
@ -25,6 +25,20 @@
|
|||
#include "eina_error.h"
|
||||
#include "eina_iterator.h"
|
||||
|
||||
/**
|
||||
* @addtogroup Eina_Rbtree_Group Red-Black tree
|
||||
*
|
||||
* @brief These functions provide Red-Black trees management.
|
||||
*
|
||||
* For a brief description look at http://en.wikipedia.org/wiki/Red-black_tree .
|
||||
* This code is largely inspired from a tutorial written by Julienne Walker at :
|
||||
* http://eternallyconfuzzled.com/tuts/datastructures/jsw_tut_rbtree.aspx . The
|
||||
* main difference is that this set of function never allocate any data, making
|
||||
* them particularly useful for memory management.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup Eina_Data_Types_Group Data Types
|
||||
*
|
||||
|
@ -135,14 +149,111 @@ typedef void (*Eina_Rbtree_Free_Cb)(Eina_Rbtree *node, void *data);
|
|||
*/
|
||||
#define EINA_RBTREE_FREE_CB(Function) ((Eina_Rbtree_Free_Cb)Function)
|
||||
|
||||
|
||||
/**
|
||||
* @brief Insert a new node inside an existing red black tree.
|
||||
*
|
||||
* @param root The root of an exisiting valid red black tree.
|
||||
* @param node The new node to insert.
|
||||
* @param cmp The callback that is able to compare two nodes.
|
||||
* @param data Private data to help the compare function.
|
||||
* @return The new root of the red black tree.
|
||||
*
|
||||
* This function insert a new node in a valid red black tree. NULL is
|
||||
* an empty valid red black tree. The resulting new tree is a valid red
|
||||
* black tree. This function doesn't allocate any data.
|
||||
*/
|
||||
EAPI Eina_Rbtree *eina_rbtree_inline_insert(Eina_Rbtree *root, Eina_Rbtree *node, Eina_Rbtree_Cmp_Node_Cb cmp, const void *data) EINA_ARG_NONNULL(2, 3) EINA_WARN_UNUSED_RESULT;
|
||||
|
||||
/**
|
||||
* @brief Remove a node from an existing red black tree.
|
||||
*
|
||||
* @param root The root of a valid red black tree.
|
||||
* @param node The node to remove from the tree.
|
||||
* @param cmp The callback that is able to compare two nodes.
|
||||
* @param data Private data to help the compare function.
|
||||
* @return The new root of the red black tree.
|
||||
*
|
||||
* This function remove a new node in a valid red black tree that should
|
||||
* contain the node that you are removing. This function will return NULL
|
||||
* when the red black tree got empty. This function doesn't free any data.
|
||||
*/
|
||||
EAPI Eina_Rbtree *eina_rbtree_inline_remove(Eina_Rbtree *root, Eina_Rbtree *node, Eina_Rbtree_Cmp_Node_Cb cmp, const void *data) EINA_ARG_NONNULL(2, 3) EINA_WARN_UNUSED_RESULT;
|
||||
|
||||
/**
|
||||
* @brief Delete all nodes from a valid red black tree.
|
||||
*
|
||||
* @param root The root of a valid red black tree.
|
||||
* @param func The callback that will free each node.
|
||||
* @param data Private data to help the compare function.
|
||||
*
|
||||
*/
|
||||
EAPI void eina_rbtree_delete(Eina_Rbtree *root, Eina_Rbtree_Free_Cb func, void *data) EINA_ARG_NONNULL(2);
|
||||
|
||||
static inline Eina_Rbtree *eina_rbtree_inline_lookup(const Eina_Rbtree *root, const void *key, int length, Eina_Rbtree_Cmp_Key_Cb cmp, const void *data) EINA_PURE EINA_ARG_NONNULL(2, 4) EINA_WARN_UNUSED_RESULT;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Returned a new prefix iterator associated to a rbtree.
|
||||
*
|
||||
* @param root The root of rbtree.
|
||||
* @return A new iterator.
|
||||
*
|
||||
* This function returns a newly allocated iterator associated to @p
|
||||
* root. It will iterate the tree using prefix walk. If @p root is @c
|
||||
* NULL, this function still returns a valid iterator that will always
|
||||
* return false on eina_iterator_next(), thus keeping API sane.
|
||||
*
|
||||
* If the memory can not be allocated, NULL is returned and
|
||||
* #EINA_ERROR_OUT_OF_MEMORY is set. Otherwise, a valid iterator is
|
||||
* returned.
|
||||
*
|
||||
* @warning if the rbtree structure changes then the iterator becomes
|
||||
* invalid! That is, if you add or remove nodes this iterator
|
||||
* behavior is undefined and your program may crash!
|
||||
*/
|
||||
EAPI Eina_Iterator *eina_rbtree_iterator_prefix(const Eina_Rbtree *root) EINA_MALLOC EINA_WARN_UNUSED_RESULT;
|
||||
|
||||
/**
|
||||
* @brief Returned a new prefix iterator associated to a rbtree.
|
||||
*
|
||||
* @param root The root of rbtree.
|
||||
* @return A new iterator.
|
||||
*
|
||||
* This function returns a newly allocated iterator associated to @p
|
||||
* root. It will iterate the tree using infix walk. If @p root is @c
|
||||
* NULL, this function still returns a valid iterator that will always
|
||||
* return false on eina_iterator_next(), thus keeping API sane.
|
||||
*
|
||||
* If the memory can not be allocated, NULL is returned and
|
||||
* #EINA_ERROR_OUT_OF_MEMORY is set. Otherwise, a valid iterator is
|
||||
* returned.
|
||||
*
|
||||
* @warning if the rbtree structure changes then the iterator becomes
|
||||
* invalid! That is, if you add or remove nodes this iterator
|
||||
* behavior is undefined and your program may crash!
|
||||
*/
|
||||
EAPI Eina_Iterator *eina_rbtree_iterator_infix(const Eina_Rbtree *root) EINA_MALLOC EINA_WARN_UNUSED_RESULT;
|
||||
|
||||
/**
|
||||
* @brief Returned a new prefix iterator associated to a rbtree.
|
||||
*
|
||||
* @param root The root of rbtree.
|
||||
* @return A new iterator.
|
||||
*
|
||||
* This function returns a newly allocated iterator associated to @p
|
||||
* root. It will iterate the tree using postfix walk. If @p root is @c
|
||||
* NULL, this function still returns a valid iterator that will always
|
||||
* return false on eina_iterator_next(), thus keeping API sane.
|
||||
*
|
||||
* If the memory can not be allocated, NULL is returned and
|
||||
* #EINA_ERROR_OUT_OF_MEMORY is set. Otherwise, a valid iterator is
|
||||
* returned.
|
||||
*
|
||||
* @warning if the rbtree structure changes then the iterator becomes
|
||||
* invalid! That is, if you add or remove nodes this iterator
|
||||
* behavior is undefined and your program may crash!
|
||||
*/
|
||||
EAPI Eina_Iterator *eina_rbtree_iterator_postfix(const Eina_Rbtree *root) EINA_MALLOC EINA_WARN_UNUSED_RESULT;
|
||||
|
||||
#include "eina_inline_rbtree.x"
|
||||
|
@ -159,4 +270,8 @@ EAPI Eina_Iterator *eina_rbtree_iterator_postfix(const Eina_Rbtree *root)
|
|||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
|
|
@ -271,33 +271,6 @@ _eina_rbtree_inline_double_rotation(Eina_Rbtree *node,
|
|||
* API *
|
||||
*============================================================================*/
|
||||
|
||||
/**
|
||||
* @addtogroup Eina_Rbtree_Group Red-Black tree
|
||||
*
|
||||
* @brief These functions provide Red-Black trees management.
|
||||
*
|
||||
* For a brief description look at http://en.wikipedia.org/wiki/Red-black_tree .
|
||||
* This code is largely inspired from a tutorial written by Julienne Walker at :
|
||||
* http://eternallyconfuzzled.com/tuts/datastructures/jsw_tut_rbtree.aspx . The
|
||||
* main difference is that this set of function never allocate any data, making
|
||||
* them particularly useful for memory management.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Insert a new node inside an existing red black tree.
|
||||
*
|
||||
* @param root The root of an exisiting valid red black tree.
|
||||
* @param node The new node to insert.
|
||||
* @param cmp The callback that is able to compare two nodes.
|
||||
* @param data Private data to help the compare function.
|
||||
* @return The new root of the red black tree.
|
||||
*
|
||||
* This function insert a new node in a valid red black tree. NULL is
|
||||
* an empty valid red black tree. The resulting new tree is a valid red
|
||||
* black tree. This function doesn't allocate any data.
|
||||
*/
|
||||
EAPI Eina_Rbtree *
|
||||
eina_rbtree_inline_insert(Eina_Rbtree *root,
|
||||
Eina_Rbtree *node,
|
||||
|
@ -388,19 +361,6 @@ end_add:
|
|||
return root;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Remove a node from an existing red black tree.
|
||||
*
|
||||
* @param root The root of a valid red black tree.
|
||||
* @param node The node to remove from the tree.
|
||||
* @param cmp The callback that is able to compare two nodes.
|
||||
* @param data Private data to help the compare function.
|
||||
* @return The new root of the red black tree.
|
||||
*
|
||||
* This function remove a new node in a valid red black tree that should
|
||||
* contain the node that you are removing. This function will return NULL
|
||||
* when the red black tree got empty. This function doesn't free any data.
|
||||
*/
|
||||
EAPI Eina_Rbtree *
|
||||
eina_rbtree_inline_remove(Eina_Rbtree *root,
|
||||
Eina_Rbtree *node,
|
||||
|
@ -526,89 +486,24 @@ eina_rbtree_inline_remove(Eina_Rbtree *root,
|
|||
return root;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returned a new prefix iterator associated to a rbtree.
|
||||
*
|
||||
* @param root The root of rbtree.
|
||||
* @return A new iterator.
|
||||
*
|
||||
* This function returns a newly allocated iterator associated to @p
|
||||
* root. It will iterate the tree using prefix walk. If @p root is @c
|
||||
* NULL, this function still returns a valid iterator that will always
|
||||
* return false on eina_iterator_next(), thus keeping API sane.
|
||||
*
|
||||
* If the memory can not be allocated, NULL is returned and
|
||||
* #EINA_ERROR_OUT_OF_MEMORY is set. Otherwise, a valid iterator is
|
||||
* returned.
|
||||
*
|
||||
* @warning if the rbtree structure changes then the iterator becomes
|
||||
* invalid! That is, if you add or remove nodes this iterator
|
||||
* behavior is undefined and your program may crash!
|
||||
*/
|
||||
EAPI Eina_Iterator *
|
||||
eina_rbtree_iterator_prefix(const Eina_Rbtree *root)
|
||||
{
|
||||
return _eina_rbtree_iterator_build(root, EINA_RBTREE_ITERATOR_PREFIX_MASK);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returned a new prefix iterator associated to a rbtree.
|
||||
*
|
||||
* @param root The root of rbtree.
|
||||
* @return A new iterator.
|
||||
*
|
||||
* This function returns a newly allocated iterator associated to @p
|
||||
* root. It will iterate the tree using infix walk. If @p root is @c
|
||||
* NULL, this function still returns a valid iterator that will always
|
||||
* return false on eina_iterator_next(), thus keeping API sane.
|
||||
*
|
||||
* If the memory can not be allocated, NULL is returned and
|
||||
* #EINA_ERROR_OUT_OF_MEMORY is set. Otherwise, a valid iterator is
|
||||
* returned.
|
||||
*
|
||||
* @warning if the rbtree structure changes then the iterator becomes
|
||||
* invalid! That is, if you add or remove nodes this iterator
|
||||
* behavior is undefined and your program may crash!
|
||||
*/
|
||||
EAPI Eina_Iterator *
|
||||
eina_rbtree_iterator_infix(const Eina_Rbtree *root)
|
||||
{
|
||||
return _eina_rbtree_iterator_build(root, EINA_RBTREE_ITERATOR_INFIX_MASK);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returned a new prefix iterator associated to a rbtree.
|
||||
*
|
||||
* @param root The root of rbtree.
|
||||
* @return A new iterator.
|
||||
*
|
||||
* This function returns a newly allocated iterator associated to @p
|
||||
* root. It will iterate the tree using postfix walk. If @p root is @c
|
||||
* NULL, this function still returns a valid iterator that will always
|
||||
* return false on eina_iterator_next(), thus keeping API sane.
|
||||
*
|
||||
* If the memory can not be allocated, NULL is returned and
|
||||
* #EINA_ERROR_OUT_OF_MEMORY is set. Otherwise, a valid iterator is
|
||||
* returned.
|
||||
*
|
||||
* @warning if the rbtree structure changes then the iterator becomes
|
||||
* invalid! That is, if you add or remove nodes this iterator
|
||||
* behavior is undefined and your program may crash!
|
||||
*/
|
||||
EAPI Eina_Iterator *
|
||||
eina_rbtree_iterator_postfix(const Eina_Rbtree *root)
|
||||
{
|
||||
return _eina_rbtree_iterator_build(root, EINA_RBTREE_ITERATOR_POSTFIX_MASK);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Delete all nodes from a valid red black tree.
|
||||
*
|
||||
* @param root The root of a valid red black tree.
|
||||
* @param func The callback that will free each node.
|
||||
* @param data Private data to help the compare function.
|
||||
*
|
||||
*/
|
||||
EAPI void
|
||||
eina_rbtree_delete(Eina_Rbtree *root, Eina_Rbtree_Free_Cb func, void *data)
|
||||
{
|
||||
|
@ -621,7 +516,3 @@ eina_rbtree_delete(Eina_Rbtree *root, Eina_Rbtree_Free_Cb func, void *data)
|
|||
eina_rbtree_delete(root->son[1], func, data);
|
||||
func(root, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue