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-2012 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 "MagickCore/studio.h"
52 #include "MagickCore/exception.h"
53 #include "MagickCore/exception-private.h"
54 #include "MagickCore/log.h"
55 #include "MagickCore/memory_.h"
56 #include "MagickCore/splay-tree.h"
57 #include "MagickCore/semaphore.h"
58 #include "MagickCore/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 the given key and value to the splay-tree.
135 % Both key and value are used as is, without coping or cloning.
137 % The format of the AddValueToSplayTree method is:
139 % MagickBooleanType AddValueToSplayTree(SplayTreeInfo *splay_tree,
140 % const void *key,const void *value)
142 % A description of each parameter follows:
144 % o splay_tree: the splay-tree info.
148 % o value: the value.
151 MagickExport MagickBooleanType AddValueToSplayTree(SplayTreeInfo *splay_tree,
152 const void *key,const void *value)
160 LockSemaphoreInfo(splay_tree->semaphore);
161 SplaySplayTree(splay_tree,key);
163 if (splay_tree->root != (NodeInfo *) NULL)
165 if (splay_tree->compare != (int (*)(const void *,const void *)) NULL)
166 compare=splay_tree->compare(splay_tree->root->key,key);
168 compare=(splay_tree->root->key > key) ? 1 :
169 ((splay_tree->root->key < key) ? -1 : 0);
172 if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
173 (splay_tree->root->value != (void *) NULL))
174 splay_tree->root->value=splay_tree->relinquish_value(
175 splay_tree->root->value);
176 if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
177 (splay_tree->root->key != (void *) NULL))
178 splay_tree->root->key=splay_tree->relinquish_key(
179 splay_tree->root->key);
180 splay_tree->root->key=(void *) key;
181 splay_tree->root->value=(void *) value;
182 UnlockSemaphoreInfo(splay_tree->semaphore);
186 node=(NodeInfo *) AcquireMagickMemory(sizeof(*node));
187 if (node == (NodeInfo *) NULL)
189 UnlockSemaphoreInfo(splay_tree->semaphore);
192 node->key=(void *) key;
193 node->value=(void *) value;
194 if (splay_tree->root == (NodeInfo *) NULL)
196 node->left=(NodeInfo *) NULL;
197 node->right=(NodeInfo *) NULL;
202 node->left=splay_tree->root;
203 node->right=node->left->right;
204 node->left->right=(NodeInfo *) NULL;
208 node->right=splay_tree->root;
209 node->left=node->right->left;
210 node->right->left=(NodeInfo *) NULL;
212 splay_tree->root=node;
213 splay_tree->key=(void *) NULL;
215 UnlockSemaphoreInfo(splay_tree->semaphore);
220 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
224 % B a l a n c e S p l a y T r e e %
228 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
230 % BalanceSplayTree() balances the splay-tree.
232 % The format of the BalanceSplayTree method is:
234 % void *BalanceSplayTree(SplayTreeInfo *splay_tree,const void *key)
236 % A description of each parameter follows:
238 % o splay_tree: the splay-tree info.
244 static NodeInfo *LinkSplayTreeNodes(NodeInfo **nodes,const size_t low,
253 bisect=low+(high-low)/2;
255 if ((low+1) > bisect)
256 node->left=(NodeInfo *) NULL;
258 node->left=LinkSplayTreeNodes(nodes,low,bisect-1);
259 if ((bisect+1) > high)
260 node->right=(NodeInfo *) NULL;
262 node->right=LinkSplayTreeNodes(nodes,bisect+1,high);
266 static int SplayTreeToNodeArray(NodeInfo *node,const void *nodes)
268 register const NodeInfo
271 p=(const NodeInfo ***) nodes;
277 static void BalanceSplayTree(SplayTreeInfo *splay_tree)
283 if (splay_tree->nodes <= 2)
285 splay_tree->balance=MagickFalse;
288 nodes=(NodeInfo **) AcquireQuantumMemory((size_t) splay_tree->nodes,
290 if (nodes == (NodeInfo **) NULL)
291 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
293 (void) IterateOverSplayTree(splay_tree,SplayTreeToNodeArray,
294 (const void *) &node);
295 splay_tree->root=LinkSplayTreeNodes(nodes,0,splay_tree->nodes-1);
296 splay_tree->balance=MagickFalse;
297 nodes=(NodeInfo **) RelinquishMagickMemory(nodes);
301 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
305 % C l o n e S p l a y T r e e %
309 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
311 % CloneSplayTree() clones the splay tree.
313 % The format of the CloneSplayTree method is:
315 % SplayTreeInfo *CloneSplayTree(SplayTreeInfo *splay_tree,
316 % void *(*clone_key)(void *),void *(*cline_value)(void *))
318 % A description of each parameter follows:
320 % o splay_tree: the splay tree.
322 % o clone_key: the key clone method, typically ConstantString(), called
323 % whenever a key is added to the splay-tree.
325 % o clone_value: the value clone method; typically ConstantString(), called
326 % whenever a value object is added to the splay-tree.
330 static void *GetFirstSplayTreeNode(SplayTreeInfo *splay_tree)
335 node=splay_tree->root;
336 if (splay_tree->root == (NodeInfo *) NULL)
337 return((NodeInfo *) NULL);
338 while (node->left != (NodeInfo *) NULL)
343 MagickExport SplayTreeInfo *CloneSplayTree(SplayTreeInfo *splay_tree,
344 void *(*clone_key)(void *),void *(*clone_value)(void *))
353 assert(splay_tree != (SplayTreeInfo *) NULL);
354 assert(splay_tree->signature == MagickSignature);
355 if (splay_tree->debug != MagickFalse)
356 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
357 clone_tree=NewSplayTree(splay_tree->compare,splay_tree->relinquish_key,
358 splay_tree->relinquish_value);
359 LockSemaphoreInfo(splay_tree->semaphore);
360 if (splay_tree->root == (NodeInfo *) NULL)
362 UnlockSemaphoreInfo(splay_tree->semaphore);
365 next=(NodeInfo *) GetFirstSplayTreeNode(splay_tree);
366 while (next != (NodeInfo *) NULL)
368 SplaySplayTree(splay_tree,next);
369 (void) AddValueToSplayTree(clone_tree,clone_key(splay_tree->root->key),
370 clone_value(splay_tree->root->value));
371 next=(NodeInfo *) NULL;
372 node=splay_tree->root->right;
373 if (node != (NodeInfo *) NULL)
375 while (node->left != (NodeInfo *) NULL)
377 next=(NodeInfo *) node->key;
380 UnlockSemaphoreInfo(splay_tree->semaphore);
385 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
389 % C o m p a r e S p l a y T r e e S t r i n g %
393 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
395 % CompareSplayTreeString() method finds a node in a splay-tree based on the
396 % contents of a string.
398 % The format of the CompareSplayTreeString method is:
400 % int CompareSplayTreeString(const void *target,const void *source)
402 % A description of each parameter follows:
404 % o target: the target string.
406 % o source: the source string.
409 MagickExport int CompareSplayTreeString(const void *target,const void *source)
415 p=(const char *) target;
416 q=(const char *) source;
417 return(LocaleCompare(p,q));
421 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
425 % 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 %
429 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
431 % CompareSplayTreeStringInfo() finds a node in a splay-tree based on the
432 % contents of a string.
434 % The format of the CompareSplayTreeStringInfo method is:
436 % int CompareSplayTreeStringInfo(const void *target,const void *source)
438 % A description of each parameter follows:
440 % o target: the target string.
442 % o source: the source string.
445 MagickExport int CompareSplayTreeStringInfo(const void *target,
452 p=(const StringInfo *) target;
453 q=(const StringInfo *) source;
454 return(CompareStringInfo(p,q));
458 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
462 % 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 %
466 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
468 % DeleteNodeByValueFromSplayTree() deletes a node by value from the
471 % The format of the DeleteNodeByValueFromSplayTree method is:
473 % MagickBooleanType DeleteNodeByValueFromSplayTree(
474 % SplayTreeInfo *splay_tree,const void *value)
476 % A description of each parameter follows:
478 % o splay_tree: the splay-tree info.
480 % o value: the value.
483 MagickExport MagickBooleanType DeleteNodeByValueFromSplayTree(
484 SplayTreeInfo *splay_tree,const void *value)
490 assert(splay_tree != (SplayTreeInfo *) NULL);
491 assert(splay_tree->signature == MagickSignature);
492 if (splay_tree->debug != MagickFalse)
493 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
494 LockSemaphoreInfo(splay_tree->semaphore);
495 if (splay_tree->root == (NodeInfo *) NULL)
497 UnlockSemaphoreInfo(splay_tree->semaphore);
500 next=(NodeInfo *) GetFirstSplayTreeNode(splay_tree);
501 while (next != (NodeInfo *) NULL)
503 SplaySplayTree(splay_tree,next);
504 next=(NodeInfo *) NULL;
505 node=splay_tree->root->right;
506 if (node != (NodeInfo *) NULL)
508 while (node->left != (NodeInfo *) NULL)
510 next=(NodeInfo *) node->key;
512 if (splay_tree->root->value == value)
525 We found the node that matches the value; now delete it.
527 key=splay_tree->root->key;
528 SplaySplayTree(splay_tree,key);
529 splay_tree->key=(void *) NULL;
530 if (splay_tree->compare != (int (*)(const void *,const void *)) NULL)
531 compare=splay_tree->compare(splay_tree->root->key,key);
533 compare=(splay_tree->root->key > key) ? 1 :
534 ((splay_tree->root->key < key) ? -1 : 0);
537 UnlockSemaphoreInfo(splay_tree->semaphore);
540 left=splay_tree->root->left;
541 right=splay_tree->root->right;
542 if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
543 (splay_tree->root->value != (void *) NULL))
544 splay_tree->root->value=splay_tree->relinquish_value(
545 splay_tree->root->value);
546 if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
547 (splay_tree->root->key != (void *) NULL))
548 splay_tree->root->key=splay_tree->relinquish_key(
549 splay_tree->root->key);
550 splay_tree->root=(NodeInfo *) RelinquishMagickMemory(splay_tree->root);
552 if (left == (NodeInfo *) NULL)
554 splay_tree->root=right;
555 UnlockSemaphoreInfo(splay_tree->semaphore);
558 splay_tree->root=left;
559 if (right != (NodeInfo *) NULL)
561 while (left->right != (NodeInfo *) NULL)
565 UnlockSemaphoreInfo(splay_tree->semaphore);
569 UnlockSemaphoreInfo(splay_tree->semaphore);
574 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
578 % D e l e t e N o d e F r o m S p l a y T r e e %
582 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
584 % DeleteNodeFromSplayTree() deletes a node from the splay-tree. It returns
585 % MagickTrue if the option is found and successfully deleted from the
588 % The format of the DeleteNodeFromSplayTree method is:
590 % MagickBooleanType DeleteNodeFromSplayTree(SplayTreeInfo *splay_tree,
593 % A description of each parameter follows:
595 % o splay_tree: the splay-tree info.
600 MagickExport MagickBooleanType DeleteNodeFromSplayTree(
601 SplayTreeInfo *splay_tree,const void *key)
610 assert(splay_tree != (SplayTreeInfo *) NULL);
611 assert(splay_tree->signature == MagickSignature);
612 if (splay_tree->debug != MagickFalse)
613 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
614 if (splay_tree->root == (NodeInfo *) NULL)
616 LockSemaphoreInfo(splay_tree->semaphore);
617 SplaySplayTree(splay_tree,key);
618 splay_tree->key=(void *) NULL;
619 if (splay_tree->compare != (int (*)(const void *,const void *)) NULL)
620 compare=splay_tree->compare(splay_tree->root->key,key);
622 compare=(splay_tree->root->key > key) ? 1 :
623 ((splay_tree->root->key < key) ? -1 : 0);
626 UnlockSemaphoreInfo(splay_tree->semaphore);
629 left=splay_tree->root->left;
630 right=splay_tree->root->right;
631 if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
632 (splay_tree->root->value != (void *) NULL))
633 splay_tree->root->value=splay_tree->relinquish_value(
634 splay_tree->root->value);
635 if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
636 (splay_tree->root->key != (void *) NULL))
637 splay_tree->root->key=splay_tree->relinquish_key(splay_tree->root->key);
638 splay_tree->root=(NodeInfo *) RelinquishMagickMemory(splay_tree->root);
640 if (left == (NodeInfo *) NULL)
642 splay_tree->root=right;
643 UnlockSemaphoreInfo(splay_tree->semaphore);
646 splay_tree->root=left;
647 if (right != (NodeInfo *) NULL)
649 while (left->right != (NodeInfo *) NULL)
653 UnlockSemaphoreInfo(splay_tree->semaphore);
658 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
662 % D e s t r o y S p l a y T r e e %
666 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
668 % DestroySplayTree() destroys the splay-tree.
670 % The format of the DestroySplayTree method is:
672 % SplayTreeInfo *DestroySplayTree(SplayTreeInfo *splay_tree)
674 % A description of each parameter follows:
676 % o splay_tree: the splay tree.
679 MagickExport SplayTreeInfo *DestroySplayTree(SplayTreeInfo *splay_tree)
688 LockSemaphoreInfo(splay_tree->semaphore);
689 if (splay_tree->root != (NodeInfo *) NULL)
691 if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
692 (splay_tree->root->value != (void *) NULL))
693 splay_tree->root->value=splay_tree->relinquish_value(
694 splay_tree->root->value);
695 if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
696 (splay_tree->root->key != (void *) NULL))
697 splay_tree->root->key=splay_tree->relinquish_key(splay_tree->root->key);
698 splay_tree->root->key=(void *) NULL;
699 for (pend=splay_tree->root; pend != (NodeInfo *) NULL; )
702 for (pend=(NodeInfo *) NULL; active != (NodeInfo *) NULL; )
704 if (active->left != (NodeInfo *) NULL)
706 if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
707 (active->left->value != (void *) NULL))
708 active->left->value=splay_tree->relinquish_value(
709 active->left->value);
710 if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
711 (active->left->key != (void *) NULL))
712 active->left->key=splay_tree->relinquish_key(active->left->key);
713 active->left->key=(void *) pend;
716 if (active->right != (NodeInfo *) NULL)
718 if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
719 (active->right->value != (void *) NULL))
720 active->right->value=splay_tree->relinquish_value(
721 active->right->value);
722 if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
723 (active->right->key != (void *) NULL))
724 active->right->key=splay_tree->relinquish_key(
726 active->right->key=(void *) pend;
730 active=(NodeInfo *) node->key;
731 node=(NodeInfo *) RelinquishMagickMemory(node);
735 splay_tree->signature=(~MagickSignature);
736 UnlockSemaphoreInfo(splay_tree->semaphore);
737 DestroySemaphoreInfo(&splay_tree->semaphore);
738 splay_tree=(SplayTreeInfo *) RelinquishMagickMemory(splay_tree);
743 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
747 % G e t N e x t K e y I n S p l a y T r e e %
751 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
753 % GetNextKeyInSplayTree() gets the next key in the splay-tree.
755 % The format of the GetNextKeyInSplayTree method is:
757 % const void *GetNextKeyInSplayTree(SplayTreeInfo *splay_tree)
759 % A description of each parameter follows:
761 % o splay_tree: the splay tree.
766 MagickExport const void *GetNextKeyInSplayTree(SplayTreeInfo *splay_tree)
774 assert(splay_tree != (SplayTreeInfo *) NULL);
775 assert(splay_tree->signature == MagickSignature);
776 if (splay_tree->debug != MagickFalse)
777 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
778 if ((splay_tree->root == (NodeInfo *) NULL) ||
779 (splay_tree->next == (void *) NULL))
780 return((void *) NULL);
781 LockSemaphoreInfo(splay_tree->semaphore);
782 SplaySplayTree(splay_tree,splay_tree->next);
783 splay_tree->next=(void *) NULL;
784 node=splay_tree->root->right;
785 if (node != (NodeInfo *) NULL)
787 while (node->left != (NodeInfo *) NULL)
789 splay_tree->next=node->key;
791 key=splay_tree->root->key;
792 UnlockSemaphoreInfo(splay_tree->semaphore);
797 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
801 % G e t N e x t V a l u e I n S p l a y T r e e %
805 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
807 % GetNextValueInSplayTree() gets the next value in the splay-tree.
809 % The format of the GetNextValueInSplayTree method is:
811 % const void *GetNextValueInSplayTree(SplayTreeInfo *splay_tree)
813 % A description of each parameter follows:
815 % o splay_tree: the splay tree.
820 MagickExport const void *GetNextValueInSplayTree(SplayTreeInfo *splay_tree)
828 assert(splay_tree != (SplayTreeInfo *) NULL);
829 assert(splay_tree->signature == MagickSignature);
830 if (splay_tree->debug != MagickFalse)
831 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
832 if ((splay_tree->root == (NodeInfo *) NULL) ||
833 (splay_tree->next == (void *) NULL))
834 return((void *) NULL);
835 LockSemaphoreInfo(splay_tree->semaphore);
836 SplaySplayTree(splay_tree,splay_tree->next);
837 splay_tree->next=(void *) NULL;
838 node=splay_tree->root->right;
839 if (node != (NodeInfo *) NULL)
841 while (node->left != (NodeInfo *) NULL)
843 splay_tree->next=node->key;
845 value=splay_tree->root->value;
846 UnlockSemaphoreInfo(splay_tree->semaphore);
851 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
855 % G e t V a l u e F r o m S p l a y T r e e %
859 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
861 % GetValueFromSplayTree() gets a value from the splay-tree by its key.
863 % Note, the value is a constant. Do not attempt to free it.
865 % The format of the GetValueFromSplayTree method is:
867 % const void *GetValueFromSplayTree(SplayTreeInfo *splay_tree,
870 % A description of each parameter follows:
872 % o splay_tree: the splay tree.
877 MagickExport const void *GetValueFromSplayTree(SplayTreeInfo *splay_tree,
886 assert(splay_tree != (SplayTreeInfo *) NULL);
887 assert(splay_tree->signature == MagickSignature);
888 if (splay_tree->debug != MagickFalse)
889 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
890 if (splay_tree->root == (NodeInfo *) NULL)
891 return((void *) NULL);
892 LockSemaphoreInfo(splay_tree->semaphore);
893 SplaySplayTree(splay_tree,key);
894 if (splay_tree->compare != (int (*)(const void *,const void *)) NULL)
895 compare=splay_tree->compare(splay_tree->root->key,key);
897 compare=(splay_tree->root->key > key) ? 1 :
898 ((splay_tree->root->key < key) ? -1 : 0);
901 UnlockSemaphoreInfo(splay_tree->semaphore);
902 return((void *) NULL);
904 value=splay_tree->root->value;
905 UnlockSemaphoreInfo(splay_tree->semaphore);
910 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
914 % 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 %
918 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
920 % GetNumberOfNodesInSplayTree() returns the number of nodes in the splay-tree.
922 % The format of the GetNumberOfNodesInSplayTree method is:
924 % size_t GetNumberOfNodesInSplayTree(
925 % const SplayTreeInfo *splay_tree)
927 % A description of each parameter follows:
929 % o splay_tree: the splay tree.
932 MagickExport size_t GetNumberOfNodesInSplayTree(
933 const SplayTreeInfo *splay_tree)
935 assert(splay_tree != (SplayTreeInfo *) NULL);
936 assert(splay_tree->signature == MagickSignature);
937 if (splay_tree->debug != MagickFalse)
938 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
939 return(splay_tree->nodes);
943 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
947 % I t e r a t e O v e r S p l a y T r e e %
951 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
953 % IterateOverSplayTree() iterates over the splay-tree.
955 % The format of the IterateOverSplayTree method is:
957 % int IterateOverSplayTree(SplayTreeInfo *splay_tree,
958 % int (*method)(NodeInfo *,void *),const void *value)
960 % A description of each parameter follows:
962 % o splay_tree: the splay-tree info.
964 % o method: the method.
966 % o value: the value.
969 static int IterateOverSplayTree(SplayTreeInfo *splay_tree,
970 int (*method)(NodeInfo *,const void *),const void *value)
1001 if (splay_tree->root == (NodeInfo *) NULL)
1003 nodes=(NodeInfo **) AcquireQuantumMemory((size_t) splay_tree->nodes,
1005 transitions=(unsigned char *) AcquireQuantumMemory((size_t) splay_tree->nodes,
1006 sizeof(*transitions));
1007 if ((nodes == (NodeInfo **) NULL) || (transitions == (unsigned char *) NULL))
1008 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1010 final_transition=MagickFalse;
1011 nodes[0]=splay_tree->root;
1012 transitions[0]=(unsigned char) LeftTransition;
1013 for (i=0; final_transition == MagickFalse; )
1016 transition=(TransitionType) transitions[i];
1019 case LeftTransition:
1021 transitions[i]=(unsigned char) DownTransition;
1022 if (node->left == (NodeInfo *) NULL)
1025 nodes[i]=node->left;
1026 transitions[i]=(unsigned char) LeftTransition;
1029 case RightTransition:
1031 transitions[i]=(unsigned char) UpTransition;
1032 if (node->right == (NodeInfo *) NULL)
1035 nodes[i]=node->right;
1036 transitions[i]=(unsigned char) LeftTransition;
1039 case DownTransition:
1042 transitions[i]=(unsigned char) RightTransition;
1043 status=(*method)(node,value);
1045 final_transition=MagickTrue;
1052 final_transition=MagickTrue;
1060 nodes=(NodeInfo **) RelinquishMagickMemory(nodes);
1061 transitions=(unsigned char *) RelinquishMagickMemory(transitions);
1066 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1070 % N e w S p l a y T r e e %
1074 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1076 % NewSplayTree() returns a pointer to a SplayTreeInfo structure initialized
1077 % to default values.
1079 % The format of the NewSplayTree method is:
1081 % SplayTreeInfo *NewSplayTree(int (*compare)(const void *,const void *),
1082 % void *(*relinquish_key)(void *),void *(*relinquish_value)(void *))
1084 % A description of each parameter follows:
1086 % o compare: the compare method.
1088 % o relinquish_key: the key deallocation method, typically
1089 % RelinquishMagickMemory(), called whenever a key is removed from the
1092 % o relinquish_value: the value deallocation method; typically
1093 % RelinquishMagickMemory(), called whenever a value object is removed from
1097 MagickExport SplayTreeInfo *NewSplayTree(
1098 int (*compare)(const void *,const void *),void *(*relinquish_key)(void *),
1099 void *(*relinquish_value)(void *))
1104 splay_tree=(SplayTreeInfo *) AcquireMagickMemory(sizeof(*splay_tree));
1105 if (splay_tree == (SplayTreeInfo *) NULL)
1106 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1107 (void) ResetMagickMemory(splay_tree,0,sizeof(*splay_tree));
1108 splay_tree->root=(NodeInfo *) NULL;
1109 splay_tree->compare=compare;
1110 splay_tree->relinquish_key=relinquish_key;
1111 splay_tree->relinquish_value=relinquish_value;
1112 splay_tree->balance=MagickFalse;
1113 splay_tree->key=(void *) NULL;
1114 splay_tree->next=(void *) NULL;
1115 splay_tree->nodes=0;
1116 splay_tree->debug=IsEventLogging();
1117 splay_tree->semaphore=AllocateSemaphoreInfo();
1118 splay_tree->signature=MagickSignature;
1123 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1127 % 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 %
1131 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1133 % RemoveNodeByValueFromSplayTree() removes a node by value from the splay-tree
1134 % and returns its key.
1136 % The format of the RemoveNodeByValueFromSplayTree method is:
1138 % void *RemoveNodeByValueFromSplayTree(SplayTreeInfo *splay_tree,
1139 % const void *value)
1141 % A description of each parameter follows:
1143 % o splay_tree: the splay-tree info.
1145 % o value: the value.
1148 MagickExport void *RemoveNodeByValueFromSplayTree(SplayTreeInfo *splay_tree,
1158 assert(splay_tree != (SplayTreeInfo *) NULL);
1159 assert(splay_tree->signature == MagickSignature);
1160 if (splay_tree->debug != MagickFalse)
1161 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1163 if (splay_tree->root == (NodeInfo *) NULL)
1165 LockSemaphoreInfo(splay_tree->semaphore);
1166 next=(NodeInfo *) GetFirstSplayTreeNode(splay_tree);
1167 while (next != (NodeInfo *) NULL)
1169 SplaySplayTree(splay_tree,next);
1170 next=(NodeInfo *) NULL;
1171 node=splay_tree->root->right;
1172 if (node != (NodeInfo *) NULL)
1174 while (node->left != (NodeInfo *) NULL)
1176 next=(NodeInfo *) node->key;
1178 if (splay_tree->root->value == value)
1188 We found the node that matches the value; now remove it.
1190 key=splay_tree->root->key;
1191 SplaySplayTree(splay_tree,key);
1192 splay_tree->key=(void *) NULL;
1193 if (splay_tree->compare != (int (*)(const void *,const void *)) NULL)
1194 compare=splay_tree->compare(splay_tree->root->key,key);
1196 compare=(splay_tree->root->key > key) ? 1 :
1197 ((splay_tree->root->key < key) ? -1 : 0);
1200 UnlockSemaphoreInfo(splay_tree->semaphore);
1203 left=splay_tree->root->left;
1204 right=splay_tree->root->right;
1205 if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
1206 (splay_tree->root->value != (void *) NULL))
1207 splay_tree->root->value=splay_tree->relinquish_value(
1208 splay_tree->root->value);
1209 splay_tree->root=(NodeInfo *) RelinquishMagickMemory(splay_tree->root);
1210 splay_tree->nodes--;
1211 if (left == (NodeInfo *) NULL)
1213 splay_tree->root=right;
1214 UnlockSemaphoreInfo(splay_tree->semaphore);
1217 splay_tree->root=left;
1218 if (right != (NodeInfo *) NULL)
1220 while (left->right != (NodeInfo *) NULL)
1224 UnlockSemaphoreInfo(splay_tree->semaphore);
1228 UnlockSemaphoreInfo(splay_tree->semaphore);
1233 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1237 % R e m o v e N o d e F r o m S p l a y T r e e %
1241 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1243 % RemoveNodeFromSplayTree() removes a node from the splay-tree and returns its
1246 % The format of the RemoveNodeFromSplayTree method is:
1248 % void *RemoveNodeFromSplayTree(SplayTreeInfo *splay_tree,const void *key)
1250 % A description of each parameter follows:
1252 % o splay_tree: the splay-tree info.
1257 MagickExport void *RemoveNodeFromSplayTree(SplayTreeInfo *splay_tree,
1270 assert(splay_tree != (SplayTreeInfo *) NULL);
1271 assert(splay_tree->signature == MagickSignature);
1272 if (splay_tree->debug != MagickFalse)
1273 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1274 value=(void *) NULL;
1275 if (splay_tree->root == (NodeInfo *) NULL)
1277 LockSemaphoreInfo(splay_tree->semaphore);
1278 SplaySplayTree(splay_tree,key);
1279 splay_tree->key=(void *) NULL;
1280 if (splay_tree->compare != (int (*)(const void *,const void *)) NULL)
1281 compare=splay_tree->compare(splay_tree->root->key,key);
1283 compare=(splay_tree->root->key > key) ? 1 :
1284 ((splay_tree->root->key < key) ? -1 : 0);
1287 UnlockSemaphoreInfo(splay_tree->semaphore);
1290 left=splay_tree->root->left;
1291 right=splay_tree->root->right;
1292 value=splay_tree->root->value;
1293 if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
1294 (splay_tree->root->key != (void *) NULL))
1295 splay_tree->root->key=splay_tree->relinquish_key(splay_tree->root->key);
1296 splay_tree->root=(NodeInfo *) RelinquishMagickMemory(splay_tree->root);
1297 splay_tree->nodes--;
1298 if (left == (NodeInfo *) NULL)
1300 splay_tree->root=right;
1301 UnlockSemaphoreInfo(splay_tree->semaphore);
1304 splay_tree->root=left;
1305 if (right != (NodeInfo *) NULL)
1307 while (left->right != (NodeInfo *) NULL)
1311 UnlockSemaphoreInfo(splay_tree->semaphore);
1316 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1320 % R e s e t S p l a y T r e e %
1324 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1326 % ResetSplayTree() resets the splay-tree. That is, it deletes all the nodes
1329 % The format of the ResetSplayTree method is:
1331 % ResetSplayTree(SplayTreeInfo *splay_tree)
1333 % A description of each parameter follows:
1335 % o splay_tree: the splay tree.
1338 MagickExport void ResetSplayTree(SplayTreeInfo *splay_tree)
1347 assert(splay_tree != (SplayTreeInfo *) NULL);
1348 assert(splay_tree->signature == MagickSignature);
1349 if (splay_tree->debug != MagickFalse)
1350 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1351 LockSemaphoreInfo(splay_tree->semaphore);
1352 if (splay_tree->root != (NodeInfo *) NULL)
1354 if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
1355 (splay_tree->root->value != (void *) NULL))
1356 splay_tree->root->value=splay_tree->relinquish_value(
1357 splay_tree->root->value);
1358 if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
1359 (splay_tree->root->key != (void *) NULL))
1360 splay_tree->root->key=splay_tree->relinquish_key(splay_tree->root->key);
1361 splay_tree->root->key=(void *) NULL;
1362 for (pend=splay_tree->root; pend != (NodeInfo *) NULL; )
1365 for (pend=(NodeInfo *) NULL; active != (NodeInfo *) NULL; )
1367 if (active->left != (NodeInfo *) NULL)
1369 if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
1370 (active->left->value != (void *) NULL))
1371 active->left->value=splay_tree->relinquish_value(
1372 active->left->value);
1373 if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
1374 (active->left->key != (void *) NULL))
1375 active->left->key=splay_tree->relinquish_key(active->left->key);
1376 active->left->key=(void *) pend;
1379 if (active->right != (NodeInfo *) NULL)
1381 if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
1382 (active->right->value != (void *) NULL))
1383 active->right->value=splay_tree->relinquish_value(
1384 active->right->value);
1385 if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
1386 (active->right->key != (void *) NULL))
1387 active->right->key=splay_tree->relinquish_key(
1388 active->right->key);
1389 active->right->key=(void *) pend;
1393 active=(NodeInfo *) node->key;
1394 node=(NodeInfo *) RelinquishMagickMemory(node);
1398 splay_tree->root=(NodeInfo *) NULL;
1399 splay_tree->key=(void *) NULL;
1400 splay_tree->next=(void *) NULL;
1401 splay_tree->nodes=0;
1402 splay_tree->balance=MagickFalse;
1403 UnlockSemaphoreInfo(splay_tree->semaphore);
1407 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1411 % R e s e t S p l a y T r e e I t e r a t o r %
1415 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1417 % ResetSplayTreeIterator() resets the splay-tree iterator. Use it in
1418 % conjunction with GetNextValueInSplayTree() to iterate over all the nodes in
1421 % The format of the ResetSplayTreeIterator method is:
1423 % ResetSplayTreeIterator(SplayTreeInfo *splay_tree)
1425 % A description of each parameter follows:
1427 % o splay_tree: the splay tree.
1430 MagickExport void ResetSplayTreeIterator(SplayTreeInfo *splay_tree)
1432 assert(splay_tree != (SplayTreeInfo *) NULL);
1433 assert(splay_tree->signature == MagickSignature);
1434 if (splay_tree->debug != MagickFalse)
1435 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1436 LockSemaphoreInfo(splay_tree->semaphore);
1437 splay_tree->next=GetFirstSplayTreeNode(splay_tree);
1438 UnlockSemaphoreInfo(splay_tree->semaphore);
1442 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1446 % S p l a y S p l a y T r e e %
1450 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1452 % SplaySplayTree() splays the splay-tree.
1454 % The format of the SplaySplayTree method is:
1456 % void SplaySplayTree(SplayTreeInfo *splay_tree,const void *key,
1457 % NodeInfo **node,NodeInfo **parent,NodeInfo **grandparent)
1459 % A description of each parameter follows:
1461 % o splay_tree: the splay-tree info.
1467 % o parent: the parent node.
1469 % o grandparent: the grandparent node.
1473 static NodeInfo *Splay(SplayTreeInfo *splay_tree,const size_t depth,
1474 const void *key,NodeInfo **node,NodeInfo **parent,NodeInfo **grandparent)
1487 if (n == (NodeInfo *) NULL)
1489 if (splay_tree->compare != (int (*)(const void *,const void *)) NULL)
1490 compare=splay_tree->compare(n->key,key);
1492 compare=(n->key > key) ? 1 : ((n->key < key) ? -1 : 0);
1493 next=(NodeInfo **) NULL;
1499 if (next != (NodeInfo **) NULL)
1501 if (depth >= MaxSplayTreeDepth)
1503 splay_tree->balance=MagickTrue;
1506 n=Splay(splay_tree,depth+1,key,next,node,parent);
1507 if ((n != *node) || (splay_tree->balance != MagickFalse))
1510 if (parent == (NodeInfo **) NULL)
1512 if (grandparent == (NodeInfo **) NULL)
1514 if (n == (*parent)->left)
1527 if ((n == (*parent)->left) && (*parent == (*grandparent)->left))
1530 (*grandparent)->left=p->right;
1531 p->right=(*grandparent);
1537 if ((n == (*parent)->right) && (*parent == (*grandparent)->right))
1540 (*grandparent)->right=p->left;
1541 p->left=(*grandparent);
1547 if (n == (*parent)->left)
1549 (*parent)->left=n->right;
1551 (*grandparent)->right=n->left;
1552 n->left=(*grandparent);
1556 (*parent)->right=n->left;
1558 (*grandparent)->left=n->right;
1559 n->right=(*grandparent);
1564 static void SplaySplayTree(SplayTreeInfo *splay_tree,const void *key)
1566 if (splay_tree->root == (NodeInfo *) NULL)
1568 if (splay_tree->key != (void *) NULL)
1573 if (splay_tree->compare != (int (*)(const void *,const void *)) NULL)
1574 compare=splay_tree->compare(splay_tree->root->key,key);
1576 compare=(splay_tree->key > key) ? 1 :
1577 ((splay_tree->key < key) ? -1 : 0);
1581 (void) Splay(splay_tree,0UL,key,&splay_tree->root,(NodeInfo **) NULL,
1582 (NodeInfo **) NULL);
1583 if (splay_tree->balance != MagickFalse)
1585 BalanceSplayTree(splay_tree);
1586 (void) Splay(splay_tree,0UL,key,&splay_tree->root,(NodeInfo **) NULL,
1587 (NodeInfo **) NULL);
1588 if (splay_tree->balance != MagickFalse)
1589 ThrowFatalException(ResourceLimitFatalError,
1590 "MemoryAllocationFailed");
1592 splay_tree->key=(void *) key;