2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6 % SSSSS PPPP L AAA Y Y %
10 % SSSSS P LLLLL A A Y %
12 % TTTTT RRRR EEEEE EEEEE %
19 % MagickCore Self-adjusting Binary Search Tree Methods %
26 % Copyright 1999-2010 ImageMagick Studio LLC, a non-profit organization %
27 % dedicated to making software imaging solutions freely available. %
29 % You may not use this file except in compliance with the License. You may %
30 % obtain a copy of the License at %
32 % http://www.imagemagick.org/script/license.php %
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. %
40 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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.
51 #include "magick/studio.h"
52 #include "magick/exception.h"
53 #include "magick/exception-private.h"
54 #include "magick/log.h"
55 #include "magick/memory_.h"
56 #include "magick/splay-tree.h"
57 #include "magick/semaphore.h"
58 #include "magick/string_.h"
63 #define MaxSplayTreeDepth 1024
68 typedef struct _NodeInfo
87 (*compare)(const void *,const void *);
90 *(*relinquish_key)(void *),
91 *(*relinquish_value)(void *);
114 Forward declarations.
117 IterateOverSplayTree(SplayTreeInfo *,int (*)(NodeInfo *,const void *),
121 SplaySplayTree(SplayTreeInfo *,const void *);
124 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
128 % A d d V a l u e T o S p l a y T r e e %
132 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
134 % AddValueToSplayTree() adds a value to the splay-tree.
136 % The format of the AddValueToSplayTree method is:
138 % MagickBooleanType AddValueToSplayTree(SplayTreeInfo *splay_tree,
139 % const void *key,const void *value)
141 % A description of each parameter follows:
143 % o splay_tree: the splay-tree info.
147 % o value: the value.
150 MagickExport MagickBooleanType AddValueToSplayTree(SplayTreeInfo *splay_tree,
151 const void *key,const void *value)
159 LockSemaphoreInfo(splay_tree->semaphore);
160 SplaySplayTree(splay_tree,key);
162 if (splay_tree->root != (NodeInfo *) NULL)
164 if (splay_tree->compare != (int (*)(const void *,const void *)) NULL)
165 compare=splay_tree->compare(splay_tree->root->key,key);
167 compare=(splay_tree->root->key > key) ? 1 :
168 ((splay_tree->root->key < key) ? -1 : 0);
171 if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
172 (splay_tree->root->key != (void *) NULL))
173 splay_tree->root->key=splay_tree->relinquish_key(
174 splay_tree->root->key);
175 splay_tree->root->key=(void *) key;
176 if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
177 (splay_tree->root->value != (void *) NULL))
178 splay_tree->root->value=splay_tree->relinquish_value(
179 splay_tree->root->value);
180 splay_tree->root->value=(void *) value;
181 UnlockSemaphoreInfo(splay_tree->semaphore);
185 node=(NodeInfo *) AcquireAlignedMemory(1,sizeof(*node));
186 if (node == (NodeInfo *) NULL)
188 UnlockSemaphoreInfo(splay_tree->semaphore);
191 node->key=(void *) key;
192 node->value=(void *) value;
193 if (splay_tree->root == (NodeInfo *) NULL)
195 node->left=(NodeInfo *) NULL;
196 node->right=(NodeInfo *) NULL;
201 node->left=splay_tree->root;
202 node->right=node->left->right;
203 node->left->right=(NodeInfo *) NULL;
207 node->right=splay_tree->root;
208 node->left=node->right->left;
209 node->right->left=(NodeInfo *) NULL;
211 splay_tree->root=node;
212 splay_tree->key=(void *) NULL;
214 UnlockSemaphoreInfo(splay_tree->semaphore);
219 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
223 % B a l a n c e S p l a y T r e e %
227 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
229 % BalanceSplayTree() balances the splay-tree.
231 % The format of the BalanceSplayTree method is:
233 % void *BalanceSplayTree(SplayTreeInfo *splay_tree,const void *key)
235 % A description of each parameter follows:
237 % o splay_tree: the splay-tree info.
243 static NodeInfo *LinkSplayTreeNodes(NodeInfo **nodes,const unsigned long low,
244 const unsigned long high)
252 bisect=low+(high-low)/2;
254 if ((low+1) > bisect)
255 node->left=(NodeInfo *) NULL;
257 node->left=LinkSplayTreeNodes(nodes,low,bisect-1);
258 if ((bisect+1) > high)
259 node->right=(NodeInfo *) NULL;
261 node->right=LinkSplayTreeNodes(nodes,bisect+1,high);
265 static int SplayTreeToNodeArray(NodeInfo *node,const void *nodes)
267 register const NodeInfo
270 p=(const NodeInfo ***) nodes;
276 static void BalanceSplayTree(SplayTreeInfo *splay_tree)
282 if (splay_tree->nodes <= 2)
284 splay_tree->balance=MagickFalse;
287 nodes=(NodeInfo **) AcquireQuantumMemory((size_t) splay_tree->nodes,
289 if (nodes == (NodeInfo **) NULL)
290 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
292 (void) IterateOverSplayTree(splay_tree,SplayTreeToNodeArray,
293 (const void *) &node);
294 splay_tree->root=LinkSplayTreeNodes(nodes,0,splay_tree->nodes-1);
295 splay_tree->balance=MagickFalse;
296 nodes=(NodeInfo **) RelinquishMagickMemory(nodes);
300 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
304 % C l o n e S p l a y T r e e %
308 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
310 % CloneSplayTree() clones the splay tree.
312 % The format of the CloneSplayTree method is:
314 % SplayTreeInfo *CloneSplayTree(SplayTreeInfo *splay_tree,
315 % void *(*clone_key)(void *),void *(*cline_value)(void *))
317 % A description of each parameter follows:
319 % o splay_tree: the splay tree.
321 % o clone_key: the key clone method, typically ConstantString(), called
322 % whenever a key is added to the splay-tree.
324 % o clone_value: the value clone method; typically ConstantString(), called
325 % whenever a value object is added to the splay-tree.
328 MagickExport SplayTreeInfo *CloneSplayTree(SplayTreeInfo *splay_tree,
329 void *(*clone_key)(void *),void *(*clone_value)(void *))
334 assert(splay_tree != (SplayTreeInfo *) NULL);
335 assert(splay_tree->signature == MagickSignature);
336 if (splay_tree->debug != MagickFalse)
337 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
338 clone_tree=NewSplayTree(splay_tree->compare,splay_tree->relinquish_key,
339 splay_tree->relinquish_value);
340 LockSemaphoreInfo(splay_tree->semaphore);
341 if (splay_tree->root != (NodeInfo *) NULL)
352 key=splay_tree->root->key;
353 if ((clone_key != (void *(*)(void *)) NULL) && (key != (void *) NULL))
355 value=splay_tree->root->value;
356 if ((clone_value != (void *(*)(void *)) NULL) && (value != (void *) NULL))
357 value=clone_value(value);
358 (void) AddValueToSplayTree(clone_tree,key,value);
359 for (node=splay_tree->root; node != (NodeInfo *) NULL; )
362 for (node=(NodeInfo *) NULL; active != (NodeInfo *) NULL; )
364 next=(NodeInfo *) NULL;
365 if (active->left != (NodeInfo *) NULL)
368 key=active->left->key;
369 if ((clone_key != (void *(*)(void *)) NULL) &&
370 (key != (void *) NULL))
372 value=active->left->value;
373 if ((clone_value != (void *(*)(void *)) NULL) &&
374 (value != (void *) NULL))
375 value=clone_value(value);
376 (void) AddValueToSplayTree(clone_tree,key,value);
379 if (active->right != (NodeInfo *) NULL)
382 key=active->right->key;
383 if ((clone_key != (void *(*)(void *)) NULL) &&
384 (key != (void *) NULL))
386 value=active->right->value;
387 if ((clone_value != (void *(*)(void *)) NULL) &&
388 (value != (void *) NULL))
389 value=clone_value(value);
390 (void) AddValueToSplayTree(clone_tree,key,value);
397 UnlockSemaphoreInfo(splay_tree->semaphore);
402 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
406 % C o m p a r e S p l a y T r e e S t r i n g %
410 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
412 % CompareSplayTreeString() method finds a node in a splay-tree based on the
413 % contents of a string.
415 % The format of the CompareSplayTreeString method is:
417 % int CompareSplayTreeString(const void *target,const void *source)
419 % A description of each parameter follows:
421 % o target: the target string.
423 % o source: the source string.
426 MagickExport int CompareSplayTreeString(const void *target,const void *source)
432 p=(const char *) target;
433 q=(const char *) source;
434 return(LocaleCompare(p,q));
438 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
442 % 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 %
446 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
448 % CompareSplayTreeStringInfo() finds a node in a splay-tree based on the
449 % contents of a string.
451 % The format of the CompareSplayTreeStringInfo method is:
453 % int CompareSplayTreeStringInfo(const void *target,const void *source)
455 % A description of each parameter follows:
457 % o target: the target string.
459 % o source: the source string.
462 MagickExport int CompareSplayTreeStringInfo(const void *target,
469 p=(const StringInfo *) target;
470 q=(const StringInfo *) source;
471 return(CompareStringInfo(p,q));
475 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
479 % 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 %
483 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
485 % DeleteNodeByValueFromSplayTree() deletes a node by value from the
488 % The format of the DeleteNodeByValueFromSplayTree method is:
490 % MagickBooleanType DeleteNodeByValueFromSplayTree(
491 % SplayTreeInfo *splay_tree,const void *value)
493 % A description of each parameter follows:
495 % o splay_tree: the splay-tree info.
497 % o value: the value.
501 static void *GetFirstSplayTreeNode(SplayTreeInfo *splay_tree)
506 node=splay_tree->root;
507 if (splay_tree->root == (NodeInfo *) NULL)
508 return((NodeInfo *) NULL);
509 while (node->left != (NodeInfo *) NULL)
514 MagickExport MagickBooleanType DeleteNodeByValueFromSplayTree(
515 SplayTreeInfo *splay_tree,const void *value)
521 assert(splay_tree != (SplayTreeInfo *) NULL);
522 assert(splay_tree->signature == MagickSignature);
523 if (splay_tree->debug != MagickFalse)
524 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
525 LockSemaphoreInfo(splay_tree->semaphore);
526 if (splay_tree->root == (NodeInfo *) NULL)
528 UnlockSemaphoreInfo(splay_tree->semaphore);
531 next=(NodeInfo *) GetFirstSplayTreeNode(splay_tree);
532 while (next != (NodeInfo *) NULL)
534 SplaySplayTree(splay_tree,next);
535 next=(NodeInfo *) NULL;
536 node=splay_tree->root->right;
537 if (node != (NodeInfo *) NULL)
539 while (node->left != (NodeInfo *) NULL)
541 next=(NodeInfo *) node->key;
543 if (splay_tree->root->value == value)
556 We found the node that matches the value; now delete it.
558 key=splay_tree->root->key;
559 SplaySplayTree(splay_tree,key);
560 splay_tree->key=(void *) NULL;
561 if (splay_tree->compare != (int (*)(const void *,const void *)) NULL)
562 compare=splay_tree->compare(splay_tree->root->key,key);
564 compare=(splay_tree->root->key > key) ? 1 :
565 ((splay_tree->root->key < key) ? -1 : 0);
568 UnlockSemaphoreInfo(splay_tree->semaphore);
571 left=splay_tree->root->left;
572 right=splay_tree->root->right;
573 if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
574 (splay_tree->root->key != (void *) NULL))
575 splay_tree->root->key=splay_tree->relinquish_key(
576 splay_tree->root->key);
577 if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
578 (splay_tree->root->value != (void *) NULL))
579 splay_tree->root->value=splay_tree->relinquish_value(
580 splay_tree->root->value);
581 splay_tree->root=(NodeInfo *) RelinquishMagickMemory(splay_tree->root);
583 if (left == (NodeInfo *) NULL)
585 splay_tree->root=right;
586 UnlockSemaphoreInfo(splay_tree->semaphore);
589 splay_tree->root=left;
590 if (right != (NodeInfo *) NULL)
592 while (left->right != (NodeInfo *) NULL)
596 UnlockSemaphoreInfo(splay_tree->semaphore);
600 UnlockSemaphoreInfo(splay_tree->semaphore);
605 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
609 % D e l e t e N o d e F r o m S p l a y T r e e %
613 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
615 % DeleteNodeFromSplayTree() deletes a node from the splay-tree.
617 % The format of the DeleteNodeFromSplayTree method is:
619 % MagickBooleanType DeleteNodeFromSplayTree(SplayTreeInfo *splay_tree,
622 % A description of each parameter follows:
624 % o splay_tree: the splay-tree info.
629 MagickExport MagickBooleanType DeleteNodeFromSplayTree(
630 SplayTreeInfo *splay_tree,const void *key)
639 assert(splay_tree != (SplayTreeInfo *) NULL);
640 assert(splay_tree->signature == MagickSignature);
641 if (splay_tree->debug != MagickFalse)
642 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
643 if (splay_tree->root == (NodeInfo *) NULL)
645 LockSemaphoreInfo(splay_tree->semaphore);
646 SplaySplayTree(splay_tree,key);
647 splay_tree->key=(void *) NULL;
648 if (splay_tree->compare != (int (*)(const void *,const void *)) NULL)
649 compare=splay_tree->compare(splay_tree->root->key,key);
651 compare=(splay_tree->root->key > key) ? 1 :
652 ((splay_tree->root->key < key) ? -1 : 0);
655 UnlockSemaphoreInfo(splay_tree->semaphore);
658 left=splay_tree->root->left;
659 right=splay_tree->root->right;
660 if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
661 (splay_tree->root->value != (void *) NULL))
662 splay_tree->root->value=splay_tree->relinquish_value(
663 splay_tree->root->value);
664 if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
665 (splay_tree->root->key != (void *) NULL))
666 splay_tree->root->key=splay_tree->relinquish_key(splay_tree->root->key);
667 splay_tree->root=(NodeInfo *) RelinquishMagickMemory(splay_tree->root);
669 if (left == (NodeInfo *) NULL)
671 splay_tree->root=right;
672 UnlockSemaphoreInfo(splay_tree->semaphore);
675 splay_tree->root=left;
676 if (right != (NodeInfo *) NULL)
678 while (left->right != (NodeInfo *) NULL)
682 UnlockSemaphoreInfo(splay_tree->semaphore);
687 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
691 % D e s t r o y S p l a y T r e e %
695 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
697 % DestroySplayTree() destroys the splay-tree.
699 % The format of the DestroySplayTree method is:
701 % SplayTreeInfo *DestroySplayTree(SplayTreeInfo *splay_tree)
703 % A description of each parameter follows:
705 % o splay_tree: the splay tree.
708 MagickExport SplayTreeInfo *DestroySplayTree(SplayTreeInfo *splay_tree)
717 LockSemaphoreInfo(splay_tree->semaphore);
718 if (splay_tree->root != (NodeInfo *) NULL)
720 if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
721 (splay_tree->root->key != (void *) NULL))
722 splay_tree->root->key=splay_tree->relinquish_key(splay_tree->root->key);
723 splay_tree->root->key=(void *) NULL;
724 if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
725 (splay_tree->root->value != (void *) NULL))
726 splay_tree->root->value=splay_tree->relinquish_value(
727 splay_tree->root->value);
728 for (pend=splay_tree->root; pend != (NodeInfo *) NULL; )
731 for (pend=(NodeInfo *) NULL; active != (NodeInfo *) NULL; )
733 if (active->left != (NodeInfo *) NULL)
735 if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
736 (active->left->key != (void *) NULL))
737 active->left->key=splay_tree->relinquish_key(active->left->key);
738 active->left->key=(void *) pend;
739 if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
740 (active->left->value != (void *) NULL))
741 active->left->value=splay_tree->relinquish_value(
742 active->left->value);
745 if (active->right != (NodeInfo *) NULL)
747 if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
748 (active->right->key != (void *) NULL))
749 active->right->key=splay_tree->relinquish_key(
751 active->right->key=(void *) pend;
752 if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
753 (active->right->value != (void *) NULL))
754 active->right->value=splay_tree->relinquish_value(
755 active->right->value);
759 active=(NodeInfo *) node->key;
760 node=(NodeInfo *) RelinquishMagickMemory(node);
764 splay_tree->signature=(~MagickSignature);
765 UnlockSemaphoreInfo(splay_tree->semaphore);
766 DestroySemaphoreInfo(&splay_tree->semaphore);
767 splay_tree=(SplayTreeInfo *) RelinquishMagickMemory(splay_tree);
772 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
776 % G e t N e x t K e y I n S p l a y T r e e %
780 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
782 % GetNextKeyInSplayTree() gets the next key in the splay-tree.
784 % The format of the GetNextKeyInSplayTree method is:
786 % void *GetNextKeyInSplayTree(SplayTreeInfo *splay_tree)
788 % A description of each parameter follows:
790 % o splay_tree: the splay tree.
795 MagickExport void *GetNextKeyInSplayTree(SplayTreeInfo *splay_tree)
803 assert(splay_tree != (SplayTreeInfo *) NULL);
804 assert(splay_tree->signature == MagickSignature);
805 if (splay_tree->debug != MagickFalse)
806 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
807 if ((splay_tree->root == (NodeInfo *) NULL) ||
808 (splay_tree->next == (void *) NULL))
809 return((void *) NULL);
810 LockSemaphoreInfo(splay_tree->semaphore);
811 SplaySplayTree(splay_tree,splay_tree->next);
812 splay_tree->next=(void *) NULL;
813 node=splay_tree->root->right;
814 if (node != (NodeInfo *) NULL)
816 while (node->left != (NodeInfo *) NULL)
818 splay_tree->next=node->key;
820 key=splay_tree->root->key;
821 UnlockSemaphoreInfo(splay_tree->semaphore);
826 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
830 % G e t N e x t V a l u e I n S p l a y T r e e %
834 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
836 % GetNextValueInSplayTree() gets the next value in the splay-tree.
838 % The format of the GetNextValueInSplayTree method is:
840 % void *GetNextValueInSplayTree(SplayTreeInfo *splay_tree)
842 % A description of each parameter follows:
844 % o splay_tree: the splay tree.
849 MagickExport void *GetNextValueInSplayTree(SplayTreeInfo *splay_tree)
857 assert(splay_tree != (SplayTreeInfo *) NULL);
858 assert(splay_tree->signature == MagickSignature);
859 if (splay_tree->debug != MagickFalse)
860 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
861 if ((splay_tree->root == (NodeInfo *) NULL) ||
862 (splay_tree->next == (void *) NULL))
863 return((void *) NULL);
864 LockSemaphoreInfo(splay_tree->semaphore);
865 SplaySplayTree(splay_tree,splay_tree->next);
866 splay_tree->next=(void *) NULL;
867 node=splay_tree->root->right;
868 if (node != (NodeInfo *) NULL)
870 while (node->left != (NodeInfo *) NULL)
872 splay_tree->next=node->key;
874 value=splay_tree->root->value;
875 UnlockSemaphoreInfo(splay_tree->semaphore);
880 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
884 % G e t V a l u e F r o m S p l a y T r e e %
888 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
890 % GetValueFromSplayTree() gets a value from the splay-tree by its key.
892 % The format of the GetValueFromSplayTree method is:
894 % void *GetValueFromSplayTree(SplayTreeInfo *splay_tree,const void *key)
896 % A description of each parameter follows:
898 % o splay_tree: the splay tree.
903 MagickExport void *GetValueFromSplayTree(SplayTreeInfo *splay_tree,
912 assert(splay_tree != (SplayTreeInfo *) NULL);
913 assert(splay_tree->signature == MagickSignature);
914 if (splay_tree->debug != MagickFalse)
915 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
916 if (splay_tree->root == (NodeInfo *) NULL)
917 return((void *) NULL);
918 LockSemaphoreInfo(splay_tree->semaphore);
919 SplaySplayTree(splay_tree,key);
920 if (splay_tree->compare != (int (*)(const void *,const void *)) NULL)
921 compare=splay_tree->compare(splay_tree->root->key,key);
923 compare=(splay_tree->root->key > key) ? 1 :
924 ((splay_tree->root->key < key) ? -1 : 0);
927 UnlockSemaphoreInfo(splay_tree->semaphore);
928 return((void *) NULL);
930 value=splay_tree->root->value;
931 UnlockSemaphoreInfo(splay_tree->semaphore);
936 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
940 % 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 %
944 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
946 % GetNumberOfNodesInSplayTree() returns the number of nodes in the splay-tree.
948 % The format of the GetNumberOfNodesInSplayTree method is:
950 % unsigned long GetNumberOfNodesInSplayTree(
951 % const SplayTreeInfo *splay_tree)
953 % A description of each parameter follows:
955 % o splay_tree: the splay tree.
958 MagickExport unsigned long GetNumberOfNodesInSplayTree(
959 const SplayTreeInfo *splay_tree)
961 assert(splay_tree != (SplayTreeInfo *) NULL);
962 assert(splay_tree->signature == MagickSignature);
963 if (splay_tree->debug != MagickFalse)
964 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
965 return(splay_tree->nodes);
969 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
973 % I t e r a t e O v e r S p l a y T r e e %
977 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
979 % IterateOverSplayTree() iterates over the splay-tree.
981 % The format of the IterateOverSplayTree method is:
983 % int IterateOverSplayTree(SplayTreeInfo *splay_tree,
984 % int (*method)(NodeInfo *,void *),const void *value)
986 % A description of each parameter follows:
988 % o splay_tree: the splay-tree info.
990 % o method: the method.
992 % o value: the value.
995 static int IterateOverSplayTree(SplayTreeInfo *splay_tree,
996 int (*method)(NodeInfo *,const void *),const void *value)
1027 if (splay_tree->root == (NodeInfo *) NULL)
1029 nodes=(NodeInfo **) AcquireQuantumMemory((size_t) splay_tree->nodes,
1031 transitions=(unsigned char *) AcquireQuantumMemory((size_t) splay_tree->nodes,
1032 sizeof(*transitions));
1033 if ((nodes == (NodeInfo **) NULL) || (transitions == (unsigned char *) NULL))
1034 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1036 final_transition=MagickFalse;
1037 nodes[0]=splay_tree->root;
1038 transitions[0]=(unsigned char) LeftTransition;
1039 for (i=0; final_transition == MagickFalse; )
1042 transition=(TransitionType) transitions[i];
1045 case LeftTransition:
1047 transitions[i]=(unsigned char) DownTransition;
1048 if (node->left == (NodeInfo *) NULL)
1051 nodes[i]=node->left;
1052 transitions[i]=(unsigned char) LeftTransition;
1055 case RightTransition:
1057 transitions[i]=(unsigned char) UpTransition;
1058 if (node->right == (NodeInfo *) NULL)
1061 nodes[i]=node->right;
1062 transitions[i]=(unsigned char) LeftTransition;
1065 case DownTransition:
1068 transitions[i]=(unsigned char) RightTransition;
1069 status=(*method)(node,value);
1071 final_transition=MagickTrue;
1078 final_transition=MagickTrue;
1086 nodes=(NodeInfo **) RelinquishMagickMemory(nodes);
1087 transitions=(unsigned char *) RelinquishMagickMemory(transitions);
1092 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1096 % N e w S p l a y T r e e %
1100 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1102 % NewSplayTree() returns a pointer to a SplayTreeInfo structure initialized
1103 % to default values.
1105 % The format of the NewSplayTree method is:
1107 % SplayTreeInfo *NewSplayTree(int (*compare)(const void *,const void *),
1108 % void *(*relinquish_key)(void *),void *(*relinquish_value)(void *))
1110 % A description of each parameter follows:
1112 % o compare: the compare method.
1114 % o relinquish_key: the key deallocation method, typically
1115 % RelinquishMagickMemory(), called whenever a key is removed from the
1118 % o relinquish_value: the value deallocation method; typically
1119 % RelinquishMagickMemory(), called whenever a value object is removed from
1123 MagickExport SplayTreeInfo *NewSplayTree(
1124 int (*compare)(const void *,const void *),void *(*relinquish_key)(void *),
1125 void *(*relinquish_value)(void *))
1130 splay_tree=(SplayTreeInfo *) AcquireAlignedMemory(1,sizeof(*splay_tree));
1131 if (splay_tree == (SplayTreeInfo *) NULL)
1132 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1133 (void) ResetMagickMemory(splay_tree,0,sizeof(*splay_tree));
1134 splay_tree->root=(NodeInfo *) NULL;
1135 splay_tree->compare=compare;
1136 splay_tree->relinquish_key=relinquish_key;
1137 splay_tree->relinquish_value=relinquish_value;
1138 splay_tree->balance=MagickFalse;
1139 splay_tree->key=(void *) NULL;
1140 splay_tree->next=(void *) NULL;
1141 splay_tree->nodes=0;
1142 splay_tree->debug=IsEventLogging();
1143 splay_tree->semaphore=AllocateSemaphoreInfo();
1144 splay_tree->signature=MagickSignature;
1149 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1153 % 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 %
1157 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1159 % RemoveNodeByValueFromSplayTree() removes a node by value from the splay-tree
1160 % and returns its key.
1162 % The format of the RemoveNodeByValueFromSplayTree method is:
1164 % void *RemoveNodeByValueFromSplayTree(SplayTreeInfo *splay_tree,
1165 % const void *value)
1167 % A description of each parameter follows:
1169 % o splay_tree: the splay-tree info.
1171 % o value: the value.
1174 MagickExport void *RemoveNodeByValueFromSplayTree(SplayTreeInfo *splay_tree,
1184 assert(splay_tree != (SplayTreeInfo *) NULL);
1185 assert(splay_tree->signature == MagickSignature);
1186 if (splay_tree->debug != MagickFalse)
1187 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1189 if (splay_tree->root == (NodeInfo *) NULL)
1191 LockSemaphoreInfo(splay_tree->semaphore);
1192 next=(NodeInfo *) GetFirstSplayTreeNode(splay_tree);
1193 while (next != (NodeInfo *) NULL)
1195 SplaySplayTree(splay_tree,next);
1196 next=(NodeInfo *) NULL;
1197 node=splay_tree->root->right;
1198 if (node != (NodeInfo *) NULL)
1200 while (node->left != (NodeInfo *) NULL)
1202 next=(NodeInfo *) node->key;
1204 if (splay_tree->root->value == value)
1214 We found the node that matches the value; now remove it.
1216 key=splay_tree->root->key;
1217 SplaySplayTree(splay_tree,key);
1218 splay_tree->key=(void *) NULL;
1219 if (splay_tree->compare != (int (*)(const void *,const void *)) NULL)
1220 compare=splay_tree->compare(splay_tree->root->key,key);
1222 compare=(splay_tree->root->key > key) ? 1 :
1223 ((splay_tree->root->key < key) ? -1 : 0);
1226 UnlockSemaphoreInfo(splay_tree->semaphore);
1229 left=splay_tree->root->left;
1230 right=splay_tree->root->right;
1231 if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
1232 (splay_tree->root->value != (void *) NULL))
1233 splay_tree->root->value=splay_tree->relinquish_value(
1234 splay_tree->root->value);
1235 splay_tree->root=(NodeInfo *) RelinquishMagickMemory(splay_tree->root);
1236 splay_tree->nodes--;
1237 if (left == (NodeInfo *) NULL)
1239 splay_tree->root=right;
1240 UnlockSemaphoreInfo(splay_tree->semaphore);
1243 splay_tree->root=left;
1244 if (right != (NodeInfo *) NULL)
1246 while (left->right != (NodeInfo *) NULL)
1250 UnlockSemaphoreInfo(splay_tree->semaphore);
1254 UnlockSemaphoreInfo(splay_tree->semaphore);
1259 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1263 % R e m o v e N o d e F r o m S p l a y T r e e %
1267 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1269 % RemoveNodeFromSplayTree() removes a node from the splay-tree and returns its
1272 % The format of the RemoveNodeFromSplayTree method is:
1274 % void *RemoveNodeFromSplayTree(SplayTreeInfo *splay_tree,const void *key)
1276 % A description of each parameter follows:
1278 % o splay_tree: the splay-tree info.
1283 MagickExport void *RemoveNodeFromSplayTree(SplayTreeInfo *splay_tree,
1296 assert(splay_tree != (SplayTreeInfo *) NULL);
1297 assert(splay_tree->signature == MagickSignature);
1298 if (splay_tree->debug != MagickFalse)
1299 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1300 value=(void *) NULL;
1301 if (splay_tree->root == (NodeInfo *) NULL)
1303 LockSemaphoreInfo(splay_tree->semaphore);
1304 SplaySplayTree(splay_tree,key);
1305 splay_tree->key=(void *) NULL;
1306 if (splay_tree->compare != (int (*)(const void *,const void *)) NULL)
1307 compare=splay_tree->compare(splay_tree->root->key,key);
1309 compare=(splay_tree->root->key > key) ? 1 :
1310 ((splay_tree->root->key < key) ? -1 : 0);
1313 UnlockSemaphoreInfo(splay_tree->semaphore);
1316 left=splay_tree->root->left;
1317 right=splay_tree->root->right;
1318 value=splay_tree->root->value;
1319 if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
1320 (splay_tree->root->key != (void *) NULL))
1321 splay_tree->root->key=splay_tree->relinquish_key(splay_tree->root->key);
1322 splay_tree->root=(NodeInfo *) RelinquishMagickMemory(splay_tree->root);
1323 splay_tree->nodes--;
1324 if (left == (NodeInfo *) NULL)
1326 splay_tree->root=right;
1327 UnlockSemaphoreInfo(splay_tree->semaphore);
1330 splay_tree->root=left;
1331 if (right != (NodeInfo *) NULL)
1333 while (left->right != (NodeInfo *) NULL)
1337 UnlockSemaphoreInfo(splay_tree->semaphore);
1342 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1346 % R e s e t S p l a y T r e e %
1350 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1352 % ResetSplayTree() resets the splay-tree. That is, it deletes all the nodes
1355 % The format of the ResetSplayTree method is:
1357 % ResetSplayTree(SplayTreeInfo *splay_tree)
1359 % A description of each parameter follows:
1361 % o splay_tree: the splay tree.
1364 MagickExport void ResetSplayTree(SplayTreeInfo *splay_tree)
1373 assert(splay_tree != (SplayTreeInfo *) NULL);
1374 assert(splay_tree->signature == MagickSignature);
1375 if (splay_tree->debug != MagickFalse)
1376 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1377 LockSemaphoreInfo(splay_tree->semaphore);
1378 if (splay_tree->root != (NodeInfo *) NULL)
1380 if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
1381 (splay_tree->root->key != (void *) NULL))
1382 splay_tree->root->key=splay_tree->relinquish_key(splay_tree->root->key);
1383 splay_tree->root->key=(void *) NULL;
1384 if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
1385 (splay_tree->root->value != (void *) NULL))
1386 splay_tree->root->value=splay_tree->relinquish_value(
1387 splay_tree->root->value);
1388 for (pend=splay_tree->root; pend != (NodeInfo *) NULL; )
1391 for (pend=(NodeInfo *) NULL; active != (NodeInfo *) NULL; )
1393 if (active->left != (NodeInfo *) NULL)
1395 if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
1396 (active->left->key != (void *) NULL))
1397 active->left->key=splay_tree->relinquish_key(active->left->key);
1398 active->left->key=(void *) pend;
1399 if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
1400 (active->left->value != (void *) NULL))
1401 active->left->value=splay_tree->relinquish_value(
1402 active->left->value);
1405 if (active->right != (NodeInfo *) NULL)
1407 if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
1408 (active->right->key != (void *) NULL))
1409 active->right->key=splay_tree->relinquish_key(
1410 active->right->key);
1411 active->right->key=(void *) pend;
1412 if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
1413 (active->right->value != (void *) NULL))
1414 active->right->value=splay_tree->relinquish_value(
1415 active->right->value);
1419 active=(NodeInfo *) node->key;
1420 node=(NodeInfo *) RelinquishMagickMemory(node);
1424 splay_tree->root=(NodeInfo *) NULL;
1425 splay_tree->key=(void *) NULL;
1426 splay_tree->next=(void *) NULL;
1427 splay_tree->nodes=0;
1428 splay_tree->balance=MagickFalse;
1429 UnlockSemaphoreInfo(splay_tree->semaphore);
1433 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1437 % R e s e t S p l a y T r e e I t e r a t o r %
1441 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1443 % ResetSplayTreeIterator() resets the splay-tree iterator. Use it in
1444 % conjunction with GetNextValueInSplayTree() to iterate over all the nodes in
1447 % The format of the ResetSplayTreeIterator method is:
1449 % ResetSplayTreeIterator(SplayTreeInfo *splay_tree)
1451 % A description of each parameter follows:
1453 % o splay_tree: the splay tree.
1456 MagickExport void ResetSplayTreeIterator(SplayTreeInfo *splay_tree)
1458 assert(splay_tree != (SplayTreeInfo *) NULL);
1459 assert(splay_tree->signature == MagickSignature);
1460 if (splay_tree->debug != MagickFalse)
1461 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1462 LockSemaphoreInfo(splay_tree->semaphore);
1463 splay_tree->next=GetFirstSplayTreeNode(splay_tree);
1464 UnlockSemaphoreInfo(splay_tree->semaphore);
1468 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1472 % S p l a y S p l a y T r e e %
1476 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1478 % SplaySplayTree() splays the splay-tree.
1480 % The format of the SplaySplayTree method is:
1482 % void SplaySplayTree(SplayTreeInfo *splay_tree,const void *key,
1483 % NodeInfo **node,NodeInfo **parent,NodeInfo **grandparent)
1485 % A description of each parameter follows:
1487 % o splay_tree: the splay-tree info.
1493 % o parent: the parent node.
1495 % o grandparent: the grandparent node.
1499 static NodeInfo *Splay(SplayTreeInfo *splay_tree,const unsigned long depth,
1500 const void *key,NodeInfo **node,NodeInfo **parent,NodeInfo **grandparent)
1513 if (n == (NodeInfo *) NULL)
1515 if (splay_tree->compare != (int (*)(const void *,const void *)) NULL)
1516 compare=splay_tree->compare(n->key,key);
1518 compare=(n->key > key) ? 1 : ((n->key < key) ? -1 : 0);
1519 next=(NodeInfo **) NULL;
1525 if (next != (NodeInfo **) NULL)
1527 if (depth >= MaxSplayTreeDepth)
1529 splay_tree->balance=MagickTrue;
1532 n=Splay(splay_tree,depth+1,key,next,node,parent);
1533 if ((n != *node) || (splay_tree->balance != MagickFalse))
1536 if (parent == (NodeInfo **) NULL)
1538 if (grandparent == (NodeInfo **) NULL)
1540 if (n == (*parent)->left)
1553 if ((n == (*parent)->left) && (*parent == (*grandparent)->left))
1556 (*grandparent)->left=p->right;
1557 p->right=(*grandparent);
1563 if ((n == (*parent)->right) && (*parent == (*grandparent)->right))
1566 (*grandparent)->right=p->left;
1567 p->left=(*grandparent);
1573 if (n == (*parent)->left)
1575 (*parent)->left=n->right;
1577 (*grandparent)->right=n->left;
1578 n->left=(*grandparent);
1582 (*parent)->right=n->left;
1584 (*grandparent)->left=n->right;
1585 n->right=(*grandparent);
1590 static void SplaySplayTree(SplayTreeInfo *splay_tree,const void *key)
1592 if (splay_tree->root == (NodeInfo *) NULL)
1594 if (splay_tree->key != (void *) NULL)
1599 if (splay_tree->compare != (int (*)(const void *,const void *)) NULL)
1600 compare=splay_tree->compare(splay_tree->root->key,key);
1602 compare=(splay_tree->key > key) ? 1 :
1603 ((splay_tree->key < key) ? -1 : 0);
1607 (void) Splay(splay_tree,0UL,key,&splay_tree->root,(NodeInfo **) NULL,
1608 (NodeInfo **) NULL);
1609 if (splay_tree->balance != MagickFalse)
1611 BalanceSplayTree(splay_tree);
1612 (void) Splay(splay_tree,0UL,key,&splay_tree->root,(NodeInfo **) NULL,
1613 (NodeInfo **) NULL);
1614 if (splay_tree->balance != MagickFalse)
1615 ThrowFatalException(ResourceLimitFatalError,
1616 "MemoryAllocationFailed");
1618 splay_tree->key=(void *) key;