| 1 | /***************************************************************************** |
| 2 | |
| 3 | Copyright (c) 2007, 2015, Oracle and/or its affiliates. All Rights Reserved. |
| 4 | |
| 5 | This program is free software; you can redistribute it and/or modify it under |
| 6 | the terms of the GNU General Public License as published by the Free Software |
| 7 | Foundation; version 2 of the License. |
| 8 | |
| 9 | This program is distributed in the hope that it will be useful, but WITHOUT |
| 10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
| 11 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. |
| 12 | |
| 13 | You should have received a copy of the GNU General Public License along with |
| 14 | this program; if not, write to the Free Software Foundation, Inc., |
| 15 | 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA |
| 16 | |
| 17 | *****************************************************************************/ |
| 18 | /******************************************************************//** |
| 19 | @file include/ut0rbt.h |
| 20 | Various utilities |
| 21 | |
| 22 | Created 2007-03-20 Sunny Bains |
| 23 | *******************************************************/ |
| 24 | |
| 25 | #ifndef INNOBASE_UT0RBT_H |
| 26 | #define INNOBASE_UT0RBT_H |
| 27 | |
| 28 | #if !defined(IB_RBT_TESTING) |
| 29 | #include "univ.i" |
| 30 | #include "ut0mem.h" |
| 31 | #else |
| 32 | #include <stdio.h> |
| 33 | #include <stdlib.h> |
| 34 | #include <string.h> |
| 35 | #include <assert.h> |
| 36 | |
| 37 | #define ut_malloc malloc |
| 38 | #define ut_free free |
| 39 | #define ulint unsigned long |
| 40 | #define ut_a(c) assert(c) |
| 41 | #define ut_error assert(0) |
| 42 | #define ibool unsigned int |
| 43 | #define TRUE 1 |
| 44 | #define FALSE 0 |
| 45 | #endif |
| 46 | |
| 47 | struct ib_rbt_node_t; |
| 48 | typedef void (*ib_rbt_print_node)(const ib_rbt_node_t* node); |
| 49 | typedef int (*ib_rbt_compare)(const void* p1, const void* p2); |
| 50 | typedef int (*ib_rbt_arg_compare)(const void*, const void* p1, const void* p2); |
| 51 | |
| 52 | /** Red black tree color types */ |
| 53 | enum ib_rbt_color_t { |
| 54 | IB_RBT_RED, |
| 55 | IB_RBT_BLACK |
| 56 | }; |
| 57 | |
| 58 | /** Red black tree node */ |
| 59 | struct ib_rbt_node_t { |
| 60 | ib_rbt_color_t color; /* color of this node */ |
| 61 | |
| 62 | ib_rbt_node_t* left; /* points left child */ |
| 63 | ib_rbt_node_t* right; /* points right child */ |
| 64 | ib_rbt_node_t* parent; /* points parent node */ |
| 65 | |
| 66 | char value[1]; /* Data value */ |
| 67 | }; |
| 68 | |
| 69 | /** Red black tree instance.*/ |
| 70 | struct ib_rbt_t { |
| 71 | ib_rbt_node_t* nil; /* Black colored node that is |
| 72 | used as a sentinel. This is |
| 73 | pre-allocated too.*/ |
| 74 | |
| 75 | ib_rbt_node_t* root; /* Root of the tree, this is |
| 76 | pre-allocated and the first |
| 77 | data node is the left child.*/ |
| 78 | |
| 79 | ulint n_nodes; /* Total number of data nodes */ |
| 80 | |
| 81 | ib_rbt_compare compare; /* Fn. to use for comparison */ |
| 82 | ib_rbt_arg_compare |
| 83 | compare_with_arg; /* Fn. to use for comparison |
| 84 | with argument */ |
| 85 | ulint sizeof_value; /* Sizeof the item in bytes */ |
| 86 | void* cmp_arg; /* Compare func argument */ |
| 87 | }; |
| 88 | |
| 89 | /** The result of searching for a key in the tree, this is useful for |
| 90 | a speedy lookup and insert if key doesn't exist.*/ |
| 91 | struct ib_rbt_bound_t { |
| 92 | const ib_rbt_node_t* |
| 93 | last; /* Last node visited */ |
| 94 | |
| 95 | int result; /* Result of comparing with |
| 96 | the last non-nil node that |
| 97 | was visited */ |
| 98 | }; |
| 99 | |
| 100 | /* Size in elements (t is an rb tree instance) */ |
| 101 | #define rbt_size(t) (t->n_nodes) |
| 102 | |
| 103 | /* Check whether the rb tree is empty (t is an rb tree instance) */ |
| 104 | #define rbt_empty(t) (rbt_size(t) == 0) |
| 105 | |
| 106 | /* Get data value (t is the data type, n is an rb tree node instance) */ |
| 107 | #define rbt_value(t, n) ((t*) &n->value[0]) |
| 108 | |
| 109 | /* Compare a key with the node value (t is tree, k is key, n is node)*/ |
| 110 | #define rbt_compare(t, k, n) (t->compare(k, n->value)) |
| 111 | |
| 112 | /**********************************************************************//** |
| 113 | Free an instance of a red black tree */ |
| 114 | void |
| 115 | rbt_free( |
| 116 | /*=====*/ |
| 117 | ib_rbt_t* tree); /*!< in: rb tree to free */ |
| 118 | /**********************************************************************//** |
| 119 | Create an instance of a red black tree |
| 120 | @return rb tree instance */ |
| 121 | ib_rbt_t* |
| 122 | rbt_create( |
| 123 | /*=======*/ |
| 124 | size_t sizeof_value, /*!< in: size in bytes */ |
| 125 | ib_rbt_compare compare); /*!< in: comparator */ |
| 126 | /**********************************************************************//** |
| 127 | Create an instance of a red black tree, whose comparison function takes |
| 128 | an argument |
| 129 | @return rb tree instance */ |
| 130 | ib_rbt_t* |
| 131 | rbt_create_arg_cmp( |
| 132 | /*===============*/ |
| 133 | size_t sizeof_value, /*!< in: size in bytes */ |
| 134 | ib_rbt_arg_compare |
| 135 | compare, /*!< in: comparator */ |
| 136 | void* cmp_arg); /*!< in: compare fn arg */ |
| 137 | /**********************************************************************//** |
| 138 | Delete a node from the red black tree, identified by key */ |
| 139 | ibool |
| 140 | rbt_delete( |
| 141 | /*=======*/ |
| 142 | /* in: TRUE on success */ |
| 143 | ib_rbt_t* tree, /* in: rb tree */ |
| 144 | const void* key); /* in: key to delete */ |
| 145 | /**********************************************************************//** |
| 146 | Remove a node from the red black tree, NOTE: This function will not delete |
| 147 | the node instance, THAT IS THE CALLERS RESPONSIBILITY. |
| 148 | @return the deleted node with the const. */ |
| 149 | ib_rbt_node_t* |
| 150 | rbt_remove_node( |
| 151 | /*============*/ |
| 152 | ib_rbt_t* tree, /*!< in: rb tree */ |
| 153 | const ib_rbt_node_t* |
| 154 | node); /*!< in: node to delete, this |
| 155 | is a fudge and declared const |
| 156 | because the caller has access |
| 157 | only to const nodes.*/ |
| 158 | /**********************************************************************//** |
| 159 | Add data to the red black tree, identified by key (no dups yet!) |
| 160 | @return inserted node */ |
| 161 | const ib_rbt_node_t* |
| 162 | rbt_insert( |
| 163 | /*=======*/ |
| 164 | ib_rbt_t* tree, /*!< in: rb tree */ |
| 165 | const void* key, /*!< in: key for ordering */ |
| 166 | const void* value); /*!< in: data that will be |
| 167 | copied to the node.*/ |
| 168 | /**********************************************************************//** |
| 169 | Add a new node to the tree, useful for data that is pre-sorted. |
| 170 | @return appended node */ |
| 171 | const ib_rbt_node_t* |
| 172 | rbt_add_node( |
| 173 | /*=========*/ |
| 174 | ib_rbt_t* tree, /*!< in: rb tree */ |
| 175 | ib_rbt_bound_t* parent, /*!< in: parent */ |
| 176 | const void* value); /*!< in: this value is copied |
| 177 | to the node */ |
| 178 | /**********************************************************************//** |
| 179 | Return the left most data node in the tree |
| 180 | @return left most node */ |
| 181 | const ib_rbt_node_t* |
| 182 | rbt_first( |
| 183 | /*======*/ |
| 184 | const ib_rbt_t* tree); /*!< in: rb tree */ |
| 185 | /**********************************************************************//** |
| 186 | Return the right most data node in the tree |
| 187 | @return right most node */ |
| 188 | const ib_rbt_node_t* |
| 189 | rbt_last( |
| 190 | /*=====*/ |
| 191 | const ib_rbt_t* tree); /*!< in: rb tree */ |
| 192 | /**********************************************************************//** |
| 193 | Return the next node from current. |
| 194 | @return successor node to current that is passed in. */ |
| 195 | const ib_rbt_node_t* |
| 196 | rbt_next( |
| 197 | /*=====*/ |
| 198 | const ib_rbt_t* tree, /*!< in: rb tree */ |
| 199 | const ib_rbt_node_t* /* in: current node */ |
| 200 | current); |
| 201 | /**********************************************************************//** |
| 202 | Return the prev node from current. |
| 203 | @return precedessor node to current that is passed in */ |
| 204 | const ib_rbt_node_t* |
| 205 | rbt_prev( |
| 206 | /*=====*/ |
| 207 | const ib_rbt_t* tree, /*!< in: rb tree */ |
| 208 | const ib_rbt_node_t* /* in: current node */ |
| 209 | current); |
| 210 | /**********************************************************************//** |
| 211 | Search for the key, a node will be retuned in parent.last, whether it |
| 212 | was found or not. If not found then parent.last will contain the |
| 213 | parent node for the possibly new key otherwise the matching node. |
| 214 | @return result of last comparison */ |
| 215 | int |
| 216 | rbt_search( |
| 217 | /*=======*/ |
| 218 | const ib_rbt_t* tree, /*!< in: rb tree */ |
| 219 | ib_rbt_bound_t* parent, /*!< in: search bounds */ |
| 220 | const void* key); /*!< in: key to search */ |
| 221 | /**********************************************************************//** |
| 222 | Search for the key, a node will be retuned in parent.last, whether it |
| 223 | was found or not. If not found then parent.last will contain the |
| 224 | parent node for the possibly new key otherwise the matching node. |
| 225 | @return result of last comparison */ |
| 226 | int |
| 227 | rbt_search_cmp( |
| 228 | /*===========*/ |
| 229 | const ib_rbt_t* tree, /*!< in: rb tree */ |
| 230 | ib_rbt_bound_t* parent, /*!< in: search bounds */ |
| 231 | const void* key, /*!< in: key to search */ |
| 232 | ib_rbt_compare compare, /*!< in: comparator */ |
| 233 | ib_rbt_arg_compare |
| 234 | arg_compare); /*!< in: fn to compare items |
| 235 | with argument */ |
| 236 | /**********************************************************************//** |
| 237 | Merge the node from dst into src. Return the number of nodes merged. |
| 238 | @return no. of recs merged */ |
| 239 | ulint |
| 240 | rbt_merge_uniq( |
| 241 | /*===========*/ |
| 242 | ib_rbt_t* dst, /*!< in: dst rb tree */ |
| 243 | const ib_rbt_t* src); /*!< in: src rb tree */ |
| 244 | #if defined UNIV_DEBUG || defined IB_RBT_TESTING |
| 245 | /**********************************************************************//** |
| 246 | Verify the integrity of the RB tree. For debugging. 0 failure else height |
| 247 | of tree (in count of black nodes). |
| 248 | @return TRUE if OK FALSE if tree invalid. */ |
| 249 | ibool |
| 250 | rbt_validate( |
| 251 | /*=========*/ |
| 252 | const ib_rbt_t* tree); /*!< in: tree to validate */ |
| 253 | #endif /* UNIV_DEBUG || IB_RBT_TESTING */ |
| 254 | |
| 255 | #endif /* INNOBASE_UT0RBT_H */ |
| 256 | |