00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <apol/bst.h>
00028 #include <apol/vector.h>
00029 #include <assert.h>
00030 #include <errno.h>
00031 #include <stdlib.h>
00032 #include <string.h>
00033
00034 #include "vector-internal.h"
00035
00036 typedef struct bst_node
00037 {
00038 void *elem;
00039 int is_red;
00040 struct bst_node *child[2];
00041 } bst_node_t;
00042
00043
00044
00045
00046 struct apol_bst
00047 {
00048
00049 apol_bst_comp_func *cmp;
00050
00051 apol_bst_free_func *fr;
00052
00053 size_t size;
00054
00055 bst_node_t *head;
00056 };
00057
00058 apol_bst_t *apol_bst_create(apol_bst_comp_func * cmp, apol_bst_free_func * fr)
00059 {
00060 apol_bst_t *b = NULL;
00061 if ((b = calloc(1, sizeof(*b))) == NULL) {
00062 return NULL;
00063 }
00064 b->cmp = cmp;
00065 b->fr = fr;
00066 return b;
00067 }
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077 static void bst_node_free(bst_node_t * node, apol_bst_free_func * fr)
00078 {
00079 if (node != NULL) {
00080 if (fr != NULL) {
00081 fr(node->elem);
00082 }
00083 bst_node_free(node->child[0], fr);
00084 bst_node_free(node->child[1], fr);
00085 free(node);
00086 }
00087 }
00088
00089 void apol_bst_destroy(apol_bst_t ** b)
00090 {
00091 if (!b || !(*b))
00092 return;
00093 bst_node_free((*b)->head, (*b)->fr);
00094 (*b)->head = NULL;
00095 free(*b);
00096 *b = NULL;
00097 }
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108 static int bst_node_to_vector(bst_node_t * node, apol_vector_t * v)
00109 {
00110 int retval;
00111 if (node == NULL) {
00112 return 0;
00113 }
00114 if ((retval = bst_node_to_vector(node->child[0], v)) < 0) {
00115 return retval;
00116 }
00117 if ((retval = apol_vector_append(v, node->elem)) < 0) {
00118 return retval;
00119 }
00120 return bst_node_to_vector(node->child[1], v);
00121 }
00122
00123 apol_vector_t *apol_bst_get_vector(apol_bst_t * b, int change_owner)
00124 {
00125 apol_vector_t *v = NULL;
00126 if (!b) {
00127 errno = EINVAL;
00128 return NULL;
00129 }
00130 if ((v = apol_vector_create_with_capacity(b->size, NULL)) == NULL) {
00131 return NULL;
00132 }
00133 if (bst_node_to_vector(b->head, v) < 0) {
00134 int error = errno;
00135 apol_vector_destroy(&v);
00136 errno = error;
00137 return NULL;
00138 }
00139 if (change_owner) {
00140 vector_set_free_func(v, b->fr);
00141 b->fr = NULL;
00142 }
00143 return v;
00144 }
00145
00146 size_t apol_bst_get_size(const apol_bst_t * b)
00147 {
00148 if (!b) {
00149 errno = EINVAL;
00150 return 0;
00151 } else {
00152 return b->size;
00153 }
00154 }
00155
00156 int apol_bst_get_element(const apol_bst_t * b, const void *elem, void *data, void **result)
00157 {
00158 bst_node_t *node;
00159 int compval;
00160 if (!b || !result) {
00161 errno = EINVAL;
00162 return -1;
00163 }
00164 node = b->head;
00165 while (node != NULL) {
00166 if (b->cmp != NULL) {
00167 compval = b->cmp(node->elem, elem, data);
00168 } else {
00169 char *p1 = (char *)node->elem;
00170 char *p2 = (char *)elem;
00171 if (p1 < p2) {
00172 compval = -1;
00173 } else if (p1 > p2) {
00174 compval = 1;
00175 } else {
00176 compval = 0;
00177 }
00178 }
00179 if (compval == 0) {
00180 *result = node->elem;
00181 return 0;
00182 } else if (compval > 0) {
00183 node = node->child[0];
00184 } else {
00185 node = node->child[1];
00186 }
00187 }
00188 return -1;
00189 }
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201 static bst_node_t *bst_node_make(apol_bst_t * b, void *elem)
00202 {
00203 bst_node_t *new_node;
00204 if ((new_node = calloc(1, sizeof(*new_node))) == NULL) {
00205 return NULL;
00206 }
00207 new_node->elem = elem;
00208 new_node->is_red = 1;
00209 b->size++;
00210 return new_node;
00211 }
00212
00213
00214
00215
00216
00217
00218
00219
00220 static int bst_node_is_red(bst_node_t * node)
00221 {
00222 return node != NULL && node->is_red;
00223 }
00224
00225 static bst_node_t *bst_rotate_single(bst_node_t * root, int dir)
00226 {
00227 bst_node_t *save = root->child[!dir];
00228 root->child[!dir] = save->child[dir];
00229 save->child[dir] = root;
00230 root->is_red = 1;
00231 save->is_red = 0;
00232 return save;
00233 }
00234
00235 static bst_node_t *bst_rotate_double(bst_node_t * root, int dir)
00236 {
00237 root->child[!dir] = bst_rotate_single(root->child[!dir], !dir);
00238 return bst_rotate_single(root, dir);
00239 }
00240
00241 static bst_node_t *bst_insert_recursive(apol_bst_t * b, bst_node_t * root, void **elem, void *data, apol_bst_free_func * fr,
00242 int *not_uniq)
00243 {
00244 int compval, dir;
00245 if (root == NULL) {
00246 if ((root = bst_node_make(b, *elem)) == NULL) {
00247 *not_uniq = -1;
00248 return NULL;
00249 }
00250 *not_uniq = 0;
00251 } else {
00252 if (b->cmp != NULL) {
00253 compval = b->cmp(root->elem, *elem, data);
00254 } else {
00255 char *p1 = (char *)root->elem;
00256 char *p2 = (char *)(*elem);
00257 if (p1 < p2) {
00258 compval = -1;
00259 } else if (p1 > p2) {
00260 compval = 1;
00261 } else {
00262 compval = 0;
00263 }
00264 }
00265 if (compval == 0) {
00266
00267 if (fr != NULL) {
00268 fr(*elem);
00269 }
00270 *elem = root->elem;
00271 *not_uniq = 1;
00272 return root;
00273 } else if (compval > 0) {
00274 dir = 0;
00275 } else {
00276 dir = 1;
00277 }
00278 root->child[dir] = bst_insert_recursive(b, root->child[dir], elem, data, fr, not_uniq);
00279 if (*not_uniq != 0) {
00280 return root;
00281 }
00282
00283
00284 if (bst_node_is_red(root->child[dir])) {
00285 if (bst_node_is_red(root->child[!dir])) {
00286
00287
00288
00289 root->is_red = 1;
00290 root->child[0]->is_red = 0;
00291 root->child[1]->is_red = 0;
00292 } else {
00293 if (bst_node_is_red(root->child[dir]->child[dir])) {
00294 root = bst_rotate_single(root, !dir);
00295 } else if (bst_node_is_red(root->child[dir]->child[!dir])) {
00296 root = bst_rotate_double(root, !dir);
00297 }
00298 }
00299 }
00300 }
00301 return root;
00302 }
00303
00304 int apol_bst_insert(apol_bst_t * b, void *elem, void *data)
00305 {
00306 int retval = -1;
00307 if (!b || !elem) {
00308 errno = EINVAL;
00309 return -1;
00310 }
00311 b->head = bst_insert_recursive(b, b->head, &elem, data, NULL, &retval);
00312 if (retval >= 0) {
00313 b->head->is_red = 0;
00314 }
00315 return retval;
00316 }
00317
00318 int apol_bst_insert_and_get(apol_bst_t * b, void **elem, void *data)
00319 {
00320 int retval = -1;
00321 if (!b || !elem) {
00322 errno = EINVAL;
00323 return -1;
00324 }
00325 b->head = bst_insert_recursive(b, b->head, elem, data, b->fr, &retval);
00326 if (retval >= 0) {
00327 b->head->is_red = 0;
00328 }
00329 return retval;
00330 }
00331
00332 static int bst_inorder_map(const bst_node_t * node, int (*fn) (void *, void *), void *data)
00333 {
00334 int retval;
00335 if (node == NULL) {
00336 return 0;
00337 }
00338 if ((retval = bst_inorder_map(node->child[0], fn, data)) < 0) {
00339 return retval;
00340 }
00341 if ((retval = fn(node->elem, data)) < 0) {
00342 return retval;
00343 }
00344 return bst_inorder_map(node->child[1], fn, data);
00345 }
00346
00347 int apol_bst_inorder_map(const apol_bst_t * b, int (*fn) (void *, void *), void *data)
00348 {
00349 if (b == NULL || fn == NULL)
00350 return -1;
00351 return bst_inorder_map(b->head, fn, data);
00352 }