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