1 /* 2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 % % 4 % % 5 % % 6 % SSSSS PPPP L AAA Y Y % 7 % SS P P L A A Y Y % 8 % SSS PPPP L AAAAA Y % 9 % SS P L A A Y % 10 % SSSSS P LLLLL A A Y % 11 % % 12 % TTTTT RRRR EEEEE EEEEE % 13 % T R R E E % 14 % T RRRR EEE EEE % 15 % T R R E E % 16 % T R R EEEEE EEEEE % 17 % % 18 % % 19 % MagickCore Self-adjusting Binary Search Tree Methods % 20 % % 21 % Software Design % 22 % Cristy % 23 % December 2002 % 24 % % 25 % % 26 % Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization % 27 % dedicated to making software imaging solutions freely available. % 28 % % 29 % You may not use this file except in compliance with the License. You may % 30 % obtain a copy of the License at % 31 % % 32 % http://www.imagemagick.org/script/license.php % 33 % % 34 % Unless required by applicable law or agreed to in writing, software % 35 % distributed under the License is distributed on an "AS IS" BASIS, % 36 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % 37 % See the License for the specific language governing permissions and % 38 % limitations under the License. % 39 % % 40 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 41 % 42 % This module implements the standard handy splay-tree methods for storing and 43 % retrieving large numbers of data elements. It is loosely based on the Java 44 % implementation of these algorithms. 45 % 46 */ 47 48 /* 50 Include declarations. 51 */ 52 #include "MagickCore/studio.h" 53 #include "MagickCore/exception.h" 54 #include "MagickCore/exception-private.h" 55 #include "MagickCore/locale_.h" 56 #include "MagickCore/log.h" 57 #include "MagickCore/memory_.h" 58 #include "MagickCore/splay-tree.h" 59 #include "MagickCore/semaphore.h" 60 #include "MagickCore/string_.h" 61 62 /* 64 Define declarations. 65 */ 66 #define MaxSplayTreeDepth 1024 67 68 /* 70 Typedef declarations. 71 */ 72 typedef struct _NodeInfo 73 { 74 void 75 *key; 76 77 void 78 *value; 79 80 struct _NodeInfo 81 *left, 82 *right; 83 } NodeInfo; 84 85 struct _SplayTreeInfo 86 { 87 NodeInfo 88 *root; 89 90 int 91 (*compare)(const void *,const void *); 92 93 void 94 *(*relinquish_key)(void *), 95 *(*relinquish_value)(void *); 96 97 MagickBooleanType 98 balance; 99 100 void 101 *key, 102 *next; 103 104 size_t 105 nodes; 106 107 MagickBooleanType 108 debug; 109 110 SemaphoreInfo 111 *semaphore; 112 113 size_t 114 signature; 115 }; 116 117 /* 119 Forward declarations. 120 */ 121 static int 122 IterateOverSplayTree(SplayTreeInfo *,int (*)(NodeInfo *,const void *), 123 const void *); 124 125 static void 126 SplaySplayTree(SplayTreeInfo *,const void *); 127 128 /* 130 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 131 % % 132 % % 133 % % 134 % A d d V a l u e T o S p l a y T r e e % 135 % % 136 % % 137 % % 138 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 139 % 140 % AddValueToSplayTree() adds the given key and value to the splay-tree. Both 141 % key and value are used as is, without coping or cloning. It returns 142 % MagickTrue on success, otherwise MagickFalse. 143 % 144 % The format of the AddValueToSplayTree method is: 145 % 146 % MagickBooleanType AddValueToSplayTree(SplayTreeInfo *splay_tree, 147 % const void *key,const void *value) 148 % 149 % A description of each parameter follows: 150 % 151 % o splay_tree: the splay-tree info. 152 % 153 % o key: the key. 154 % 155 % o value: the value. 156 % 157 */ 158 MagickExport MagickBooleanType AddValueToSplayTree(SplayTreeInfo *splay_tree, 159 const void *key,const void *value) 160 { 161 int 162 compare; 163 164 register NodeInfo 165 *node; 166 167 LockSemaphoreInfo(splay_tree->semaphore); 168 SplaySplayTree(splay_tree,key); 169 compare=0; 170 if (splay_tree->root != (NodeInfo *) NULL) 171 { 172 if (splay_tree->compare != (int (*)(const void *,const void *)) NULL) 173 compare=splay_tree->compare(splay_tree->root->key,key); 174 else 175 compare=(splay_tree->root->key > key) ? 1 : 176 ((splay_tree->root->key < key) ? -1 : 0); 177 if (compare == 0) 178 { 179 if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) && 180 (splay_tree->root->value != (void *) NULL)) 181 splay_tree->root->value=splay_tree->relinquish_value( 182 splay_tree->root->value); 183 if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) && 184 (splay_tree->root->key != (void *) NULL)) 185 splay_tree->root->key=splay_tree->relinquish_key( 186 splay_tree->root->key); 187 splay_tree->root->key=(void *) key; 188 splay_tree->root->value=(void *) value; 189 UnlockSemaphoreInfo(splay_tree->semaphore); 190 return(MagickTrue); 191 } 192 } 193 node=(NodeInfo *) AcquireMagickMemory(sizeof(*node)); 194 if (node == (NodeInfo *) NULL) 195 { 196 UnlockSemaphoreInfo(splay_tree->semaphore); 197 return(MagickFalse); 198 } 199 node->key=(void *) key; 200 node->value=(void *) value; 201 if (splay_tree->root == (NodeInfo *) NULL) 202 { 203 node->left=(NodeInfo *) NULL; 204 node->right=(NodeInfo *) NULL; 205 } 206 else 207 if (compare < 0) 208 { 209 node->left=splay_tree->root; 210 node->right=node->left->right; 211 node->left->right=(NodeInfo *) NULL; 212 } 213 else 214 { 215 node->right=splay_tree->root; 216 node->left=node->right->left; 217 node->right->left=(NodeInfo *) NULL; 218 } 219 splay_tree->root=node; 220 splay_tree->key=(void *) NULL; 221 splay_tree->nodes++; 222 UnlockSemaphoreInfo(splay_tree->semaphore); 223 return(MagickTrue); 224 } 225 226 /* 228 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 229 % % 230 % % 231 % % 232 % B a l a n c e S p l a y T r e e % 233 % % 234 % % 235 % % 236 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 237 % 238 % BalanceSplayTree() balances the splay-tree. 239 % 240 % The format of the BalanceSplayTree method is: 241 % 242 % void *BalanceSplayTree(SplayTreeInfo *splay_tree,const void *key) 243 % 244 % A description of each parameter follows: 245 % 246 % o splay_tree: the splay-tree info. 247 % 248 % o key: the key. 249 % 250 */ 251 252 static NodeInfo *LinkSplayTreeNodes(NodeInfo **nodes,const size_t low, 253 const size_t high) 254 { 255 register NodeInfo 256 *node; 257 258 size_t 259 bisect; 260 261 bisect=low+(high-low)/2; 262 node=nodes[bisect]; 263 if ((low+1) > bisect) 264 node->left=(NodeInfo *) NULL; 265 else 266 node->left=LinkSplayTreeNodes(nodes,low,bisect-1); 267 if ((bisect+1) > high) 268 node->right=(NodeInfo *) NULL; 269 else 270 node->right=LinkSplayTreeNodes(nodes,bisect+1,high); 271 return(node); 272 } 273 274 static inline int SplayTreeToNodeArray(NodeInfo *node,const void *nodes) 275 { 276 register const NodeInfo 277 ***p; 278 279 p=(const NodeInfo ***) nodes; 280 *(*p)=node; 281 (*p)++; 282 return(0); 283 } 284 285 static void BalanceSplayTree(SplayTreeInfo *splay_tree) 286 { 287 NodeInfo 288 **node, 289 **nodes; 290 291 if (splay_tree->nodes <= 2) 292 { 293 splay_tree->balance=MagickFalse; 294 return; 295 } 296 nodes=(NodeInfo **) AcquireQuantumMemory((size_t) splay_tree->nodes, 297 sizeof(*nodes)); 298 if (nodes == (NodeInfo **) NULL) 299 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); 300 node=nodes; 301 (void) IterateOverSplayTree(splay_tree,SplayTreeToNodeArray,(const void *) 302 &node); 303 splay_tree->root=LinkSplayTreeNodes(nodes,0,splay_tree->nodes-1); 304 splay_tree->balance=MagickFalse; 305 nodes=(NodeInfo **) RelinquishMagickMemory(nodes); 306 } 307 308 /* 310 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 311 % % 312 % % 313 % % 314 % C l o n e S p l a y T r e e % 315 % % 316 % % 317 % % 318 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 319 % 320 % CloneSplayTree() clones the splay tree. 321 % 322 % The format of the CloneSplayTree method is: 323 % 324 % SplayTreeInfo *CloneSplayTree(SplayTreeInfo *splay_tree, 325 % void *(*clone_key)(void *),void *(*cline_value)(void *)) 326 % 327 % A description of each parameter follows: 328 % 329 % o splay_tree: the splay tree. 330 % 331 % o clone_key: the key clone method, typically ConstantString(), called 332 % whenever a key is added to the splay-tree. 333 % 334 % o clone_value: the value clone method; typically ConstantString(), called 335 % whenever a value object is added to the splay-tree. 336 % 337 */ 338 339 static inline void *GetFirstSplayTreeNode(SplayTreeInfo *splay_tree) 340 { 341 register NodeInfo 342 *node; 343 344 node=splay_tree->root; 345 if (splay_tree->root == (NodeInfo *) NULL) 346 return((NodeInfo *) NULL); 347 while (node->left != (NodeInfo *) NULL) 348 node=node->left; 349 return(node->key); 350 } 351 352 MagickExport SplayTreeInfo *CloneSplayTree(SplayTreeInfo *splay_tree, 353 void *(*clone_key)(void *),void *(*clone_value)(void *)) 354 { 355 register NodeInfo 356 *next, 357 *node; 358 359 SplayTreeInfo 360 *clone_tree; 361 362 assert(splay_tree != (SplayTreeInfo *) NULL); 363 assert(splay_tree->signature == MagickCoreSignature); 364 if (splay_tree->debug != MagickFalse) 365 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 366 clone_tree=NewSplayTree(splay_tree->compare,splay_tree->relinquish_key, 367 splay_tree->relinquish_value); 368 LockSemaphoreInfo(splay_tree->semaphore); 369 if (splay_tree->root == (NodeInfo *) NULL) 370 { 371 UnlockSemaphoreInfo(splay_tree->semaphore); 372 return(clone_tree); 373 } 374 next=(NodeInfo *) GetFirstSplayTreeNode(splay_tree); 375 while (next != (NodeInfo *) NULL) 376 { 377 SplaySplayTree(splay_tree,next); 378 (void) AddValueToSplayTree(clone_tree,clone_key(splay_tree->root->key), 379 clone_value(splay_tree->root->value)); 380 next=(NodeInfo *) NULL; 381 node=splay_tree->root->right; 382 if (node != (NodeInfo *) NULL) 383 { 384 while (node->left != (NodeInfo *) NULL) 385 node=node->left; 386 next=(NodeInfo *) node->key; 387 } 388 } 389 UnlockSemaphoreInfo(splay_tree->semaphore); 390 return(clone_tree); 391 } 392 393 /* 395 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 396 % % 397 % % 398 % % 399 % C o m p a r e S p l a y T r e e S t r i n g % 400 % % 401 % % 402 % % 403 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 404 % 405 % CompareSplayTreeString() method finds a node in a splay-tree based on the 406 % contents of a string. 407 % 408 % The format of the CompareSplayTreeString method is: 409 % 410 % int CompareSplayTreeString(const void *target,const void *source) 411 % 412 % A description of each parameter follows: 413 % 414 % o target: the target string. 415 % 416 % o source: the source string. 417 % 418 */ 419 MagickExport int CompareSplayTreeString(const void *target,const void *source) 420 { 421 const char 422 *p, 423 *q; 424 425 p=(const char *) target; 426 q=(const char *) source; 427 return(LocaleCompare(p,q)); 428 } 429 430 /* 432 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 433 % % 434 % % 435 % % 436 % C o m p a r e S p l a y T r e e S t r i n g I n f o % 437 % % 438 % % 439 % % 440 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 441 % 442 % CompareSplayTreeStringInfo() finds a node in a splay-tree based on the 443 % contents of a string. 444 % 445 % The format of the CompareSplayTreeStringInfo method is: 446 % 447 % int CompareSplayTreeStringInfo(const void *target,const void *source) 448 % 449 % A description of each parameter follows: 450 % 451 % o target: the target string. 452 % 453 % o source: the source string. 454 % 455 */ 456 MagickExport int CompareSplayTreeStringInfo(const void *target, 457 const void *source) 458 { 459 const StringInfo 460 *p, 461 *q; 462 463 p=(const StringInfo *) target; 464 q=(const StringInfo *) source; 465 return(CompareStringInfo(p,q)); 466 } 467 468 /* 470 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 471 % % 472 % % 473 % % 474 % D e l e t e N o d e B y V a l u e F r o m S p l a y T r e e % 475 % % 476 % % 477 % % 478 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 479 % 480 % DeleteNodeByValueFromSplayTree() deletes a node by value from the 481 % splay-tree. 482 % 483 % The format of the DeleteNodeByValueFromSplayTree method is: 484 % 485 % MagickBooleanType DeleteNodeByValueFromSplayTree( 486 % SplayTreeInfo *splay_tree,const void *value) 487 % 488 % A description of each parameter follows: 489 % 490 % o splay_tree: the splay-tree info. 491 % 492 % o value: the value. 493 % 494 */ 495 MagickExport MagickBooleanType DeleteNodeByValueFromSplayTree( 496 SplayTreeInfo *splay_tree,const void *value) 497 { 498 register NodeInfo 499 *next, 500 *node; 501 502 assert(splay_tree != (SplayTreeInfo *) NULL); 503 assert(splay_tree->signature == MagickCoreSignature); 504 if (splay_tree->debug != MagickFalse) 505 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 506 LockSemaphoreInfo(splay_tree->semaphore); 507 if (splay_tree->root == (NodeInfo *) NULL) 508 { 509 UnlockSemaphoreInfo(splay_tree->semaphore); 510 return(MagickFalse); 511 } 512 next=(NodeInfo *) GetFirstSplayTreeNode(splay_tree); 513 while (next != (NodeInfo *) NULL) 514 { 515 SplaySplayTree(splay_tree,next); 516 next=(NodeInfo *) NULL; 517 node=splay_tree->root->right; 518 if (node != (NodeInfo *) NULL) 519 { 520 while (node->left != (NodeInfo *) NULL) 521 node=node->left; 522 next=(NodeInfo *) node->key; 523 } 524 if (splay_tree->root->value == value) 525 { 526 int 527 compare; 528 529 register NodeInfo 530 *left, 531 *right; 532 533 void 534 *key; 535 536 /* 537 We found the node that matches the value; now delete it. 538 */ 539 key=splay_tree->root->key; 540 SplaySplayTree(splay_tree,key); 541 splay_tree->key=(void *) NULL; 542 if (splay_tree->compare != (int (*)(const void *,const void *)) NULL) 543 compare=splay_tree->compare(splay_tree->root->key,key); 544 else 545 compare=(splay_tree->root->key > key) ? 1 : 546 ((splay_tree->root->key < key) ? -1 : 0); 547 if (compare != 0) 548 { 549 UnlockSemaphoreInfo(splay_tree->semaphore); 550 return(MagickFalse); 551 } 552 left=splay_tree->root->left; 553 right=splay_tree->root->right; 554 if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) && 555 (splay_tree->root->value != (void *) NULL)) 556 splay_tree->root->value=splay_tree->relinquish_value( 557 splay_tree->root->value); 558 if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) && 559 (splay_tree->root->key != (void *) NULL)) 560 splay_tree->root->key=splay_tree->relinquish_key( 561 splay_tree->root->key); 562 splay_tree->root=(NodeInfo *) RelinquishMagickMemory(splay_tree->root); 563 splay_tree->nodes--; 564 if (left == (NodeInfo *) NULL) 565 { 566 splay_tree->root=right; 567 UnlockSemaphoreInfo(splay_tree->semaphore); 568 return(MagickTrue); 569 } 570 splay_tree->root=left; 571 if (right != (NodeInfo *) NULL) 572 { 573 while (left->right != (NodeInfo *) NULL) 574 left=left->right; 575 left->right=right; 576 } 577 UnlockSemaphoreInfo(splay_tree->semaphore); 578 return(MagickTrue); 579 } 580 } 581 UnlockSemaphoreInfo(splay_tree->semaphore); 582 return(MagickFalse); 583 } 584 585 /* 587 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 588 % % 589 % % 590 % % 591 % D e l e t e N o d e F r o m S p l a y T r e e % 592 % % 593 % % 594 % % 595 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 596 % 597 % DeleteNodeFromSplayTree() deletes a node from the splay-tree. It returns 598 % MagickTrue if the option is found and successfully deleted from the 599 % splay-tree. 600 % 601 % The format of the DeleteNodeFromSplayTree method is: 602 % 603 % MagickBooleanType DeleteNodeFromSplayTree(SplayTreeInfo *splay_tree, 604 % const void *key) 605 % 606 % A description of each parameter follows: 607 % 608 % o splay_tree: the splay-tree info. 609 % 610 % o key: the key. 611 % 612 */ 613 MagickExport MagickBooleanType DeleteNodeFromSplayTree( 614 SplayTreeInfo *splay_tree,const void *key) 615 { 616 int 617 compare; 618 619 register NodeInfo 620 *left, 621 *right; 622 623 assert(splay_tree != (SplayTreeInfo *) NULL); 624 assert(splay_tree->signature == MagickCoreSignature); 625 if (splay_tree->debug != MagickFalse) 626 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 627 if (splay_tree->root == (NodeInfo *) NULL) 628 return(MagickFalse); 629 LockSemaphoreInfo(splay_tree->semaphore); 630 SplaySplayTree(splay_tree,key); 631 splay_tree->key=(void *) NULL; 632 if (splay_tree->compare != (int (*)(const void *,const void *)) NULL) 633 compare=splay_tree->compare(splay_tree->root->key,key); 634 else 635 compare=(splay_tree->root->key > key) ? 1 : 636 ((splay_tree->root->key < key) ? -1 : 0); 637 if (compare != 0) 638 { 639 UnlockSemaphoreInfo(splay_tree->semaphore); 640 return(MagickFalse); 641 } 642 left=splay_tree->root->left; 643 right=splay_tree->root->right; 644 if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) && 645 (splay_tree->root->value != (void *) NULL)) 646 splay_tree->root->value=splay_tree->relinquish_value( 647 splay_tree->root->value); 648 if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) && 649 (splay_tree->root->key != (void *) NULL)) 650 splay_tree->root->key=splay_tree->relinquish_key(splay_tree->root->key); 651 splay_tree->root=(NodeInfo *) RelinquishMagickMemory(splay_tree->root); 652 splay_tree->nodes--; 653 if (left == (NodeInfo *) NULL) 654 { 655 splay_tree->root=right; 656 UnlockSemaphoreInfo(splay_tree->semaphore); 657 return(MagickTrue); 658 } 659 splay_tree->root=left; 660 if (right != (NodeInfo *) NULL) 661 { 662 while (left->right != (NodeInfo *) NULL) 663 left=left->right; 664 left->right=right; 665 } 666 UnlockSemaphoreInfo(splay_tree->semaphore); 667 return(MagickTrue); 668 } 669 670 /* 672 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 673 % % 674 % % 675 % % 676 % D e s t r o y S p l a y T r e e % 677 % % 678 % % 679 % % 680 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 681 % 682 % DestroySplayTree() destroys the splay-tree. 683 % 684 % The format of the DestroySplayTree method is: 685 % 686 % SplayTreeInfo *DestroySplayTree(SplayTreeInfo *splay_tree) 687 % 688 % A description of each parameter follows: 689 % 690 % o splay_tree: the splay tree. 691 % 692 */ 693 MagickExport SplayTreeInfo *DestroySplayTree(SplayTreeInfo *splay_tree) 694 { 695 NodeInfo 696 *node; 697 698 register NodeInfo 699 *active, 700 *pend; 701 702 LockSemaphoreInfo(splay_tree->semaphore); 703 if (splay_tree->root != (NodeInfo *) NULL) 704 { 705 if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) && 706 (splay_tree->root->value != (void *) NULL)) 707 splay_tree->root->value=splay_tree->relinquish_value( 708 splay_tree->root->value); 709 if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) && 710 (splay_tree->root->key != (void *) NULL)) 711 splay_tree->root->key=splay_tree->relinquish_key(splay_tree->root->key); 712 splay_tree->root->key=(void *) NULL; 713 for (pend=splay_tree->root; pend != (NodeInfo *) NULL; ) 714 { 715 active=pend; 716 for (pend=(NodeInfo *) NULL; active != (NodeInfo *) NULL; ) 717 { 718 if (active->left != (NodeInfo *) NULL) 719 { 720 if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) && 721 (active->left->value != (void *) NULL)) 722 active->left->value=splay_tree->relinquish_value( 723 active->left->value); 724 if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) && 725 (active->left->key != (void *) NULL)) 726 active->left->key=splay_tree->relinquish_key(active->left->key); 727 active->left->key=(void *) pend; 728 pend=active->left; 729 } 730 if (active->right != (NodeInfo *) NULL) 731 { 732 if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) && 733 (active->right->value != (void *) NULL)) 734 active->right->value=splay_tree->relinquish_value( 735 active->right->value); 736 if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) && 737 (active->right->key != (void *) NULL)) 738 active->right->key=splay_tree->relinquish_key( 739 active->right->key); 740 active->right->key=(void *) pend; 741 pend=active->right; 742 } 743 node=active; 744 active=(NodeInfo *) node->key; 745 node=(NodeInfo *) RelinquishMagickMemory(node); 746 } 747 } 748 } 749 splay_tree->signature=(~MagickCoreSignature); 750 UnlockSemaphoreInfo(splay_tree->semaphore); 751 RelinquishSemaphoreInfo(&splay_tree->semaphore); 752 splay_tree=(SplayTreeInfo *) RelinquishMagickMemory(splay_tree); 753 return(splay_tree); 754 } 755 756 /* 758 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 759 % % 760 % % 761 % % 762 % G e t N e x t K e y I n S p l a y T r e e % 763 % % 764 % % 765 % % 766 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 767 % 768 % GetNextKeyInSplayTree() gets the next key in the splay-tree. 769 % 770 % The format of the GetNextKeyInSplayTree method is: 771 % 772 % const void *GetNextKeyInSplayTree(SplayTreeInfo *splay_tree) 773 % 774 % A description of each parameter follows: 775 % 776 % o splay_tree: the splay tree. 777 % 778 % o key: the key. 779 % 780 */ 781 MagickExport const void *GetNextKeyInSplayTree(SplayTreeInfo *splay_tree) 782 { 783 register NodeInfo 784 *node; 785 786 void 787 *key; 788 789 assert(splay_tree != (SplayTreeInfo *) NULL); 790 assert(splay_tree->signature == MagickCoreSignature); 791 if (splay_tree->debug != MagickFalse) 792 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 793 if ((splay_tree->root == (NodeInfo *) NULL) || 794 (splay_tree->next == (void *) NULL)) 795 return((void *) NULL); 796 LockSemaphoreInfo(splay_tree->semaphore); 797 SplaySplayTree(splay_tree,splay_tree->next); 798 splay_tree->next=(void *) NULL; 799 node=splay_tree->root->right; 800 if (node != (NodeInfo *) NULL) 801 { 802 while (node->left != (NodeInfo *) NULL) 803 node=node->left; 804 splay_tree->next=node->key; 805 } 806 key=splay_tree->root->key; 807 UnlockSemaphoreInfo(splay_tree->semaphore); 808 return(key); 809 } 810 811 /* 813 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 814 % % 815 % % 816 % % 817 % G e t N e x t V a l u e I n S p l a y T r e e % 818 % % 819 % % 820 % % 821 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 822 % 823 % GetNextValueInSplayTree() gets the next value in the splay-tree. 824 % 825 % The format of the GetNextValueInSplayTree method is: 826 % 827 % const void *GetNextValueInSplayTree(SplayTreeInfo *splay_tree) 828 % 829 % A description of each parameter follows: 830 % 831 % o splay_tree: the splay tree. 832 % 833 % o key: the key. 834 % 835 */ 836 MagickExport const void *GetNextValueInSplayTree(SplayTreeInfo *splay_tree) 837 { 838 register NodeInfo 839 *node; 840 841 void 842 *value; 843 844 assert(splay_tree != (SplayTreeInfo *) NULL); 845 assert(splay_tree->signature == MagickCoreSignature); 846 if (splay_tree->debug != MagickFalse) 847 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 848 if ((splay_tree->root == (NodeInfo *) NULL) || 849 (splay_tree->next == (void *) NULL)) 850 return((void *) NULL); 851 LockSemaphoreInfo(splay_tree->semaphore); 852 SplaySplayTree(splay_tree,splay_tree->next); 853 splay_tree->next=(void *) NULL; 854 node=splay_tree->root->right; 855 if (node != (NodeInfo *) NULL) 856 { 857 while (node->left != (NodeInfo *) NULL) 858 node=node->left; 859 splay_tree->next=node->key; 860 } 861 value=splay_tree->root->value; 862 UnlockSemaphoreInfo(splay_tree->semaphore); 863 return(value); 864 } 865 866 /* 868 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 869 % % 870 % % 871 % % 872 % G e t V a l u e F r o m S p l a y T r e e % 873 % % 874 % % 875 % % 876 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 877 % 878 % GetValueFromSplayTree() gets a value from the splay-tree by its key. 879 % 880 % Note, the value is a constant. Do not attempt to free it. 881 % 882 % The format of the GetValueFromSplayTree method is: 883 % 884 % const void *GetValueFromSplayTree(SplayTreeInfo *splay_tree, 885 % const void *key) 886 % 887 % A description of each parameter follows: 888 % 889 % o splay_tree: the splay tree. 890 % 891 % o key: the key. 892 % 893 */ 894 MagickExport const void *GetValueFromSplayTree(SplayTreeInfo *splay_tree, 895 const void *key) 896 { 897 int 898 compare; 899 900 void 901 *value; 902 903 assert(splay_tree != (SplayTreeInfo *) NULL); 904 assert(splay_tree->signature == MagickCoreSignature); 905 if (splay_tree->debug != MagickFalse) 906 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 907 if (splay_tree->root == (NodeInfo *) NULL) 908 return((void *) NULL); 909 LockSemaphoreInfo(splay_tree->semaphore); 910 SplaySplayTree(splay_tree,key); 911 if (splay_tree->compare != (int (*)(const void *,const void *)) NULL) 912 compare=splay_tree->compare(splay_tree->root->key,key); 913 else 914 compare=(splay_tree->root->key > key) ? 1 : 915 ((splay_tree->root->key < key) ? -1 : 0); 916 if (compare != 0) 917 { 918 UnlockSemaphoreInfo(splay_tree->semaphore); 919 return((void *) NULL); 920 } 921 value=splay_tree->root->value; 922 UnlockSemaphoreInfo(splay_tree->semaphore); 923 return(value); 924 } 925 926 /* 928 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 929 % % 930 % % 931 % % 932 % G e t N u m b e r O f N o d e s I n S p l a y T r e e % 933 % % 934 % % 935 % % 936 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 937 % 938 % GetNumberOfNodesInSplayTree() returns the number of nodes in the splay-tree. 939 % 940 % The format of the GetNumberOfNodesInSplayTree method is: 941 % 942 % size_t GetNumberOfNodesInSplayTree( 943 % const SplayTreeInfo *splay_tree) 944 % 945 % A description of each parameter follows: 946 % 947 % o splay_tree: the splay tree. 948 % 949 */ 950 MagickExport size_t GetNumberOfNodesInSplayTree( 951 const SplayTreeInfo *splay_tree) 952 { 953 assert(splay_tree != (SplayTreeInfo *) NULL); 954 assert(splay_tree->signature == MagickCoreSignature); 955 if (splay_tree->debug != MagickFalse) 956 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 957 return(splay_tree->nodes); 958 } 959 960 /* 962 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 963 % % 964 % % 965 % % 966 % I t e r a t e O v e r S p l a y T r e e % 967 % % 968 % % 969 % % 970 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 971 % 972 % IterateOverSplayTree() iterates over the splay-tree. 973 % 974 % The format of the IterateOverSplayTree method is: 975 % 976 % int IterateOverSplayTree(SplayTreeInfo *splay_tree, 977 % int (*method)(NodeInfo *,void *),const void *value) 978 % 979 % A description of each parameter follows: 980 % 981 % o splay_tree: the splay-tree info. 982 % 983 % o method: the method. 984 % 985 % o value: the value. 986 % 987 */ 988 static int IterateOverSplayTree(SplayTreeInfo *splay_tree, 989 int (*method)(NodeInfo *,const void *),const void *value) 990 { 991 typedef enum 992 { 993 LeftTransition, 994 RightTransition, 995 DownTransition, 996 UpTransition 997 } TransitionType; 998 999 int 1000 status; 1001 1002 MagickBooleanType 1003 final_transition; 1004 1005 NodeInfo 1006 **nodes; 1007 1008 register ssize_t 1009 i; 1010 1011 register NodeInfo 1012 *node; 1013 1014 TransitionType 1015 transition; 1016 1017 unsigned char 1018 *transitions; 1019 1020 if (splay_tree->root == (NodeInfo *) NULL) 1021 return(0); 1022 nodes=(NodeInfo **) AcquireQuantumMemory((size_t) splay_tree->nodes, 1023 sizeof(*nodes)); 1024 transitions=(unsigned char *) AcquireQuantumMemory((size_t) splay_tree->nodes, 1025 sizeof(*transitions)); 1026 if ((nodes == (NodeInfo **) NULL) || (transitions == (unsigned char *) NULL)) 1027 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); 1028 status=0; 1029 final_transition=MagickFalse; 1030 nodes[0]=splay_tree->root; 1031 transitions[0]=(unsigned char) LeftTransition; 1032 for (i=0; final_transition == MagickFalse; ) 1033 { 1034 node=nodes[i]; 1035 transition=(TransitionType) transitions[i]; 1036 switch (transition) 1037 { 1038 case LeftTransition: 1039 { 1040 transitions[i]=(unsigned char) DownTransition; 1041 if (node->left == (NodeInfo *) NULL) 1042 break; 1043 i++; 1044 nodes[i]=node->left; 1045 transitions[i]=(unsigned char) LeftTransition; 1046 break; 1047 } 1048 case RightTransition: 1049 { 1050 transitions[i]=(unsigned char) UpTransition; 1051 if (node->right == (NodeInfo *) NULL) 1052 break; 1053 i++; 1054 nodes[i]=node->right; 1055 transitions[i]=(unsigned char) LeftTransition; 1056 break; 1057 } 1058 case DownTransition: 1059 default: 1060 { 1061 transitions[i]=(unsigned char) RightTransition; 1062 status=(*method)(node,value); 1063 if (status != 0) 1064 final_transition=MagickTrue; 1065 break; 1066 } 1067 case UpTransition: 1068 { 1069 if (i == 0) 1070 { 1071 final_transition=MagickTrue; 1072 break; 1073 } 1074 i--; 1075 break; 1076 } 1077 } 1078 } 1079 nodes=(NodeInfo **) RelinquishMagickMemory(nodes); 1080 transitions=(unsigned char *) RelinquishMagickMemory(transitions); 1081 return(status); 1082 } 1083 1084 /* 1086 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1087 % % 1088 % % 1089 % % 1090 % N e w S p l a y T r e e % 1091 % % 1092 % % 1093 % % 1094 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1095 % 1096 % NewSplayTree() returns a pointer to a SplayTreeInfo structure initialized 1097 % to default values. 1098 % 1099 % The format of the NewSplayTree method is: 1100 % 1101 % SplayTreeInfo *NewSplayTree(int (*compare)(const void *,const void *), 1102 % void *(*relinquish_key)(void *),void *(*relinquish_value)(void *)) 1103 % 1104 % A description of each parameter follows: 1105 % 1106 % o compare: the compare method. 1107 % 1108 % o relinquish_key: the key deallocation method, typically 1109 % RelinquishMagickMemory(), called whenever a key is removed from the 1110 % splay-tree. 1111 % 1112 % o relinquish_value: the value deallocation method; typically 1113 % RelinquishMagickMemory(), called whenever a value object is removed from 1114 % the splay-tree. 1115 % 1116 */ 1117 MagickExport SplayTreeInfo *NewSplayTree( 1118 int (*compare)(const void *,const void *),void *(*relinquish_key)(void *), 1119 void *(*relinquish_value)(void *)) 1120 { 1121 SplayTreeInfo 1122 *splay_tree; 1123 1124 splay_tree=(SplayTreeInfo *) AcquireMagickMemory(sizeof(*splay_tree)); 1125 if (splay_tree == (SplayTreeInfo *) NULL) 1126 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); 1127 (void) ResetMagickMemory(splay_tree,0,sizeof(*splay_tree)); 1128 splay_tree->root=(NodeInfo *) NULL; 1129 splay_tree->compare=compare; 1130 splay_tree->relinquish_key=relinquish_key; 1131 splay_tree->relinquish_value=relinquish_value; 1132 splay_tree->balance=MagickFalse; 1133 splay_tree->key=(void *) NULL; 1134 splay_tree->next=(void *) NULL; 1135 splay_tree->nodes=0; 1136 splay_tree->debug=IsEventLogging(); 1137 splay_tree->semaphore=AcquireSemaphoreInfo(); 1138 splay_tree->signature=MagickCoreSignature; 1139 return(splay_tree); 1140 } 1141 1142 /* 1144 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1145 % % 1146 % % 1147 % % 1148 % R e m o v e N o d e B y V a l u e F r o m S p l a y T r e e % 1149 % % 1150 % % 1151 % % 1152 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1153 % 1154 % RemoveNodeByValueFromSplayTree() removes a node by value from the splay-tree 1155 % and returns its key. 1156 % 1157 % The format of the RemoveNodeByValueFromSplayTree method is: 1158 % 1159 % void *RemoveNodeByValueFromSplayTree(SplayTreeInfo *splay_tree, 1160 % const void *value) 1161 % 1162 % A description of each parameter follows: 1163 % 1164 % o splay_tree: the splay-tree info. 1165 % 1166 % o value: the value. 1167 % 1168 */ 1169 MagickExport void *RemoveNodeByValueFromSplayTree(SplayTreeInfo *splay_tree, 1170 const void *value) 1171 { 1172 register NodeInfo 1173 *next, 1174 *node; 1175 1176 void 1177 *key; 1178 1179 assert(splay_tree != (SplayTreeInfo *) NULL); 1180 assert(splay_tree->signature == MagickCoreSignature); 1181 if (splay_tree->debug != MagickFalse) 1182 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 1183 key=(void *) NULL; 1184 if (splay_tree->root == (NodeInfo *) NULL) 1185 return(key); 1186 LockSemaphoreInfo(splay_tree->semaphore); 1187 next=(NodeInfo *) GetFirstSplayTreeNode(splay_tree); 1188 while (next != (NodeInfo *) NULL) 1189 { 1190 SplaySplayTree(splay_tree,next); 1191 next=(NodeInfo *) NULL; 1192 node=splay_tree->root->right; 1193 if (node != (NodeInfo *) NULL) 1194 { 1195 while (node->left != (NodeInfo *) NULL) 1196 node=node->left; 1197 next=(NodeInfo *) node->key; 1198 } 1199 if (splay_tree->root->value == value) 1200 { 1201 int 1202 compare; 1203 1204 register NodeInfo 1205 *left, 1206 *right; 1207 1208 /* 1209 We found the node that matches the value; now remove it. 1210 */ 1211 key=splay_tree->root->key; 1212 SplaySplayTree(splay_tree,key); 1213 splay_tree->key=(void *) NULL; 1214 if (splay_tree->compare != (int (*)(const void *,const void *)) NULL) 1215 compare=splay_tree->compare(splay_tree->root->key,key); 1216 else 1217 compare=(splay_tree->root->key > key) ? 1 : 1218 ((splay_tree->root->key < key) ? -1 : 0); 1219 if (compare != 0) 1220 { 1221 UnlockSemaphoreInfo(splay_tree->semaphore); 1222 return(key); 1223 } 1224 left=splay_tree->root->left; 1225 right=splay_tree->root->right; 1226 if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) && 1227 (splay_tree->root->value != (void *) NULL)) 1228 splay_tree->root->value=splay_tree->relinquish_value( 1229 splay_tree->root->value); 1230 splay_tree->root=(NodeInfo *) RelinquishMagickMemory(splay_tree->root); 1231 splay_tree->nodes--; 1232 if (left == (NodeInfo *) NULL) 1233 { 1234 splay_tree->root=right; 1235 UnlockSemaphoreInfo(splay_tree->semaphore); 1236 return(key); 1237 } 1238 splay_tree->root=left; 1239 if (right != (NodeInfo *) NULL) 1240 { 1241 while (left->right != (NodeInfo *) NULL) 1242 left=left->right; 1243 left->right=right; 1244 } 1245 UnlockSemaphoreInfo(splay_tree->semaphore); 1246 return(key); 1247 } 1248 } 1249 UnlockSemaphoreInfo(splay_tree->semaphore); 1250 return(key); 1251 } 1252 1253 /* 1255 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1256 % % 1257 % % 1258 % % 1259 % R e m o v e N o d e F r o m S p l a y T r e e % 1260 % % 1261 % % 1262 % % 1263 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1264 % 1265 % RemoveNodeFromSplayTree() removes a node from the splay-tree and returns its 1266 % value. 1267 % 1268 % The format of the RemoveNodeFromSplayTree method is: 1269 % 1270 % void *RemoveNodeFromSplayTree(SplayTreeInfo *splay_tree,const void *key) 1271 % 1272 % A description of each parameter follows: 1273 % 1274 % o splay_tree: the splay-tree info. 1275 % 1276 % o key: the key. 1277 % 1278 */ 1279 MagickExport void *RemoveNodeFromSplayTree(SplayTreeInfo *splay_tree, 1280 const void *key) 1281 { 1282 int 1283 compare; 1284 1285 register NodeInfo 1286 *left, 1287 *right; 1288 1289 void 1290 *value; 1291 1292 assert(splay_tree != (SplayTreeInfo *) NULL); 1293 assert(splay_tree->signature == MagickCoreSignature); 1294 if (splay_tree->debug != MagickFalse) 1295 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 1296 value=(void *) NULL; 1297 if (splay_tree->root == (NodeInfo *) NULL) 1298 return(value); 1299 LockSemaphoreInfo(splay_tree->semaphore); 1300 SplaySplayTree(splay_tree,key); 1301 splay_tree->key=(void *) NULL; 1302 if (splay_tree->compare != (int (*)(const void *,const void *)) NULL) 1303 compare=splay_tree->compare(splay_tree->root->key,key); 1304 else 1305 compare=(splay_tree->root->key > key) ? 1 : 1306 ((splay_tree->root->key < key) ? -1 : 0); 1307 if (compare != 0) 1308 { 1309 UnlockSemaphoreInfo(splay_tree->semaphore); 1310 return(value); 1311 } 1312 left=splay_tree->root->left; 1313 right=splay_tree->root->right; 1314 value=splay_tree->root->value; 1315 if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) && 1316 (splay_tree->root->key != (void *) NULL)) 1317 splay_tree->root->key=splay_tree->relinquish_key(splay_tree->root->key); 1318 splay_tree->root=(NodeInfo *) RelinquishMagickMemory(splay_tree->root); 1319 splay_tree->nodes--; 1320 if (left == (NodeInfo *) NULL) 1321 { 1322 splay_tree->root=right; 1323 UnlockSemaphoreInfo(splay_tree->semaphore); 1324 return(value); 1325 } 1326 splay_tree->root=left; 1327 if (right != (NodeInfo *) NULL) 1328 { 1329 while (left->right != (NodeInfo *) NULL) 1330 left=left->right; 1331 left->right=right; 1332 } 1333 UnlockSemaphoreInfo(splay_tree->semaphore); 1334 return(value); 1335 } 1336 1337 /* 1339 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1340 % % 1341 % % 1342 % % 1343 % R e s e t S p l a y T r e e % 1344 % % 1345 % % 1346 % % 1347 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1348 % 1349 % ResetSplayTree() resets the splay-tree. That is, it deletes all the nodes 1350 % from the tree. 1351 % 1352 % The format of the ResetSplayTree method is: 1353 % 1354 % ResetSplayTree(SplayTreeInfo *splay_tree) 1355 % 1356 % A description of each parameter follows: 1357 % 1358 % o splay_tree: the splay tree. 1359 % 1360 */ 1361 MagickExport void ResetSplayTree(SplayTreeInfo *splay_tree) 1362 { 1363 NodeInfo 1364 *node; 1365 1366 register NodeInfo 1367 *active, 1368 *pend; 1369 1370 assert(splay_tree != (SplayTreeInfo *) NULL); 1371 assert(splay_tree->signature == MagickCoreSignature); 1372 if (splay_tree->debug != MagickFalse) 1373 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 1374 LockSemaphoreInfo(splay_tree->semaphore); 1375 if (splay_tree->root != (NodeInfo *) NULL) 1376 { 1377 if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) && 1378 (splay_tree->root->value != (void *) NULL)) 1379 splay_tree->root->value=splay_tree->relinquish_value( 1380 splay_tree->root->value); 1381 if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) && 1382 (splay_tree->root->key != (void *) NULL)) 1383 splay_tree->root->key=splay_tree->relinquish_key(splay_tree->root->key); 1384 splay_tree->root->key=(void *) NULL; 1385 for (pend=splay_tree->root; pend != (NodeInfo *) NULL; ) 1386 { 1387 active=pend; 1388 for (pend=(NodeInfo *) NULL; active != (NodeInfo *) NULL; ) 1389 { 1390 if (active->left != (NodeInfo *) NULL) 1391 { 1392 if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) && 1393 (active->left->value != (void *) NULL)) 1394 active->left->value=splay_tree->relinquish_value( 1395 active->left->value); 1396 if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) && 1397 (active->left->key != (void *) NULL)) 1398 active->left->key=splay_tree->relinquish_key(active->left->key); 1399 active->left->key=(void *) pend; 1400 pend=active->left; 1401 } 1402 if (active->right != (NodeInfo *) NULL) 1403 { 1404 if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) && 1405 (active->right->value != (void *) NULL)) 1406 active->right->value=splay_tree->relinquish_value( 1407 active->right->value); 1408 if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) && 1409 (active->right->key != (void *) NULL)) 1410 active->right->key=splay_tree->relinquish_key( 1411 active->right->key); 1412 active->right->key=(void *) pend; 1413 pend=active->right; 1414 } 1415 node=active; 1416 active=(NodeInfo *) node->key; 1417 node=(NodeInfo *) RelinquishMagickMemory(node); 1418 } 1419 } 1420 } 1421 splay_tree->root=(NodeInfo *) NULL; 1422 splay_tree->key=(void *) NULL; 1423 splay_tree->next=(void *) NULL; 1424 splay_tree->nodes=0; 1425 splay_tree->balance=MagickFalse; 1426 UnlockSemaphoreInfo(splay_tree->semaphore); 1427 } 1428 1429 /* 1431 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1432 % % 1433 % % 1434 % % 1435 % R e s e t S p l a y T r e e I t e r a t o r % 1436 % % 1437 % % 1438 % % 1439 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1440 % 1441 % ResetSplayTreeIterator() resets the splay-tree iterator. Use it in 1442 % conjunction with GetNextValueInSplayTree() to iterate over all the nodes in 1443 % the splay-tree. 1444 % 1445 % The format of the ResetSplayTreeIterator method is: 1446 % 1447 % ResetSplayTreeIterator(SplayTreeInfo *splay_tree) 1448 % 1449 % A description of each parameter follows: 1450 % 1451 % o splay_tree: the splay tree. 1452 % 1453 */ 1454 MagickExport void ResetSplayTreeIterator(SplayTreeInfo *splay_tree) 1455 { 1456 assert(splay_tree != (SplayTreeInfo *) NULL); 1457 assert(splay_tree->signature == MagickCoreSignature); 1458 if (splay_tree->debug != MagickFalse) 1459 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 1460 LockSemaphoreInfo(splay_tree->semaphore); 1461 splay_tree->next=GetFirstSplayTreeNode(splay_tree); 1462 UnlockSemaphoreInfo(splay_tree->semaphore); 1463 } 1464 1465 /* 1467 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1468 % % 1469 % % 1470 % % 1471 % S p l a y S p l a y T r e e % 1472 % % 1473 % % 1474 % % 1475 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1476 % 1477 % SplaySplayTree() splays the splay-tree. 1478 % 1479 % The format of the SplaySplayTree method is: 1480 % 1481 % void SplaySplayTree(SplayTreeInfo *splay_tree,const void *key, 1482 % NodeInfo **node,NodeInfo **parent,NodeInfo **grandparent) 1483 % 1484 % A description of each parameter follows: 1485 % 1486 % o splay_tree: the splay-tree info. 1487 % 1488 % o key: the key. 1489 % 1490 % o node: the node. 1491 % 1492 % o parent: the parent node. 1493 % 1494 % o grandparent: the grandparent node. 1495 % 1496 */ 1497 1498 static NodeInfo *Splay(SplayTreeInfo *splay_tree,const size_t depth, 1499 const void *key,NodeInfo **node,NodeInfo **parent,NodeInfo **grandparent) 1500 { 1501 int 1502 compare; 1503 1504 NodeInfo 1505 **next; 1506 1507 register NodeInfo 1508 *n, 1509 *p; 1510 1511 n=(*node); 1512 if (n == (NodeInfo *) NULL) 1513 return(*parent); 1514 if (splay_tree->compare != (int (*)(const void *,const void *)) NULL) 1515 compare=splay_tree->compare(n->key,key); 1516 else 1517 compare=(n->key > key) ? 1 : ((n->key < key) ? -1 : 0); 1518 next=(NodeInfo **) NULL; 1519 if (compare > 0) 1520 next=(&n->left); 1521 else 1522 if (compare < 0) 1523 next=(&n->right); 1524 if (next != (NodeInfo **) NULL) 1525 { 1526 if (depth >= MaxSplayTreeDepth) 1527 { 1528 splay_tree->balance=MagickTrue; 1529 return(n); 1530 } 1531 n=Splay(splay_tree,depth+1,key,next,node,parent); 1532 if ((n != *node) || (splay_tree->balance != MagickFalse)) 1533 return(n); 1534 } 1535 if (parent == (NodeInfo **) NULL) 1536 return(n); 1537 if (grandparent == (NodeInfo **) NULL) 1538 { 1539 if (n == (*parent)->left) 1540 { 1541 *node=n->right; 1542 n->right=(*parent); 1543 } 1544 else 1545 { 1546 *node=n->left; 1547 n->left=(*parent); 1548 } 1549 *parent=n; 1550 return(n); 1551 } 1552 if ((n == (*parent)->left) && (*parent == (*grandparent)->left)) 1553 { 1554 p=(*parent); 1555 (*grandparent)->left=p->right; 1556 p->right=(*grandparent); 1557 p->left=n->right; 1558 n->right=p; 1559 *grandparent=n; 1560 return(n); 1561 } 1562 if ((n == (*parent)->right) && (*parent == (*grandparent)->right)) 1563 { 1564 p=(*parent); 1565 (*grandparent)->right=p->left; 1566 p->left=(*grandparent); 1567 p->right=n->left; 1568 n->left=p; 1569 *grandparent=n; 1570 return(n); 1571 } 1572 if (n == (*parent)->left) 1573 { 1574 (*parent)->left=n->right; 1575 n->right=(*parent); 1576 (*grandparent)->right=n->left; 1577 n->left=(*grandparent); 1578 *grandparent=n; 1579 return(n); 1580 } 1581 (*parent)->right=n->left; 1582 n->left=(*parent); 1583 (*grandparent)->left=n->right; 1584 n->right=(*grandparent); 1585 *grandparent=n; 1586 return(n); 1587 } 1588 1589 static void SplaySplayTree(SplayTreeInfo *splay_tree,const void *key) 1590 { 1591 if (splay_tree->root == (NodeInfo *) NULL) 1592 return; 1593 if (splay_tree->key != (void *) NULL) 1594 { 1595 int 1596 compare; 1597 1598 if (splay_tree->compare != (int (*)(const void *,const void *)) NULL) 1599 compare=splay_tree->compare(splay_tree->root->key,key); 1600 else 1601 compare=(splay_tree->key > key) ? 1 : 1602 ((splay_tree->key < key) ? -1 : 0); 1603 if (compare == 0) 1604 return; 1605 } 1606 (void) Splay(splay_tree,0UL,key,&splay_tree->root,(NodeInfo **) NULL, 1607 (NodeInfo **) NULL); 1608 if (splay_tree->balance != MagickFalse) 1609 { 1610 BalanceSplayTree(splay_tree); 1611 (void) Splay(splay_tree,0UL,key,&splay_tree->root,(NodeInfo **) NULL, 1612 (NodeInfo **) NULL); 1613 if (splay_tree->balance != MagickFalse) 1614 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); 1615 } 1616 splay_tree->key=(void *) key; 1617 } 1618