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 #ifdef HAVE_CONFIG_H
00028 #include "config.h"
00029 #endif
00030
00031 #ifdef HAVE_STDLIB_H
00032 #include <stdlib.h>
00033 #endif
00034
00035 #include <stdio.h>
00036
00037 #include "libiberty.h"
00038 #include "splay-tree.h"
00039
00040 static void splay_tree_delete_helper (splay_tree, splay_tree_node);
00041 static inline void rotate_left (splay_tree_node *,
00042 splay_tree_node, splay_tree_node);
00043 static inline void rotate_right (splay_tree_node *,
00044 splay_tree_node, splay_tree_node);
00045 static void splay_tree_splay (splay_tree, splay_tree_key);
00046 static int splay_tree_foreach_helper (splay_tree, splay_tree_node,
00047 splay_tree_foreach_fn, void*);
00048
00049
00050
00051 static void
00052 splay_tree_delete_helper (splay_tree sp, splay_tree_node node)
00053 {
00054 splay_tree_node pending = 0;
00055 splay_tree_node active = 0;
00056
00057 if (!node)
00058 return;
00059
00060 #define KDEL(x) if (sp->delete_key) (*sp->delete_key)(x);
00061 #define VDEL(x) if (sp->delete_value) (*sp->delete_value)(x);
00062
00063 KDEL (node->key);
00064 VDEL (node->value);
00065
00066
00067 node->key = (splay_tree_key)pending;
00068 pending = (splay_tree_node)node;
00069
00070
00071
00072
00073
00074 while (pending)
00075 {
00076 active = pending;
00077 pending = 0;
00078 while (active)
00079 {
00080 splay_tree_node temp;
00081
00082
00083
00084
00085 if (active->left)
00086 {
00087 KDEL (active->left->key);
00088 VDEL (active->left->value);
00089 active->left->key = (splay_tree_key)pending;
00090 pending = (splay_tree_node)(active->left);
00091 }
00092 if (active->right)
00093 {
00094 KDEL (active->right->key);
00095 VDEL (active->right->value);
00096 active->right->key = (splay_tree_key)pending;
00097 pending = (splay_tree_node)(active->right);
00098 }
00099
00100 temp = active;
00101 active = (splay_tree_node)(temp->key);
00102 (*sp->deallocate) ((char*) temp, sp->allocate_data);
00103 }
00104 }
00105 #undef KDEL
00106 #undef VDEL
00107 }
00108
00109
00110
00111
00112 static inline void
00113 rotate_left (splay_tree_node *pp, splay_tree_node p, splay_tree_node n)
00114 {
00115 splay_tree_node tmp;
00116 tmp = n->right;
00117 n->right = p;
00118 p->left = tmp;
00119 *pp = n;
00120 }
00121
00122
00123
00124
00125 static inline void
00126 rotate_right (splay_tree_node *pp, splay_tree_node p, splay_tree_node n)
00127 {
00128 splay_tree_node tmp;
00129 tmp = n->left;
00130 n->left = p;
00131 p->right = tmp;
00132 *pp = n;
00133 }
00134
00135
00136
00137 static void
00138 splay_tree_splay (splay_tree sp, splay_tree_key key)
00139 {
00140 if (sp->root == 0)
00141 return;
00142
00143 do {
00144 int cmp1, cmp2;
00145 splay_tree_node n, c;
00146
00147 n = sp->root;
00148 cmp1 = (*sp->comp) (key, n->key);
00149
00150
00151 if (cmp1 == 0)
00152 return;
00153
00154
00155 if (cmp1 < 0)
00156 c = n->left;
00157 else
00158 c = n->right;
00159 if (!c)
00160 return;
00161
00162
00163
00164 cmp2 = (*sp->comp) (key, c->key);
00165 if (cmp2 == 0
00166 || (cmp2 < 0 && !c->left)
00167 || (cmp2 > 0 && !c->right))
00168 {
00169 if (cmp1 < 0)
00170 rotate_left (&sp->root, n, c);
00171 else
00172 rotate_right (&sp->root, n, c);
00173 return;
00174 }
00175
00176
00177 if (cmp1 < 0 && cmp2 < 0)
00178 {
00179 rotate_left (&n->left, c, c->left);
00180 rotate_left (&sp->root, n, n->left);
00181 }
00182 else if (cmp1 > 0 && cmp2 > 0)
00183 {
00184 rotate_right (&n->right, c, c->right);
00185 rotate_right (&sp->root, n, n->right);
00186 }
00187 else if (cmp1 < 0 && cmp2 > 0)
00188 {
00189 rotate_right (&n->left, c, c->right);
00190 rotate_left (&sp->root, n, n->left);
00191 }
00192 else if (cmp1 > 0 && cmp2 < 0)
00193 {
00194 rotate_left (&n->right, c, c->left);
00195 rotate_right (&sp->root, n, n->right);
00196 }
00197 } while (1);
00198 }
00199
00200
00201
00202
00203
00204
00205 static int
00206 splay_tree_foreach_helper (splay_tree sp, splay_tree_node node,
00207 splay_tree_foreach_fn fn, void *data)
00208 {
00209 int val;
00210
00211 if (!node)
00212 return 0;
00213
00214 val = splay_tree_foreach_helper (sp, node->left, fn, data);
00215 if (val)
00216 return val;
00217
00218 val = (*fn)(node, data);
00219 if (val)
00220 return val;
00221
00222 return splay_tree_foreach_helper (sp, node->right, fn, data);
00223 }
00224
00225
00226
00227 static void *
00228 splay_tree_xmalloc_allocate (int size, void *data ATTRIBUTE_UNUSED)
00229 {
00230 return (void *) xmalloc (size);
00231 }
00232
00233 static void
00234 splay_tree_xmalloc_deallocate (void *object, void *data ATTRIBUTE_UNUSED)
00235 {
00236 free (object);
00237 }
00238
00239
00240
00241
00242
00243
00244
00245 splay_tree
00246 splay_tree_new (splay_tree_compare_fn compare_fn,
00247 splay_tree_delete_key_fn delete_key_fn,
00248 splay_tree_delete_value_fn delete_value_fn)
00249 {
00250 return (splay_tree_new_with_allocator
00251 (compare_fn, delete_key_fn, delete_value_fn,
00252 splay_tree_xmalloc_allocate, splay_tree_xmalloc_deallocate, 0));
00253 }
00254
00255
00256
00257
00258
00259
00260 splay_tree
00261 splay_tree_new_with_allocator (splay_tree_compare_fn compare_fn,
00262 splay_tree_delete_key_fn delete_key_fn,
00263 splay_tree_delete_value_fn delete_value_fn,
00264 splay_tree_allocate_fn allocate_fn,
00265 splay_tree_deallocate_fn deallocate_fn,
00266 void *allocate_data)
00267 {
00268 splay_tree sp = (splay_tree) (*allocate_fn) (sizeof (struct splay_tree_s),
00269 allocate_data);
00270 sp->root = 0;
00271 sp->comp = compare_fn;
00272 sp->delete_key = delete_key_fn;
00273 sp->delete_value = delete_value_fn;
00274 sp->allocate = allocate_fn;
00275 sp->deallocate = deallocate_fn;
00276 sp->allocate_data = allocate_data;
00277
00278 return sp;
00279 }
00280
00281
00282
00283 void
00284 splay_tree_delete (splay_tree sp)
00285 {
00286 splay_tree_delete_helper (sp, sp->root);
00287 (*sp->deallocate) ((char*) sp, sp->allocate_data);
00288 }
00289
00290
00291
00292
00293
00294 splay_tree_node
00295 splay_tree_insert (splay_tree sp, splay_tree_key key, splay_tree_value value)
00296 {
00297 int comparison = 0;
00298
00299 splay_tree_splay (sp, key);
00300
00301 if (sp->root)
00302 comparison = (*sp->comp)(sp->root->key, key);
00303
00304 if (sp->root && comparison == 0)
00305 {
00306
00307
00308 if (sp->delete_value)
00309 (*sp->delete_value)(sp->root->value);
00310 sp->root->value = value;
00311 }
00312 else
00313 {
00314
00315 splay_tree_node node;
00316
00317 node = ((splay_tree_node)
00318 (*sp->allocate) (sizeof (struct splay_tree_node_s),
00319 sp->allocate_data));
00320 node->key = key;
00321 node->value = value;
00322
00323 if (!sp->root)
00324 node->left = node->right = 0;
00325 else if (comparison < 0)
00326 {
00327 node->left = sp->root;
00328 node->right = node->left->right;
00329 node->left->right = 0;
00330 }
00331 else
00332 {
00333 node->right = sp->root;
00334 node->left = node->right->left;
00335 node->right->left = 0;
00336 }
00337
00338 sp->root = node;
00339 }
00340
00341 return sp->root;
00342 }
00343
00344
00345
00346 void
00347 splay_tree_remove (splay_tree sp, splay_tree_key key)
00348 {
00349 splay_tree_splay (sp, key);
00350
00351 if (sp->root && (*sp->comp) (sp->root->key, key) == 0)
00352 {
00353 splay_tree_node left, right;
00354
00355 left = sp->root->left;
00356 right = sp->root->right;
00357
00358
00359 if (sp->delete_value)
00360 (*sp->delete_value) (sp->root->value);
00361 (*sp->deallocate) (sp->root, sp->allocate_data);
00362
00363
00364
00365 if (left)
00366 {
00367 sp->root = left;
00368
00369
00370
00371 if (right)
00372 {
00373 while (left->right)
00374 left = left->right;
00375 left->right = right;
00376 }
00377 }
00378 else
00379 sp->root = right;
00380 }
00381 }
00382
00383
00384
00385
00386 splay_tree_node
00387 splay_tree_lookup (splay_tree sp, splay_tree_key key)
00388 {
00389 splay_tree_splay (sp, key);
00390
00391 if (sp->root && (*sp->comp)(sp->root->key, key) == 0)
00392 return sp->root;
00393 else
00394 return 0;
00395 }
00396
00397
00398
00399 splay_tree_node
00400 splay_tree_max (splay_tree sp)
00401 {
00402 splay_tree_node n = sp->root;
00403
00404 if (!n)
00405 return NULL;
00406
00407 while (n->right)
00408 n = n->right;
00409
00410 return n;
00411 }
00412
00413
00414
00415 splay_tree_node
00416 splay_tree_min (splay_tree sp)
00417 {
00418 splay_tree_node n = sp->root;
00419
00420 if (!n)
00421 return NULL;
00422
00423 while (n->left)
00424 n = n->left;
00425
00426 return n;
00427 }
00428
00429
00430
00431
00432 splay_tree_node
00433 splay_tree_predecessor (splay_tree sp, splay_tree_key key)
00434 {
00435 int comparison;
00436 splay_tree_node node;
00437
00438
00439 if (!sp->root)
00440 return NULL;
00441
00442
00443
00444 splay_tree_splay (sp, key);
00445 comparison = (*sp->comp)(sp->root->key, key);
00446
00447
00448 if (comparison < 0)
00449 return sp->root;
00450
00451
00452 node = sp->root->left;
00453 if (node)
00454 while (node->right)
00455 node = node->right;
00456
00457 return node;
00458 }
00459
00460
00461
00462
00463 splay_tree_node
00464 splay_tree_successor (splay_tree sp, splay_tree_key key)
00465 {
00466 int comparison;
00467 splay_tree_node node;
00468
00469
00470 if (!sp->root)
00471 return NULL;
00472
00473
00474
00475 splay_tree_splay (sp, key);
00476 comparison = (*sp->comp)(sp->root->key, key);
00477
00478
00479 if (comparison > 0)
00480 return sp->root;
00481
00482
00483 node = sp->root->right;
00484 if (node)
00485 while (node->left)
00486 node = node->left;
00487
00488 return node;
00489 }
00490
00491
00492
00493
00494
00495
00496 int
00497 splay_tree_foreach (splay_tree sp, splay_tree_foreach_fn fn, void *data)
00498 {
00499 return splay_tree_foreach_helper (sp, sp->root, fn, data);
00500 }
00501
00502
00503
00504 int
00505 splay_tree_compare_ints (splay_tree_key k1, splay_tree_key k2)
00506 {
00507 if ((int) k1 < (int) k2)
00508 return -1;
00509 else if ((int) k1 > (int) k2)
00510 return 1;
00511 else
00512 return 0;
00513 }
00514
00515
00516
00517 int
00518 splay_tree_compare_pointers (splay_tree_key k1, splay_tree_key k2)
00519 {
00520 if ((char*) k1 < (char*) k2)
00521 return -1;
00522 else if ((char*) k1 > (char*) k2)
00523 return 1;
00524 else
00525 return 0;
00526 }