src/ucx/avl.h

Thu, 03 May 2018 10:44:33 +0200

author
Mike Becker <universe@uap-core.de>
date
Thu, 03 May 2018 10:44:33 +0200
changeset 287
98da78a1e69a
parent 259
2f5dea574a75
child 308
d6f580621512
permissions
-rw-r--r--

adds ucx_avl_free_content() function and documentation in modules.md

     1 /*
     2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     3  *
     4  * Copyright 2017 Mike Becker, Olaf Wintermann All rights reserved.
     5  *
     6  * Redistribution and use in source and binary forms, with or without
     7  * modification, are permitted provided that the following conditions are met:
     8  *
     9  *   1. Redistributions of source code must retain the above copyright
    10  *      notice, this list of conditions and the following disclaimer.
    11  *
    12  *   2. Redistributions in binary form must reproduce the above copyright
    13  *      notice, this list of conditions and the following disclaimer in the
    14  *      documentation and/or other materials provided with the distribution.
    15  *
    16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    19  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
    20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    26  * POSSIBILITY OF SUCH DAMAGE.
    27  */
    30 /**
    31  * @file avl.h
    32  * 
    33  * AVL tree implementation.
    34  * 
    35  * This binary search tree implementation allows average O(1) insertion and
    36  * removal of elements (excluding binary search time).
    37  * 
    38  * @author Mike Becker
    39  * @author Olaf Wintermann
    40  */
    42 #ifndef UCX_AVL_H
    43 #define UCX_AVL_H
    45 #include "ucx.h"
    46 #include "allocator.h"
    47 #include <inttypes.h>
    49 #ifdef	__cplusplus
    50 extern "C" {
    51 #endif
    53 /**
    54  * UCX AVL Node type.
    55  * 
    56  * @see UcxAVLNode
    57  */
    58 typedef struct UcxAVLNode UcxAVLNode;
    60 /**
    61  * UCX AVL Node.
    62  */
    63 struct UcxAVLNode {
    64     /**
    65      * The key for this node.
    66      */
    67     intptr_t key;
    68     /**
    69      * Data contained by this node.
    70      */
    71     void *value;
    72     /**
    73      * The height of this (sub)-tree.
    74      */
    75     size_t height;
    76     /**
    77      * Parent node.
    78      */
    79     UcxAVLNode *parent;
    80     /**
    81      * Root node of left subtree.
    82      */
    83     UcxAVLNode *left;
    84     /**
    85      * Root node of right subtree.
    86      */
    87     UcxAVLNode *right;
    88 };
    90 /**
    91  * UCX AVL Tree.
    92  */
    93 typedef struct {
    94     /**
    95      * The UcxAllocator that shall be used to manage the memory for node data.
    96      */
    97     UcxAllocator *allocator;
    98     /**
    99      * Root node of the tree.
   100      */
   101     UcxAVLNode *root;
   102     /**
   103      * Compare function that shall be used to compare the UcxAVLNode keys.
   104      * @see UcxAVLNode.key
   105      */
   106     cmp_func cmpfunc;
   107     /**
   108      * Custom user data.
   109      * This data will also be provided to the cmpfunc.
   110      */
   111     void *userdata;
   112 } UcxAVLTree;
   114 /**
   115  * Initializes a new UcxAVLTree with a default allocator.
   116  * 
   117  * @param cmpfunc the compare function that shall be used
   118  * @return a new UcxAVLTree object
   119  * @see ucx_avl_new_a()
   120  */
   121 UcxAVLTree *ucx_avl_new(cmp_func cmpfunc);
   123 /**
   124  * Initializes a new UcxAVLTree with the specified allocator.
   125  * 
   126  * The cmpfunc should be capable of comparing two keys within this AVL tree.
   127  * So if you want to use null terminated strings as keys, you could use the
   128  * ucx_strcmp() function here.
   129  * 
   130  * @param cmpfunc the compare function that shall be used
   131  * @param allocator the UcxAllocator that shall be used
   132  * @return a new UcxAVLTree object
   133  */
   134 UcxAVLTree *ucx_avl_new_a(cmp_func cmpfunc, UcxAllocator *allocator);
   136 /**
   137  * Destroys a UcxAVLTree.
   138  * 
   139  * Note, that the contents are not automatically freed.
   140  * Use may use #ucx_avl_free_content() before calling this function.
   141  * 
   142  * @param tree the tree to destroy
   143  * @see ucx_avl_free_content()
   144  */
   145 void ucx_avl_free(UcxAVLTree *tree);
   147 /**
   148  * Frees the contents of a UcxAVLTree.
   149  * 
   150  * This is a convenience function that iterates over the tree and passes all
   151  * values to the specified destructor function.
   152  * 
   153  * If no destructor is specified (<code>NULL</code>), the free() function of
   154  * the tree's own allocator is used.
   155  * 
   156  * You must ensure, that it is valid to pass each value in the map to the same
   157  * destructor function.
   158  * 
   159  * You should free the entire tree afterwards, as the contents will be invalid.
   160  * 
   161  * @param tree for which the contents shall be freed
   162  * @param destr optional pointer to a destructor function
   163  * @see ucx_avl_free()
   164  */
   165 void ucx_avl_free_content(UcxAVLTree *tree, ucx_destructor destr);
   167 /**
   168  * Macro for initializing a new UcxAVLTree with the default allocator and a
   169  * ucx_ptrcmp() compare function.
   170  * 
   171  * @return a new default UcxAVLTree object
   172  */
   173 #define ucx_avl_default_new() ucx_avl_new_a(ucx_ptrcmp, ucx_default_allocator())
   175 /**
   176  * Gets the node from the tree, that is associated with the specified key.
   177  * @param tree the UcxAVLTree
   178  * @param key the key
   179  * @return the node (or <code>NULL</code>, if the key is not present)
   180  */
   181 UcxAVLNode *ucx_avl_get_node(UcxAVLTree *tree, intptr_t key);
   183 /**
   184  * Gets the value from the tree, that is associated with the specified key.
   185  * @param tree the UcxAVLTree
   186  * @param key the key
   187  * @return the value (or <code>NULL</code>, if the key is not present)
   188  */
   189 void *ucx_avl_get(UcxAVLTree *tree, intptr_t key);
   191 /**
   192  * A mode for #ucx_avl_find_node() with the same behavior as
   193  * #ucx_avl_get_node().
   194  */
   195 #define UCX_AVL_FIND_EXACT         0
   196 /**
   197  * A mode for #ucx_avl_find_node() finding the node whose key is at least
   198  * as large as the specified key.
   199  */
   200 #define UCX_AVL_FIND_LOWER_BOUNDED 1
   201 /**
   202  * A mode for #ucx_avl_find_node() finding the node whose key is at most
   203  * as large as the specified key.
   204  */
   205 #define UCX_AVL_FIND_UPPER_BOUNDED 2
   206 /**
   207  * A mode for #ucx_avl_find_node() finding the node with a key that is as close
   208  * to the specified key as possible. If the key is present, the behavior is
   209  * like #ucx_avl_get_node(). This mode only returns <code>NULL</code> on
   210  * empty trees.
   211  */
   212 #define UCX_AVL_FIND_CLOSEST       3
   214 /**
   215  * Finds a node within the tree. The following modes are supported:
   216  * <ul>
   217  * <li>#UCX_AVL_FIND_EXACT: the same behavior as #ucx_avl_get_node()</li>
   218  * <li>#UCX_AVL_FIND_LOWER_BOUNDED: finds the node whose key is at least
   219  * as large as the specified key</li>
   220  * <li>#UCX_AVL_FIND_UPPER_BOUNDED: finds the node whose key is at most
   221  * as large as the specified key</li>
   222  * <li>#UCX_AVL_FIND_CLOSEST: finds the node with a key that is as close to
   223  * the specified key as possible. If the key is present, the behavior is
   224  * like #ucx_avl_get_node(). This mode only returns <code>NULL</code> on
   225  * empty trees.</li> 
   226  * </ul>
   227  * 
   228  * The distance function provided MUST agree with the compare function of
   229  * the AVL tree.
   230  * 
   231  * @param tree the UcxAVLTree
   232  * @param key the key
   233  * @param dfnc the distance function
   234  * @param mode the find mode
   235  * @return the node (or <code>NULL</code>, if no node can be found)
   236  */
   237 UcxAVLNode *ucx_avl_find_node(UcxAVLTree *tree, intptr_t key,
   238         distance_func dfnc, int mode);
   240 /**
   241  * Finds a value within the tree.
   242  * See #ucx_avl_find_node() for details.
   243  * 
   244  * @param tree the UcxAVLTree
   245  * @param key the key
   246  * @param dfnc the distance function
   247  * @param mode the find mode
   248  * @return the value (or <code>NULL</code>, if no value can be found)
   249  */
   250 void *ucx_avl_find(UcxAVLTree *tree, intptr_t key,
   251         distance_func dfnc, int mode);
   253 /**
   254  * Puts a key/value pair into the tree.
   255  * 
   256  * Attention: use this function only, if a possible old value does not need
   257  * to be preserved.
   258  * 
   259  * @param tree the UcxAVLTree
   260  * @param key the key
   261  * @param value the new value
   262  * @return zero, if and only if the operation succeeded
   263  */
   264 int ucx_avl_put(UcxAVLTree *tree, intptr_t key, void *value);
   266 /**
   267  * Puts a key/value pair into the tree.
   268  * 
   269  * This is a secure function which saves the old value to the variable pointed
   270  * at by oldvalue.
   271  * 
   272  * @param tree the UcxAVLTree
   273  * @param key the key
   274  * @param value the new value
   275  * @param oldvalue optional: a pointer to the location where a possible old
   276  * value shall be stored
   277  * @return zero, if and only if the operation succeeded
   278  */
   279 int ucx_avl_put_s(UcxAVLTree *tree, intptr_t key, void *value, void **oldvalue);
   281 /**
   282  * Removes a node from the AVL tree.
   283  * 
   284  * Note: the specified node is logically removed. The tree implementation
   285  * decides which memory area is freed. In most cases the here provided node
   286  * is freed, so its further use is generally undefined.
   287  * 
   288  * @param tree the UcxAVLTree
   289  * @param node the node to remove
   290  * @return zero, if and only if an element has been removed
   291  */
   292 int ucx_avl_remove_node(UcxAVLTree *tree, UcxAVLNode *node);
   294 /**
   295  * Removes an element from the AVL tree.
   296  * 
   297  * @param tree the UcxAVLTree
   298  * @param key the key
   299  * @return zero, if and only if an element has been removed
   300  */
   301 int ucx_avl_remove(UcxAVLTree *tree, intptr_t key);
   303 /**
   304  * Removes an element from the AVL tree.
   305  * 
   306  * This is a secure function which saves the old key and value data from node
   307  * to the variables at the location of oldkey and oldvalue (if specified), so
   308  * they can be freed afterwards (if necessary).
   309  * 
   310  * Note: the returned key in oldkey is possibly not the same as the provided
   311  * key for the lookup (in terms of memory location).
   312  * 
   313  * @param tree the UcxAVLTree
   314  * @param key the key of the element to remove
   315  * @param oldkey optional: a pointer to the location where the old key shall be
   316  * stored
   317  * @param oldvalue optional: a pointer to the location where the old value
   318  * shall be stored
   319  * @return zero, if and only if an element has been removed
   320  */
   321 int ucx_avl_remove_s(UcxAVLTree *tree, intptr_t key,
   322         intptr_t *oldkey, void **oldvalue);
   324 /**
   325  * Counts the nodes in the specified UcxAVLTree.
   326  * @param tree the AVL tree
   327  * @return the node count
   328  */
   329 size_t ucx_avl_count(UcxAVLTree *tree);
   331 /**
   332  * Finds the in-order predecessor of the given node.
   333  * @param node an AVL node
   334  * @return the in-order predecessor of the given node, or <code>NULL</code> if
   335  * the given node is the in-order minimum
   336  */
   337 UcxAVLNode* ucx_avl_pred(UcxAVLNode* node);
   339 /**
   340  * Finds the in-order successor of the given node.
   341  * @param node an AVL node
   342  * @return the in-order successor of the given node, or <code>NULL</code> if
   343  * the given node is the in-order maximum
   344  */
   345 UcxAVLNode* ucx_avl_succ(UcxAVLNode* node);
   347 #ifdef	__cplusplus
   348 }
   349 #endif
   351 #endif	/* UCX_AVL_H */

mercurial