src/ucx/avl.h

Mon, 14 May 2018 18:20:56 +0200

author
Mike Becker <universe@uap-core.de>
date
Mon, 14 May 2018 18:20:56 +0200
changeset 312
e1e3b768ae8b
parent 308
d6f580621512
permissions
-rw-r--r--

renames ucx_ptrcmp() to ucx_cmp_ptr()

     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_cmp_str() 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_cmp_ptr() compare function.
   170  * 
   171  * @return a new default UcxAVLTree object
   172  */
   173 #define ucx_avl_default_new() \
   174     ucx_avl_new_a(ucx_cmp_ptr, ucx_default_allocator())
   176 /**
   177  * Gets the node from the tree, that is associated with the specified key.
   178  * @param tree the UcxAVLTree
   179  * @param key the key
   180  * @return the node (or <code>NULL</code>, if the key is not present)
   181  */
   182 UcxAVLNode *ucx_avl_get_node(UcxAVLTree *tree, intptr_t key);
   184 /**
   185  * Gets the value from the tree, that is associated with the specified key.
   186  * @param tree the UcxAVLTree
   187  * @param key the key
   188  * @return the value (or <code>NULL</code>, if the key is not present)
   189  */
   190 void *ucx_avl_get(UcxAVLTree *tree, intptr_t key);
   192 /**
   193  * A mode for #ucx_avl_find_node() with the same behavior as
   194  * #ucx_avl_get_node().
   195  */
   196 #define UCX_AVL_FIND_EXACT         0
   197 /**
   198  * A mode for #ucx_avl_find_node() finding the node whose key is at least
   199  * as large as the specified key.
   200  */
   201 #define UCX_AVL_FIND_LOWER_BOUNDED 1
   202 /**
   203  * A mode for #ucx_avl_find_node() finding the node whose key is at most
   204  * as large as the specified key.
   205  */
   206 #define UCX_AVL_FIND_UPPER_BOUNDED 2
   207 /**
   208  * A mode for #ucx_avl_find_node() finding the node with a key that is as close
   209  * to the specified key as possible. If the key is present, the behavior is
   210  * like #ucx_avl_get_node(). This mode only returns <code>NULL</code> on
   211  * empty trees.
   212  */
   213 #define UCX_AVL_FIND_CLOSEST       3
   215 /**
   216  * Finds a node within the tree. The following modes are supported:
   217  * <ul>
   218  * <li>#UCX_AVL_FIND_EXACT: the same behavior as #ucx_avl_get_node()</li>
   219  * <li>#UCX_AVL_FIND_LOWER_BOUNDED: finds the node whose key is at least
   220  * as large as the specified key</li>
   221  * <li>#UCX_AVL_FIND_UPPER_BOUNDED: finds the node whose key is at most
   222  * as large as the specified key</li>
   223  * <li>#UCX_AVL_FIND_CLOSEST: finds the node with a key that is as close to
   224  * the specified key as possible. If the key is present, the behavior is
   225  * like #ucx_avl_get_node(). This mode only returns <code>NULL</code> on
   226  * empty trees.</li> 
   227  * </ul>
   228  * 
   229  * The distance function provided MUST agree with the compare function of
   230  * the AVL tree.
   231  * 
   232  * @param tree the UcxAVLTree
   233  * @param key the key
   234  * @param dfnc the distance function
   235  * @param mode the find mode
   236  * @return the node (or <code>NULL</code>, if no node can be found)
   237  */
   238 UcxAVLNode *ucx_avl_find_node(UcxAVLTree *tree, intptr_t key,
   239         distance_func dfnc, int mode);
   241 /**
   242  * Finds a value within the tree.
   243  * See #ucx_avl_find_node() for details.
   244  * 
   245  * @param tree the UcxAVLTree
   246  * @param key the key
   247  * @param dfnc the distance function
   248  * @param mode the find mode
   249  * @return the value (or <code>NULL</code>, if no value can be found)
   250  */
   251 void *ucx_avl_find(UcxAVLTree *tree, intptr_t key,
   252         distance_func dfnc, int mode);
   254 /**
   255  * Puts a key/value pair into the tree.
   256  * 
   257  * Attention: use this function only, if a possible old value does not need
   258  * to be preserved.
   259  * 
   260  * @param tree the UcxAVLTree
   261  * @param key the key
   262  * @param value the new value
   263  * @return zero, if and only if the operation succeeded
   264  */
   265 int ucx_avl_put(UcxAVLTree *tree, intptr_t key, void *value);
   267 /**
   268  * Puts a key/value pair into the tree.
   269  * 
   270  * This is a secure function which saves the old value to the variable pointed
   271  * at by oldvalue.
   272  * 
   273  * @param tree the UcxAVLTree
   274  * @param key the key
   275  * @param value the new value
   276  * @param oldvalue optional: a pointer to the location where a possible old
   277  * value shall be stored
   278  * @return zero, if and only if the operation succeeded
   279  */
   280 int ucx_avl_put_s(UcxAVLTree *tree, intptr_t key, void *value, void **oldvalue);
   282 /**
   283  * Removes a node from the AVL tree.
   284  * 
   285  * Note: the specified node is logically removed. The tree implementation
   286  * decides which memory area is freed. In most cases the here provided node
   287  * is freed, so its further use is generally undefined.
   288  * 
   289  * @param tree the UcxAVLTree
   290  * @param node the node to remove
   291  * @return zero, if and only if an element has been removed
   292  */
   293 int ucx_avl_remove_node(UcxAVLTree *tree, UcxAVLNode *node);
   295 /**
   296  * Removes an element from the AVL tree.
   297  * 
   298  * @param tree the UcxAVLTree
   299  * @param key the key
   300  * @return zero, if and only if an element has been removed
   301  */
   302 int ucx_avl_remove(UcxAVLTree *tree, intptr_t key);
   304 /**
   305  * Removes an element from the AVL tree.
   306  * 
   307  * This is a secure function which saves the old key and value data from node
   308  * to the variables at the location of oldkey and oldvalue (if specified), so
   309  * they can be freed afterwards (if necessary).
   310  * 
   311  * Note: the returned key in oldkey is possibly not the same as the provided
   312  * key for the lookup (in terms of memory location).
   313  * 
   314  * @param tree the UcxAVLTree
   315  * @param key the key of the element to remove
   316  * @param oldkey optional: a pointer to the location where the old key shall be
   317  * stored
   318  * @param oldvalue optional: a pointer to the location where the old value
   319  * shall be stored
   320  * @return zero, if and only if an element has been removed
   321  */
   322 int ucx_avl_remove_s(UcxAVLTree *tree, intptr_t key,
   323         intptr_t *oldkey, void **oldvalue);
   325 /**
   326  * Counts the nodes in the specified UcxAVLTree.
   327  * @param tree the AVL tree
   328  * @return the node count
   329  */
   330 size_t ucx_avl_count(UcxAVLTree *tree);
   332 /**
   333  * Finds the in-order predecessor of the given node.
   334  * @param node an AVL node
   335  * @return the in-order predecessor of the given node, or <code>NULL</code> if
   336  * the given node is the in-order minimum
   337  */
   338 UcxAVLNode* ucx_avl_pred(UcxAVLNode* node);
   340 /**
   341  * Finds the in-order successor of the given node.
   342  * @param node an AVL node
   343  * @return the in-order successor of the given node, or <code>NULL</code> if
   344  * the given node is the in-order maximum
   345  */
   346 UcxAVLNode* ucx_avl_succ(UcxAVLNode* node);
   348 #ifdef	__cplusplus
   349 }
   350 #endif
   352 #endif	/* UCX_AVL_H */

mercurial