MagickCore  6.7.5
splay-tree.c
Go to the documentation of this file.
00001 /*
00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00003 %                                                                             %
00004 %                                                                             %
00005 %                                                                             %
00006 %                      SSSSS  PPPP   L       AAA   Y   Y                      %
00007 %                      SS     P   P  L      A   A   Y Y                       %
00008 %                       SSS   PPPP   L      AAAAA    Y                        %
00009 %                         SS  P      L      A   A    Y                        %
00010 %                      SSSSS  P      LLLLL  A   A    Y                        %
00011 %                                                                             %
00012 %                         TTTTT  RRRR   EEEEE  EEEEE                          %
00013 %                           T    R   R  E      E                              %
00014 %                           T    RRRR   EEE    EEE                            %
00015 %                           T    R R    E      E                              %
00016 %                           T    R  R   EEEEE  EEEEE                          %
00017 %                                                                             %
00018 %                                                                             %
00019 %             MagickCore Self-adjusting Binary Search Tree Methods            %
00020 %                                                                             %
00021 %                              Software Design                                %
00022 %                                John Cristy                                  %
00023 %                               December 2002                                 %
00024 %                                                                             %
00025 %                                                                             %
00026 %  Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization      %
00027 %  dedicated to making software imaging solutions freely available.           %
00028 %                                                                             %
00029 %  You may not use this file except in compliance with the License.  You may  %
00030 %  obtain a copy of the License at                                            %
00031 %                                                                             %
00032 %    http://www.imagemagick.org/script/license.php                            %
00033 %                                                                             %
00034 %  Unless required by applicable law or agreed to in writing, software        %
00035 %  distributed under the License is distributed on an "AS IS" BASIS,          %
00036 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
00037 %  See the License for the specific language governing permissions and        %
00038 %  limitations under the License.                                             %
00039 %                                                                             %
00040 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00041 %
00042 %  This module implements the standard handy splay-tree methods for storing and
00043 %  retrieving large numbers of data elements.  It is loosely based on the Java
00044 %  implementation of these algorithms.
00045 %
00046 */
00047 
00048 /*
00049   Include declarations.
00050 */
00051 #include "MagickCore/studio.h"
00052 #include "MagickCore/exception.h"
00053 #include "MagickCore/exception-private.h"
00054 #include "MagickCore/log.h"
00055 #include "MagickCore/memory_.h"
00056 #include "MagickCore/splay-tree.h"
00057 #include "MagickCore/semaphore.h"
00058 #include "MagickCore/string_.h"
00059 
00060 /*
00061   Define declarations.
00062 */
00063 #define MaxSplayTreeDepth  1024
00064 
00065 /*
00066   Typedef declarations.
00067 */
00068 typedef struct _NodeInfo
00069 {
00070   void
00071     *key;
00072 
00073   void
00074     *value;
00075 
00076   struct _NodeInfo
00077     *left,
00078     *right;
00079 } NodeInfo;
00080 
00081 struct _SplayTreeInfo
00082 {
00083   NodeInfo
00084     *root;
00085 
00086   int
00087     (*compare)(const void *,const void *);
00088 
00089   void
00090     *(*relinquish_key)(void *),
00091     *(*relinquish_value)(void *);
00092 
00093   MagickBooleanType
00094     balance;
00095 
00096   void
00097     *key,
00098     *next;
00099 
00100   size_t
00101     nodes;
00102 
00103   MagickBooleanType
00104     debug;
00105 
00106   SemaphoreInfo
00107     *semaphore;
00108 
00109   size_t
00110     signature;
00111 };
00112 
00113 /*
00114   Forward declarations.
00115 */
00116 static int
00117   IterateOverSplayTree(SplayTreeInfo *,int (*)(NodeInfo *,const void *),
00118     const void *);
00119 
00120 static void
00121   SplaySplayTree(SplayTreeInfo *,const void *);
00122 
00123 /*
00124 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00125 %                                                                             %
00126 %                                                                             %
00127 %                                                                             %
00128 %   A d d V a l u e T o S p l a y T r e e                                     %
00129 %                                                                             %
00130 %                                                                             %
00131 %                                                                             %
00132 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00133 %
00134 %  AddValueToSplayTree() adds the given key and value to the splay-tree.
00135 %  Both key and value are used as is, without coping or cloning.
00136 %
00137 %  The format of the AddValueToSplayTree method is:
00138 %
00139 %      MagickBooleanType AddValueToSplayTree(SplayTreeInfo *splay_tree,
00140 %        const void *key,const void *value)
00141 %
00142 %  A description of each parameter follows:
00143 %
00144 %    o splay_tree: the splay-tree info.
00145 %
00146 %    o key: the key.
00147 %
00148 %    o value: the value.
00149 %
00150 */
00151 MagickExport MagickBooleanType AddValueToSplayTree(SplayTreeInfo *splay_tree,
00152   const void *key,const void *value)
00153 {
00154   int
00155     compare;
00156 
00157   register NodeInfo
00158     *node;
00159 
00160   LockSemaphoreInfo(splay_tree->semaphore);
00161   SplaySplayTree(splay_tree,key);
00162   compare=0;
00163   if (splay_tree->root != (NodeInfo *) NULL)
00164     {
00165       if (splay_tree->compare != (int (*)(const void *,const void *)) NULL)
00166         compare=splay_tree->compare(splay_tree->root->key,key);
00167       else
00168         compare=(splay_tree->root->key > key) ? 1 :
00169           ((splay_tree->root->key < key) ? -1 : 0);
00170       if (compare == 0)
00171         {
00172           if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
00173               (splay_tree->root->value != (void *) NULL))
00174             splay_tree->root->value=splay_tree->relinquish_value(
00175               splay_tree->root->value);
00176           if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
00177               (splay_tree->root->key != (void *) NULL))
00178             splay_tree->root->key=splay_tree->relinquish_key(
00179               splay_tree->root->key);
00180           splay_tree->root->key=(void *) key;
00181           splay_tree->root->value=(void *) value;
00182           UnlockSemaphoreInfo(splay_tree->semaphore);
00183           return(MagickTrue);
00184         }
00185     }
00186   node=(NodeInfo *) AcquireMagickMemory(sizeof(*node));
00187   if (node == (NodeInfo *) NULL)
00188     {
00189       UnlockSemaphoreInfo(splay_tree->semaphore);
00190       return(MagickFalse);
00191     }
00192   node->key=(void *) key;
00193   node->value=(void *) value;
00194   if (splay_tree->root == (NodeInfo *) NULL)
00195     {
00196       node->left=(NodeInfo *) NULL;
00197       node->right=(NodeInfo *) NULL;
00198     }
00199   else
00200     if (compare < 0)
00201       {
00202         node->left=splay_tree->root;
00203         node->right=node->left->right;
00204         node->left->right=(NodeInfo *) NULL;
00205       }
00206     else
00207       {
00208         node->right=splay_tree->root;
00209         node->left=node->right->left;
00210         node->right->left=(NodeInfo *) NULL;
00211       }
00212   splay_tree->root=node;
00213   splay_tree->key=(void *) NULL;
00214   splay_tree->nodes++;
00215   UnlockSemaphoreInfo(splay_tree->semaphore);
00216   return(MagickTrue);
00217 }
00218 
00219 /*
00220 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00221 %                                                                             %
00222 %                                                                             %
00223 %                                                                             %
00224 %   B a l a n c e S p l a y T r e e                                           %
00225 %                                                                             %
00226 %                                                                             %
00227 %                                                                             %
00228 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00229 %
00230 %  BalanceSplayTree() balances the splay-tree.
00231 %
00232 %  The format of the BalanceSplayTree method is:
00233 %
00234 %      void *BalanceSplayTree(SplayTreeInfo *splay_tree,const void *key)
00235 %
00236 %  A description of each parameter follows:
00237 %
00238 %    o splay_tree: the splay-tree info.
00239 %
00240 %    o key: the key.
00241 %
00242 */
00243 
00244 static NodeInfo *LinkSplayTreeNodes(NodeInfo **nodes,const size_t low,
00245   const size_t high)
00246 {
00247   register NodeInfo
00248     *node;
00249 
00250   size_t
00251     bisect;
00252 
00253   bisect=low+(high-low)/2;
00254   node=nodes[bisect];
00255   if ((low+1) > bisect)
00256     node->left=(NodeInfo *) NULL;
00257   else
00258     node->left=LinkSplayTreeNodes(nodes,low,bisect-1);
00259   if ((bisect+1) > high)
00260     node->right=(NodeInfo *) NULL;
00261   else
00262     node->right=LinkSplayTreeNodes(nodes,bisect+1,high);
00263   return(node);
00264 }
00265 
00266 static int SplayTreeToNodeArray(NodeInfo *node,const void *nodes)
00267 {
00268   register const NodeInfo
00269     ***p;
00270 
00271   p=(const NodeInfo ***) nodes;
00272   *(*p)=node;
00273   (*p)++;
00274   return(0);
00275 }
00276 
00277 static void BalanceSplayTree(SplayTreeInfo *splay_tree)
00278 {
00279   NodeInfo
00280     **node,
00281     **nodes;
00282 
00283   if (splay_tree->nodes <= 2)
00284     {
00285       splay_tree->balance=MagickFalse;
00286       return;
00287     }
00288   nodes=(NodeInfo **) AcquireQuantumMemory((size_t) splay_tree->nodes,
00289     sizeof(*nodes));
00290   if (nodes == (NodeInfo **) NULL)
00291     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
00292   node=nodes;
00293   (void) IterateOverSplayTree(splay_tree,SplayTreeToNodeArray,
00294     (const void *) &node);
00295   splay_tree->root=LinkSplayTreeNodes(nodes,0,splay_tree->nodes-1);
00296   splay_tree->balance=MagickFalse;
00297   nodes=(NodeInfo **) RelinquishMagickMemory(nodes);
00298 }
00299 
00300 /*
00301 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00302 %                                                                             %
00303 %                                                                             %
00304 %                                                                             %
00305 %   C l o n e S p l a y T r e e                                               %
00306 %                                                                             %
00307 %                                                                             %
00308 %                                                                             %
00309 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00310 %
00311 %  CloneSplayTree() clones the splay tree.
00312 %
00313 %  The format of the CloneSplayTree method is:
00314 %
00315 %      SplayTreeInfo *CloneSplayTree(SplayTreeInfo *splay_tree,
00316 %        void *(*clone_key)(void *),void *(*cline_value)(void *))
00317 %
00318 %  A description of each parameter follows:
00319 %
00320 %    o splay_tree: the splay tree.
00321 %
00322 %    o clone_key: the key clone method, typically ConstantString(), called
00323 %      whenever a key is added to the splay-tree.
00324 %
00325 %    o clone_value: the value clone method;  typically ConstantString(), called
00326 %      whenever a value object is added to the splay-tree.
00327 %
00328 */
00329 
00330 static void *GetFirstSplayTreeNode(SplayTreeInfo *splay_tree)
00331 {
00332   register NodeInfo
00333     *node;
00334 
00335   node=splay_tree->root;
00336   if (splay_tree->root == (NodeInfo *) NULL)
00337     return((NodeInfo *) NULL);
00338   while (node->left != (NodeInfo *) NULL)
00339     node=node->left;
00340   return(node->key);
00341 }
00342 
00343 MagickExport SplayTreeInfo *CloneSplayTree(SplayTreeInfo *splay_tree,
00344   void *(*clone_key)(void *),void *(*clone_value)(void *))
00345 {
00346   register NodeInfo
00347     *next,
00348     *node;
00349 
00350   SplayTreeInfo
00351     *clone_tree;
00352 
00353   assert(splay_tree != (SplayTreeInfo *) NULL);
00354   assert(splay_tree->signature == MagickSignature);
00355   if (splay_tree->debug != MagickFalse)
00356     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00357   clone_tree=NewSplayTree(splay_tree->compare,splay_tree->relinquish_key,
00358     splay_tree->relinquish_value);
00359   LockSemaphoreInfo(splay_tree->semaphore);
00360   if (splay_tree->root == (NodeInfo *) NULL)
00361     {
00362       UnlockSemaphoreInfo(splay_tree->semaphore);
00363       return(clone_tree);
00364     }
00365   next=(NodeInfo *) GetFirstSplayTreeNode(splay_tree);
00366   while (next != (NodeInfo *) NULL)
00367   {
00368     SplaySplayTree(splay_tree,next);
00369     (void) AddValueToSplayTree(clone_tree,clone_key(splay_tree->root->key),
00370       clone_value(splay_tree->root->value));
00371     next=(NodeInfo *) NULL;
00372     node=splay_tree->root->right;
00373     if (node != (NodeInfo *) NULL)
00374       {
00375         while (node->left != (NodeInfo *) NULL)
00376           node=node->left;
00377         next=(NodeInfo *) node->key;
00378       }
00379   }
00380   UnlockSemaphoreInfo(splay_tree->semaphore);
00381   return(clone_tree);
00382 }
00383 
00384 /*
00385 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00386 %                                                                             %
00387 %                                                                             %
00388 %                                                                             %
00389 %   C o m p a r e S p l a y T r e e S t r i n g                               %
00390 %                                                                             %
00391 %                                                                             %
00392 %                                                                             %
00393 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00394 %
00395 %  CompareSplayTreeString() method finds a node in a splay-tree based on the
00396 %  contents of a string.
00397 %
00398 %  The format of the CompareSplayTreeString method is:
00399 %
00400 %      int CompareSplayTreeString(const void *target,const void *source)
00401 %
00402 %  A description of each parameter follows:
00403 %
00404 %    o target: the target string.
00405 %
00406 %    o source: the source string.
00407 %
00408 */
00409 MagickExport int CompareSplayTreeString(const void *target,const void *source)
00410 {
00411   const char
00412     *p,
00413     *q;
00414 
00415   p=(const char *) target;
00416   q=(const char *) source;
00417   return(LocaleCompare(p,q));
00418 }
00419 
00420 /*
00421 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00422 %                                                                             %
00423 %                                                                             %
00424 %                                                                             %
00425 %   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                       %
00426 %                                                                             %
00427 %                                                                             %
00428 %                                                                             %
00429 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00430 %
00431 %  CompareSplayTreeStringInfo() finds a node in a splay-tree based on the
00432 %  contents of a string.
00433 %
00434 %  The format of the CompareSplayTreeStringInfo method is:
00435 %
00436 %      int CompareSplayTreeStringInfo(const void *target,const void *source)
00437 %
00438 %  A description of each parameter follows:
00439 %
00440 %    o target: the target string.
00441 %
00442 %    o source: the source string.
00443 %
00444 */
00445 MagickExport int CompareSplayTreeStringInfo(const void *target,
00446   const void *source)
00447 {
00448   const StringInfo
00449     *p,
00450     *q;
00451 
00452   p=(const StringInfo *) target;
00453   q=(const StringInfo *) source;
00454   return(CompareStringInfo(p,q));
00455 }
00456 
00457 /*
00458 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00459 %                                                                             %
00460 %                                                                             %
00461 %                                                                             %
00462 %   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               %
00463 %                                                                             %
00464 %                                                                             %
00465 %                                                                             %
00466 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00467 %
00468 %  DeleteNodeByValueFromSplayTree() deletes a node by value from the
00469 %  splay-tree.
00470 %
00471 %  The format of the DeleteNodeByValueFromSplayTree method is:
00472 %
00473 %      MagickBooleanType DeleteNodeByValueFromSplayTree(
00474 %        SplayTreeInfo *splay_tree,const void *value)
00475 %
00476 %  A description of each parameter follows:
00477 %
00478 %    o splay_tree: the splay-tree info.
00479 %
00480 %    o value: the value.
00481 %
00482 */
00483 MagickExport MagickBooleanType DeleteNodeByValueFromSplayTree(
00484   SplayTreeInfo *splay_tree,const void *value)
00485 {
00486   register NodeInfo
00487     *next,
00488     *node;
00489 
00490   assert(splay_tree != (SplayTreeInfo *) NULL);
00491   assert(splay_tree->signature == MagickSignature);
00492   if (splay_tree->debug != MagickFalse)
00493     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00494   LockSemaphoreInfo(splay_tree->semaphore);
00495   if (splay_tree->root == (NodeInfo *) NULL)
00496     {
00497       UnlockSemaphoreInfo(splay_tree->semaphore);
00498       return(MagickFalse);
00499     }
00500   next=(NodeInfo *) GetFirstSplayTreeNode(splay_tree);
00501   while (next != (NodeInfo *) NULL)
00502   {
00503     SplaySplayTree(splay_tree,next);
00504     next=(NodeInfo *) NULL;
00505     node=splay_tree->root->right;
00506     if (node != (NodeInfo *) NULL)
00507       {
00508         while (node->left != (NodeInfo *) NULL)
00509           node=node->left;
00510         next=(NodeInfo *) node->key;
00511       }
00512     if (splay_tree->root->value == value)
00513       {
00514         int
00515           compare;
00516 
00517         register NodeInfo
00518           *left,
00519           *right;
00520 
00521         void
00522           *key;
00523 
00524         /*
00525           We found the node that matches the value; now delete it.
00526         */
00527         key=splay_tree->root->key;
00528         SplaySplayTree(splay_tree,key);
00529         splay_tree->key=(void *) NULL;
00530         if (splay_tree->compare != (int (*)(const void *,const void *)) NULL)
00531           compare=splay_tree->compare(splay_tree->root->key,key);
00532         else
00533           compare=(splay_tree->root->key > key) ? 1 :
00534             ((splay_tree->root->key < key) ? -1 : 0);
00535         if (compare != 0)
00536           {
00537             UnlockSemaphoreInfo(splay_tree->semaphore);
00538             return(MagickFalse);
00539           }
00540         left=splay_tree->root->left;
00541         right=splay_tree->root->right;
00542         if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
00543             (splay_tree->root->value != (void *) NULL))
00544           splay_tree->root->value=splay_tree->relinquish_value(
00545             splay_tree->root->value);
00546         if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
00547             (splay_tree->root->key != (void *) NULL))
00548           splay_tree->root->key=splay_tree->relinquish_key(
00549             splay_tree->root->key);
00550         splay_tree->root=(NodeInfo *) RelinquishMagickMemory(splay_tree->root);
00551         splay_tree->nodes--;
00552         if (left == (NodeInfo *) NULL)
00553           {
00554             splay_tree->root=right;
00555             UnlockSemaphoreInfo(splay_tree->semaphore);
00556             return(MagickTrue);
00557           }
00558         splay_tree->root=left;
00559         if (right != (NodeInfo *) NULL)
00560           {
00561             while (left->right != (NodeInfo *) NULL)
00562               left=left->right;
00563             left->right=right;
00564           }
00565         UnlockSemaphoreInfo(splay_tree->semaphore);
00566         return(MagickTrue);
00567       }
00568   }
00569   UnlockSemaphoreInfo(splay_tree->semaphore);
00570   return(MagickFalse);
00571 }
00572 
00573 /*
00574 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00575 %                                                                             %
00576 %                                                                             %
00577 %                                                                             %
00578 %   D e l e t e N o d e F r o m S p l a y T r e e                             %
00579 %                                                                             %
00580 %                                                                             %
00581 %                                                                             %
00582 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00583 %
00584 %  DeleteNodeFromSplayTree() deletes a node from the splay-tree.
00585 %
00586 %  The format of the DeleteNodeFromSplayTree method is:
00587 %
00588 %      MagickBooleanType DeleteNodeFromSplayTree(SplayTreeInfo *splay_tree,
00589 %        const void *key)
00590 %
00591 %  A description of each parameter follows:
00592 %
00593 %    o splay_tree: the splay-tree info.
00594 %
00595 %    o key: the key.
00596 %
00597 */
00598 MagickExport MagickBooleanType DeleteNodeFromSplayTree(
00599   SplayTreeInfo *splay_tree,const void *key)
00600 {
00601   int
00602     compare;
00603 
00604   register NodeInfo
00605     *left,
00606     *right;
00607 
00608   assert(splay_tree != (SplayTreeInfo *) NULL);
00609   assert(splay_tree->signature == MagickSignature);
00610   if (splay_tree->debug != MagickFalse)
00611     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00612   if (splay_tree->root == (NodeInfo *) NULL)
00613     return(MagickFalse);
00614   LockSemaphoreInfo(splay_tree->semaphore);
00615   SplaySplayTree(splay_tree,key);
00616   splay_tree->key=(void *) NULL;
00617   if (splay_tree->compare != (int (*)(const void *,const void *)) NULL)
00618     compare=splay_tree->compare(splay_tree->root->key,key);
00619   else
00620     compare=(splay_tree->root->key > key) ? 1 :
00621       ((splay_tree->root->key < key) ? -1 : 0);
00622   if (compare != 0)
00623     {
00624       UnlockSemaphoreInfo(splay_tree->semaphore);
00625       return(MagickFalse);
00626     }
00627   left=splay_tree->root->left;
00628   right=splay_tree->root->right;
00629   if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
00630       (splay_tree->root->value != (void *) NULL))
00631     splay_tree->root->value=splay_tree->relinquish_value(
00632       splay_tree->root->value);
00633   if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
00634       (splay_tree->root->key != (void *) NULL))
00635     splay_tree->root->key=splay_tree->relinquish_key(splay_tree->root->key);
00636   splay_tree->root=(NodeInfo *) RelinquishMagickMemory(splay_tree->root);
00637   splay_tree->nodes--;
00638   if (left == (NodeInfo *) NULL)
00639     {
00640       splay_tree->root=right;
00641       UnlockSemaphoreInfo(splay_tree->semaphore);
00642       return(MagickTrue);
00643     }
00644   splay_tree->root=left;
00645   if (right != (NodeInfo *) NULL)
00646     {
00647       while (left->right != (NodeInfo *) NULL)
00648         left=left->right;
00649       left->right=right;
00650     }
00651   UnlockSemaphoreInfo(splay_tree->semaphore);
00652   return(MagickTrue);
00653 }
00654 
00655 /*
00656 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00657 %                                                                             %
00658 %                                                                             %
00659 %                                                                             %
00660 %   D e s t r o y S p l a y T r e e                                           %
00661 %                                                                             %
00662 %                                                                             %
00663 %                                                                             %
00664 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00665 %
00666 %  DestroySplayTree() destroys the splay-tree.
00667 %
00668 %  The format of the DestroySplayTree method is:
00669 %
00670 %      SplayTreeInfo *DestroySplayTree(SplayTreeInfo *splay_tree)
00671 %
00672 %  A description of each parameter follows:
00673 %
00674 %    o splay_tree: the splay tree.
00675 %
00676 */
00677 MagickExport SplayTreeInfo *DestroySplayTree(SplayTreeInfo *splay_tree)
00678 {
00679   NodeInfo
00680     *node;
00681 
00682   register NodeInfo
00683     *active,
00684     *pend;
00685 
00686   LockSemaphoreInfo(splay_tree->semaphore);
00687   if (splay_tree->root != (NodeInfo *) NULL)
00688     {
00689       if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
00690           (splay_tree->root->value != (void *) NULL))
00691         splay_tree->root->value=splay_tree->relinquish_value(
00692           splay_tree->root->value);
00693       if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
00694           (splay_tree->root->key != (void *) NULL))
00695         splay_tree->root->key=splay_tree->relinquish_key(splay_tree->root->key);
00696       splay_tree->root->key=(void *) NULL;
00697       for (pend=splay_tree->root; pend != (NodeInfo *) NULL; )
00698       {
00699         active=pend;
00700         for (pend=(NodeInfo *) NULL; active != (NodeInfo *) NULL; )
00701         {
00702           if (active->left != (NodeInfo *) NULL)
00703             {
00704               if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
00705                   (active->left->value != (void *) NULL))
00706                 active->left->value=splay_tree->relinquish_value(
00707                   active->left->value);
00708               if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
00709                   (active->left->key != (void *) NULL))
00710                 active->left->key=splay_tree->relinquish_key(active->left->key);
00711               active->left->key=(void *) pend;
00712               pend=active->left;
00713             }
00714           if (active->right != (NodeInfo *) NULL)
00715             {
00716               if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
00717                   (active->right->value != (void *) NULL))
00718                 active->right->value=splay_tree->relinquish_value(
00719                   active->right->value);
00720               if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
00721                   (active->right->key != (void *) NULL))
00722                 active->right->key=splay_tree->relinquish_key(
00723                   active->right->key);
00724               active->right->key=(void *) pend;
00725               pend=active->right;
00726             }
00727           node=active;
00728           active=(NodeInfo *) node->key;
00729           node=(NodeInfo *) RelinquishMagickMemory(node);
00730         }
00731       }
00732     }
00733   splay_tree->signature=(~MagickSignature);
00734   UnlockSemaphoreInfo(splay_tree->semaphore);
00735   DestroySemaphoreInfo(&splay_tree->semaphore);
00736   splay_tree=(SplayTreeInfo *) RelinquishMagickMemory(splay_tree);
00737   return(splay_tree);
00738 }
00739 
00740 /*
00741 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00742 %                                                                             %
00743 %                                                                             %
00744 %                                                                             %
00745 %   G e t N e x t K e y I n S p l a y T r e e                                 %
00746 %                                                                             %
00747 %                                                                             %
00748 %                                                                             %
00749 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00750 %
00751 %  GetNextKeyInSplayTree() gets the next key in the splay-tree.
00752 %
00753 %  The format of the GetNextKeyInSplayTree method is:
00754 %
00755 %      const void *GetNextKeyInSplayTree(SplayTreeInfo *splay_tree)
00756 %
00757 %  A description of each parameter follows:
00758 %
00759 %    o splay_tree: the splay tree.
00760 %
00761 %    o key: the key.
00762 %
00763 */
00764 MagickExport const void *GetNextKeyInSplayTree(SplayTreeInfo *splay_tree)
00765 {
00766   register NodeInfo
00767     *node;
00768 
00769   void
00770     *key;
00771 
00772   assert(splay_tree != (SplayTreeInfo *) NULL);
00773   assert(splay_tree->signature == MagickSignature);
00774   if (splay_tree->debug != MagickFalse)
00775     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00776   if ((splay_tree->root == (NodeInfo *) NULL) ||
00777       (splay_tree->next == (void *) NULL))
00778     return((void *) NULL);
00779   LockSemaphoreInfo(splay_tree->semaphore);
00780   SplaySplayTree(splay_tree,splay_tree->next);
00781   splay_tree->next=(void *) NULL;
00782   node=splay_tree->root->right;
00783   if (node != (NodeInfo *) NULL)
00784     {
00785       while (node->left != (NodeInfo *) NULL)
00786         node=node->left;
00787       splay_tree->next=node->key;
00788     }
00789   key=splay_tree->root->key;
00790   UnlockSemaphoreInfo(splay_tree->semaphore);
00791   return(key);
00792 }
00793 
00794 /*
00795 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00796 %                                                                             %
00797 %                                                                             %
00798 %                                                                             %
00799 %   G e t N e x t V a l u e I n S p l a y T r e e                             %
00800 %                                                                             %
00801 %                                                                             %
00802 %                                                                             %
00803 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00804 %
00805 %  GetNextValueInSplayTree() gets the next value in the splay-tree.
00806 %
00807 %  The format of the GetNextValueInSplayTree method is:
00808 %
00809 %      const void *GetNextValueInSplayTree(SplayTreeInfo *splay_tree)
00810 %
00811 %  A description of each parameter follows:
00812 %
00813 %    o splay_tree: the splay tree.
00814 %
00815 %    o key: the key.
00816 %
00817 */
00818 MagickExport const void *GetNextValueInSplayTree(SplayTreeInfo *splay_tree)
00819 {
00820   register NodeInfo
00821     *node;
00822 
00823   void
00824     *value;
00825 
00826   assert(splay_tree != (SplayTreeInfo *) NULL);
00827   assert(splay_tree->signature == MagickSignature);
00828   if (splay_tree->debug != MagickFalse)
00829     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00830   if ((splay_tree->root == (NodeInfo *) NULL) ||
00831       (splay_tree->next == (void *) NULL))
00832     return((void *) NULL);
00833   LockSemaphoreInfo(splay_tree->semaphore);
00834   SplaySplayTree(splay_tree,splay_tree->next);
00835   splay_tree->next=(void *) NULL;
00836   node=splay_tree->root->right;
00837   if (node != (NodeInfo *) NULL)
00838     {
00839       while (node->left != (NodeInfo *) NULL)
00840         node=node->left;
00841       splay_tree->next=node->key;
00842     }
00843   value=splay_tree->root->value;
00844   UnlockSemaphoreInfo(splay_tree->semaphore);
00845   return(value);
00846 }
00847 
00848 /*
00849 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00850 %                                                                             %
00851 %                                                                             %
00852 %                                                                             %
00853 %   G e t V a l u e F r o m S p l a y T r e e                                 %
00854 %                                                                             %
00855 %                                                                             %
00856 %                                                                             %
00857 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00858 %
00859 %  GetValueFromSplayTree() gets a value from the splay-tree by its key.
00860 %
00861 %  Note, the value is a constant.  Do not attempt to free it.
00862 %
00863 %  The format of the GetValueFromSplayTree method is:
00864 %
00865 %      const void *GetValueFromSplayTree(SplayTreeInfo *splay_tree,
00866 %        const void *key)
00867 %
00868 %  A description of each parameter follows:
00869 %
00870 %    o splay_tree: the splay tree.
00871 %
00872 %    o key: the key.
00873 %
00874 */
00875 MagickExport const void *GetValueFromSplayTree(SplayTreeInfo *splay_tree,
00876   const void *key)
00877 {
00878   int
00879     compare;
00880 
00881   void
00882     *value;
00883 
00884   assert(splay_tree != (SplayTreeInfo *) NULL);
00885   assert(splay_tree->signature == MagickSignature);
00886   if (splay_tree->debug != MagickFalse)
00887     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00888   if (splay_tree->root == (NodeInfo *) NULL)
00889     return((void *) NULL);
00890   LockSemaphoreInfo(splay_tree->semaphore);
00891   SplaySplayTree(splay_tree,key);
00892   if (splay_tree->compare != (int (*)(const void *,const void *)) NULL)
00893     compare=splay_tree->compare(splay_tree->root->key,key);
00894   else
00895     compare=(splay_tree->root->key > key) ? 1 :
00896       ((splay_tree->root->key < key) ? -1 : 0);
00897   if (compare != 0)
00898     {
00899       UnlockSemaphoreInfo(splay_tree->semaphore);
00900       return((void *) NULL);
00901     }
00902   value=splay_tree->root->value;
00903   UnlockSemaphoreInfo(splay_tree->semaphore);
00904   return(value);
00905 }
00906 
00907 /*
00908 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00909 %                                                                             %
00910 %                                                                             %
00911 %                                                                             %
00912 %   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                     %
00913 %                                                                             %
00914 %                                                                             %
00915 %                                                                             %
00916 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00917 %
00918 %  GetNumberOfNodesInSplayTree() returns the number of nodes in the splay-tree.
00919 %
00920 %  The format of the GetNumberOfNodesInSplayTree method is:
00921 %
00922 %      size_t GetNumberOfNodesInSplayTree(
00923 %        const SplayTreeInfo *splay_tree)
00924 %
00925 %  A description of each parameter follows:
00926 %
00927 %    o splay_tree: the splay tree.
00928 %
00929 */
00930 MagickExport size_t GetNumberOfNodesInSplayTree(
00931   const SplayTreeInfo *splay_tree)
00932 {
00933   assert(splay_tree != (SplayTreeInfo *) NULL);
00934   assert(splay_tree->signature == MagickSignature);
00935   if (splay_tree->debug != MagickFalse)
00936     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00937   return(splay_tree->nodes);
00938 }
00939 
00940 /*
00941 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00942 %                                                                             %
00943 %                                                                             %
00944 %                                                                             %
00945 %   I t e r a t e O v e r S p l a y T r e e                                   %
00946 %                                                                             %
00947 %                                                                             %
00948 %                                                                             %
00949 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00950 %
00951 %  IterateOverSplayTree() iterates over the splay-tree.
00952 %
00953 %  The format of the IterateOverSplayTree method is:
00954 %
00955 %      int IterateOverSplayTree(SplayTreeInfo *splay_tree,
00956 %        int (*method)(NodeInfo *,void *),const void *value)
00957 %
00958 %  A description of each parameter follows:
00959 %
00960 %    o splay_tree: the splay-tree info.
00961 %
00962 %    o method: the method.
00963 %
00964 %    o value: the value.
00965 %
00966 */
00967 static int IterateOverSplayTree(SplayTreeInfo *splay_tree,
00968   int (*method)(NodeInfo *,const void *),const void *value)
00969 {
00970   typedef enum
00971   {
00972     LeftTransition,
00973     RightTransition,
00974     DownTransition,
00975     UpTransition
00976   } TransitionType;
00977 
00978   int
00979     status;
00980 
00981   MagickBooleanType
00982     final_transition;
00983 
00984   NodeInfo
00985     **nodes;
00986 
00987   register ssize_t
00988     i;
00989 
00990   register NodeInfo
00991     *node;
00992 
00993   TransitionType
00994     transition;
00995 
00996   unsigned char
00997     *transitions;
00998 
00999   if (splay_tree->root == (NodeInfo *) NULL)
01000     return(0);
01001   nodes=(NodeInfo **) AcquireQuantumMemory((size_t) splay_tree->nodes,
01002     sizeof(*nodes));
01003   transitions=(unsigned char *) AcquireQuantumMemory((size_t) splay_tree->nodes,
01004     sizeof(*transitions));
01005   if ((nodes == (NodeInfo **) NULL) || (transitions == (unsigned char *) NULL))
01006     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
01007   status=0;
01008   final_transition=MagickFalse;
01009   nodes[0]=splay_tree->root;
01010   transitions[0]=(unsigned char) LeftTransition;
01011   for (i=0; final_transition == MagickFalse; )
01012   {
01013     node=nodes[i];
01014     transition=(TransitionType) transitions[i];
01015     switch (transition)
01016     {
01017       case LeftTransition:
01018       {
01019         transitions[i]=(unsigned char) DownTransition;
01020         if (node->left == (NodeInfo *) NULL)
01021           break;
01022         i++;
01023         nodes[i]=node->left;
01024         transitions[i]=(unsigned char) LeftTransition;
01025         break;
01026       }
01027       case RightTransition:
01028       {
01029         transitions[i]=(unsigned char) UpTransition;
01030         if (node->right == (NodeInfo *) NULL)
01031           break;
01032         i++;
01033         nodes[i]=node->right;
01034         transitions[i]=(unsigned char) LeftTransition;
01035         break;
01036       }
01037       case DownTransition:
01038       default:
01039       {
01040         transitions[i]=(unsigned char) RightTransition;
01041         status=(*method)(node,value);
01042         if (status != 0)
01043           final_transition=MagickTrue;
01044         break;
01045       }
01046       case UpTransition:
01047       {
01048         if (i == 0)
01049           {
01050             final_transition=MagickTrue;
01051             break;
01052           }
01053         i--;
01054         break;
01055       }
01056     }
01057   }
01058   nodes=(NodeInfo **) RelinquishMagickMemory(nodes);
01059   transitions=(unsigned char *) RelinquishMagickMemory(transitions);
01060   return(status);
01061 }
01062 
01063 /*
01064 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01065 %                                                                             %
01066 %                                                                             %
01067 %                                                                             %
01068 %   N e w S p l a y T r e e                                                   %
01069 %                                                                             %
01070 %                                                                             %
01071 %                                                                             %
01072 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01073 %
01074 %  NewSplayTree() returns a pointer to a SplayTreeInfo structure initialized
01075 %  to default values.
01076 %
01077 %  The format of the NewSplayTree method is:
01078 %
01079 %      SplayTreeInfo *NewSplayTree(int (*compare)(const void *,const void *),
01080 %        void *(*relinquish_key)(void *),void *(*relinquish_value)(void *))
01081 %
01082 %  A description of each parameter follows:
01083 %
01084 %    o compare: the compare method.
01085 %
01086 %    o relinquish_key: the key deallocation method, typically
01087 %      RelinquishMagickMemory(), called whenever a key is removed from the
01088 %      splay-tree.
01089 %
01090 %    o relinquish_value: the value deallocation method;  typically
01091 %      RelinquishMagickMemory(), called whenever a value object is removed from
01092 %      the splay-tree.
01093 %
01094 */
01095 MagickExport SplayTreeInfo *NewSplayTree(
01096   int (*compare)(const void *,const void *),void *(*relinquish_key)(void *),
01097   void *(*relinquish_value)(void *))
01098 {
01099   SplayTreeInfo
01100     *splay_tree;
01101 
01102   splay_tree=(SplayTreeInfo *) AcquireMagickMemory(sizeof(*splay_tree));
01103   if (splay_tree == (SplayTreeInfo *) NULL)
01104     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
01105   (void) ResetMagickMemory(splay_tree,0,sizeof(*splay_tree));
01106   splay_tree->root=(NodeInfo *) NULL;
01107   splay_tree->compare=compare;
01108   splay_tree->relinquish_key=relinquish_key;
01109   splay_tree->relinquish_value=relinquish_value;
01110   splay_tree->balance=MagickFalse;
01111   splay_tree->key=(void *) NULL;
01112   splay_tree->next=(void *) NULL;
01113   splay_tree->nodes=0;
01114   splay_tree->debug=IsEventLogging();
01115   splay_tree->semaphore=AllocateSemaphoreInfo();
01116   splay_tree->signature=MagickSignature;
01117   return(splay_tree);
01118 }
01119 
01120 /*
01121 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01122 %                                                                             %
01123 %                                                                             %
01124 %                                                                             %
01125 %   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               %
01126 %                                                                             %
01127 %                                                                             %
01128 %                                                                             %
01129 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01130 %
01131 %  RemoveNodeByValueFromSplayTree() removes a node by value from the splay-tree
01132 %  and returns its key.
01133 %
01134 %  The format of the RemoveNodeByValueFromSplayTree method is:
01135 %
01136 %      void *RemoveNodeByValueFromSplayTree(SplayTreeInfo *splay_tree,
01137 %        const void *value)
01138 %
01139 %  A description of each parameter follows:
01140 %
01141 %    o splay_tree: the splay-tree info.
01142 %
01143 %    o value: the value.
01144 %
01145 */
01146 MagickExport void *RemoveNodeByValueFromSplayTree(SplayTreeInfo *splay_tree,
01147   const void *value)
01148 {
01149   register NodeInfo
01150     *next,
01151     *node;
01152 
01153   void
01154     *key;
01155 
01156   assert(splay_tree != (SplayTreeInfo *) NULL);
01157   assert(splay_tree->signature == MagickSignature);
01158   if (splay_tree->debug != MagickFalse)
01159     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
01160   key=(void *) NULL;
01161   if (splay_tree->root == (NodeInfo *) NULL)
01162     return(key);
01163   LockSemaphoreInfo(splay_tree->semaphore);
01164   next=(NodeInfo *) GetFirstSplayTreeNode(splay_tree);
01165   while (next != (NodeInfo *) NULL)
01166   {
01167     SplaySplayTree(splay_tree,next);
01168     next=(NodeInfo *) NULL;
01169     node=splay_tree->root->right;
01170     if (node != (NodeInfo *) NULL)
01171       {
01172         while (node->left != (NodeInfo *) NULL)
01173           node=node->left;
01174         next=(NodeInfo *) node->key;
01175       }
01176     if (splay_tree->root->value == value)
01177       {
01178         int
01179           compare;
01180 
01181         register NodeInfo
01182           *left,
01183           *right;
01184 
01185         /*
01186           We found the node that matches the value; now remove it.
01187         */
01188         key=splay_tree->root->key;
01189         SplaySplayTree(splay_tree,key);
01190         splay_tree->key=(void *) NULL;
01191         if (splay_tree->compare != (int (*)(const void *,const void *)) NULL)
01192           compare=splay_tree->compare(splay_tree->root->key,key);
01193         else
01194           compare=(splay_tree->root->key > key) ? 1 :
01195             ((splay_tree->root->key < key) ? -1 : 0);
01196         if (compare != 0)
01197           {
01198             UnlockSemaphoreInfo(splay_tree->semaphore);
01199             return(key);
01200           }
01201         left=splay_tree->root->left;
01202         right=splay_tree->root->right;
01203         if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
01204             (splay_tree->root->value != (void *) NULL))
01205           splay_tree->root->value=splay_tree->relinquish_value(
01206             splay_tree->root->value);
01207         splay_tree->root=(NodeInfo *) RelinquishMagickMemory(splay_tree->root);
01208         splay_tree->nodes--;
01209         if (left == (NodeInfo *) NULL)
01210           {
01211             splay_tree->root=right;
01212             UnlockSemaphoreInfo(splay_tree->semaphore);
01213             return(key);
01214           }
01215         splay_tree->root=left;
01216         if (right != (NodeInfo *) NULL)
01217           {
01218             while (left->right != (NodeInfo *) NULL)
01219               left=left->right;
01220             left->right=right;
01221           }
01222         UnlockSemaphoreInfo(splay_tree->semaphore);
01223         return(key);
01224       }
01225   }
01226   UnlockSemaphoreInfo(splay_tree->semaphore);
01227   return(key);
01228 }
01229 
01230 /*
01231 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01232 %                                                                             %
01233 %                                                                             %
01234 %                                                                             %
01235 %   R e m o v e N o d e F r o m S p l a y T r e e                             %
01236 %                                                                             %
01237 %                                                                             %
01238 %                                                                             %
01239 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01240 %
01241 %  RemoveNodeFromSplayTree() removes a node from the splay-tree and returns its
01242 %  value.
01243 %
01244 %  The format of the RemoveNodeFromSplayTree method is:
01245 %
01246 %      void *RemoveNodeFromSplayTree(SplayTreeInfo *splay_tree,const void *key)
01247 %
01248 %  A description of each parameter follows:
01249 %
01250 %    o splay_tree: the splay-tree info.
01251 %
01252 %    o key: the key.
01253 %
01254 */
01255 MagickExport void *RemoveNodeFromSplayTree(SplayTreeInfo *splay_tree,
01256   const void *key)
01257 {
01258   int
01259     compare;
01260 
01261   register NodeInfo
01262     *left,
01263     *right;
01264 
01265   void
01266     *value;
01267 
01268   assert(splay_tree != (SplayTreeInfo *) NULL);
01269   assert(splay_tree->signature == MagickSignature);
01270   if (splay_tree->debug != MagickFalse)
01271     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
01272   value=(void *) NULL;
01273   if (splay_tree->root == (NodeInfo *) NULL)
01274     return(value);
01275   LockSemaphoreInfo(splay_tree->semaphore);
01276   SplaySplayTree(splay_tree,key);
01277   splay_tree->key=(void *) NULL;
01278   if (splay_tree->compare != (int (*)(const void *,const void *)) NULL)
01279     compare=splay_tree->compare(splay_tree->root->key,key);
01280   else
01281     compare=(splay_tree->root->key > key) ? 1 :
01282       ((splay_tree->root->key < key) ? -1 : 0);
01283   if (compare != 0)
01284     {
01285       UnlockSemaphoreInfo(splay_tree->semaphore);
01286       return(value);
01287     }
01288   left=splay_tree->root->left;
01289   right=splay_tree->root->right;
01290   value=splay_tree->root->value;
01291   if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
01292       (splay_tree->root->key != (void *) NULL))
01293     splay_tree->root->key=splay_tree->relinquish_key(splay_tree->root->key);
01294   splay_tree->root=(NodeInfo *) RelinquishMagickMemory(splay_tree->root);
01295   splay_tree->nodes--;
01296   if (left == (NodeInfo *) NULL)
01297     {
01298       splay_tree->root=right;
01299       UnlockSemaphoreInfo(splay_tree->semaphore);
01300       return(value);
01301     }
01302   splay_tree->root=left;
01303   if (right != (NodeInfo *) NULL)
01304     {
01305       while (left->right != (NodeInfo *) NULL)
01306         left=left->right;
01307       left->right=right;
01308     }
01309   UnlockSemaphoreInfo(splay_tree->semaphore);
01310   return(value);
01311 }
01312 
01313 /*
01314 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01315 %                                                                             %
01316 %                                                                             %
01317 %                                                                             %
01318 %   R e s e t S p l a y T r e e                                               %
01319 %                                                                             %
01320 %                                                                             %
01321 %                                                                             %
01322 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01323 %
01324 %  ResetSplayTree() resets the splay-tree.  That is, it deletes all the nodes
01325 %  from the tree.
01326 %
01327 %  The format of the ResetSplayTree method is:
01328 %
01329 %      ResetSplayTree(SplayTreeInfo *splay_tree)
01330 %
01331 %  A description of each parameter follows:
01332 %
01333 %    o splay_tree: the splay tree.
01334 %
01335 */
01336 MagickExport void ResetSplayTree(SplayTreeInfo *splay_tree)
01337 {
01338   NodeInfo
01339     *node;
01340 
01341   register NodeInfo
01342     *active,
01343     *pend;
01344 
01345   assert(splay_tree != (SplayTreeInfo *) NULL);
01346   assert(splay_tree->signature == MagickSignature);
01347   if (splay_tree->debug != MagickFalse)
01348     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
01349   LockSemaphoreInfo(splay_tree->semaphore);
01350   if (splay_tree->root != (NodeInfo *) NULL)
01351     {
01352       if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
01353           (splay_tree->root->value != (void *) NULL))
01354         splay_tree->root->value=splay_tree->relinquish_value(
01355           splay_tree->root->value);
01356       if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
01357           (splay_tree->root->key != (void *) NULL))
01358         splay_tree->root->key=splay_tree->relinquish_key(splay_tree->root->key);
01359       splay_tree->root->key=(void *) NULL;
01360       for (pend=splay_tree->root; pend != (NodeInfo *) NULL; )
01361       {
01362         active=pend;
01363         for (pend=(NodeInfo *) NULL; active != (NodeInfo *) NULL; )
01364         {
01365           if (active->left != (NodeInfo *) NULL)
01366             {
01367               if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
01368                   (active->left->value != (void *) NULL))
01369                 active->left->value=splay_tree->relinquish_value(
01370                   active->left->value);
01371               if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
01372                   (active->left->key != (void *) NULL))
01373                 active->left->key=splay_tree->relinquish_key(active->left->key);
01374               active->left->key=(void *) pend;
01375               pend=active->left;
01376             }
01377           if (active->right != (NodeInfo *) NULL)
01378             {
01379               if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
01380                   (active->right->value != (void *) NULL))
01381                 active->right->value=splay_tree->relinquish_value(
01382                   active->right->value);
01383               if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
01384                   (active->right->key != (void *) NULL))
01385                 active->right->key=splay_tree->relinquish_key(
01386                   active->right->key);
01387               active->right->key=(void *) pend;
01388               pend=active->right;
01389             }
01390           node=active;
01391           active=(NodeInfo *) node->key;
01392           node=(NodeInfo *) RelinquishMagickMemory(node);
01393         }
01394       }
01395     }
01396   splay_tree->root=(NodeInfo *) NULL;
01397   splay_tree->key=(void *) NULL;
01398   splay_tree->next=(void *) NULL;
01399   splay_tree->nodes=0;
01400   splay_tree->balance=MagickFalse;
01401   UnlockSemaphoreInfo(splay_tree->semaphore);
01402 }
01403 
01404 /*
01405 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01406 %                                                                             %
01407 %                                                                             %
01408 %                                                                             %
01409 %   R e s e t S p l a y T r e e I t e r a t o r                               %
01410 %                                                                             %
01411 %                                                                             %
01412 %                                                                             %
01413 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01414 %
01415 %  ResetSplayTreeIterator() resets the splay-tree iterator.  Use it in
01416 %  conjunction with GetNextValueInSplayTree() to iterate over all the nodes in
01417 %  the splay-tree.
01418 %
01419 %  The format of the ResetSplayTreeIterator method is:
01420 %
01421 %      ResetSplayTreeIterator(SplayTreeInfo *splay_tree)
01422 %
01423 %  A description of each parameter follows:
01424 %
01425 %    o splay_tree: the splay tree.
01426 %
01427 */
01428 MagickExport void ResetSplayTreeIterator(SplayTreeInfo *splay_tree)
01429 {
01430   assert(splay_tree != (SplayTreeInfo *) NULL);
01431   assert(splay_tree->signature == MagickSignature);
01432   if (splay_tree->debug != MagickFalse)
01433     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
01434   LockSemaphoreInfo(splay_tree->semaphore);
01435   splay_tree->next=GetFirstSplayTreeNode(splay_tree);
01436   UnlockSemaphoreInfo(splay_tree->semaphore);
01437 }
01438 
01439 /*
01440 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01441 %                                                                             %
01442 %                                                                             %
01443 %                                                                             %
01444 %   S p l a y S p l a y T r e e                                               %
01445 %                                                                             %
01446 %                                                                             %
01447 %                                                                             %
01448 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01449 %
01450 %  SplaySplayTree() splays the splay-tree.
01451 %
01452 %  The format of the SplaySplayTree method is:
01453 %
01454 %      void SplaySplayTree(SplayTreeInfo *splay_tree,const void *key,
01455 %        NodeInfo **node,NodeInfo **parent,NodeInfo **grandparent)
01456 %
01457 %  A description of each parameter follows:
01458 %
01459 %    o splay_tree: the splay-tree info.
01460 %
01461 %    o key: the key.
01462 %
01463 %    o node: the node.
01464 %
01465 %    o parent: the parent node.
01466 %
01467 %    o grandparent: the grandparent node.
01468 %
01469 */
01470 
01471 static NodeInfo *Splay(SplayTreeInfo *splay_tree,const size_t depth,
01472   const void *key,NodeInfo **node,NodeInfo **parent,NodeInfo **grandparent)
01473 {
01474   int
01475     compare;
01476 
01477   NodeInfo
01478     **next;
01479 
01480   register NodeInfo
01481     *n,
01482     *p;
01483 
01484   n=(*node);
01485   if (n == (NodeInfo *) NULL)
01486     return(*parent);
01487   if (splay_tree->compare != (int (*)(const void *,const void *)) NULL)
01488     compare=splay_tree->compare(n->key,key);
01489   else
01490     compare=(n->key > key) ? 1 : ((n->key < key) ? -1 : 0);
01491   next=(NodeInfo **) NULL;
01492   if (compare > 0)
01493     next=(&n->left);
01494   else
01495     if (compare < 0)
01496       next=(&n->right);
01497   if (next != (NodeInfo **) NULL)
01498     {
01499       if (depth >= MaxSplayTreeDepth)
01500         {
01501           splay_tree->balance=MagickTrue;
01502           return(n);
01503         }
01504       n=Splay(splay_tree,depth+1,key,next,node,parent);
01505       if ((n != *node) || (splay_tree->balance != MagickFalse))
01506         return(n);
01507     }
01508   if (parent == (NodeInfo **) NULL)
01509     return(n);
01510   if (grandparent == (NodeInfo **) NULL)
01511     {
01512       if (n == (*parent)->left)
01513         {
01514           *node=n->right;
01515           n->right=(*parent);
01516         }
01517       else
01518         {
01519           *node=n->left;
01520           n->left=(*parent);
01521         }
01522       *parent=n;
01523       return(n);
01524     }
01525   if ((n == (*parent)->left) && (*parent == (*grandparent)->left))
01526     {
01527       p=(*parent);
01528       (*grandparent)->left=p->right;
01529       p->right=(*grandparent);
01530       p->left=n->right;
01531       n->right=p;
01532       *grandparent=n;
01533       return(n);
01534     }
01535   if ((n == (*parent)->right) && (*parent == (*grandparent)->right))
01536     {
01537       p=(*parent);
01538       (*grandparent)->right=p->left;
01539       p->left=(*grandparent);
01540       p->right=n->left;
01541       n->left=p;
01542       *grandparent=n;
01543       return(n);
01544     }
01545   if (n == (*parent)->left)
01546     {
01547       (*parent)->left=n->right;
01548       n->right=(*parent);
01549       (*grandparent)->right=n->left;
01550       n->left=(*grandparent);
01551       *grandparent=n;
01552       return(n);
01553     }
01554   (*parent)->right=n->left;
01555   n->left=(*parent);
01556   (*grandparent)->left=n->right;
01557   n->right=(*grandparent);
01558   *grandparent=n;
01559   return(n);
01560 }
01561 
01562 static void SplaySplayTree(SplayTreeInfo *splay_tree,const void *key)
01563 {
01564   if (splay_tree->root == (NodeInfo *) NULL)
01565     return;
01566   if (splay_tree->key != (void *) NULL)
01567     {
01568       int
01569         compare;
01570 
01571       if (splay_tree->compare != (int (*)(const void *,const void *)) NULL)
01572         compare=splay_tree->compare(splay_tree->root->key,key);
01573       else
01574         compare=(splay_tree->key > key) ? 1 :
01575           ((splay_tree->key < key) ? -1 : 0);
01576       if (compare == 0)
01577         return;
01578     }
01579   (void) Splay(splay_tree,0UL,key,&splay_tree->root,(NodeInfo **) NULL,
01580     (NodeInfo **) NULL);
01581   if (splay_tree->balance != MagickFalse)
01582     {
01583       BalanceSplayTree(splay_tree);
01584       (void) Splay(splay_tree,0UL,key,&splay_tree->root,(NodeInfo **) NULL,
01585         (NodeInfo **) NULL);
01586       if (splay_tree->balance != MagickFalse)
01587         ThrowFatalException(ResourceLimitFatalError,
01588           "MemoryAllocationFailed");
01589     }
01590   splay_tree->key=(void *) key;
01591 }