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-2008 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 "magick/studio.h"
00052 #include "magick/exception.h"
00053 #include "magick/exception-private.h"
00054 #include "magick/log.h"
00055 #include "magick/memory_.h"
00056 #include "magick/splay-tree.h"
00057 #include "magick/semaphore.h"
00058 #include "magick/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   unsigned long
00101     nodes;
00102 
00103   MagickBooleanType
00104     debug;
00105 
00106   SemaphoreInfo
00107     *semaphore;
00108 
00109   unsigned long
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 a value to the splay-tree.
00135 %
00136 %  The format of the AddValueToSplayTree method is:
00137 %
00138 %      MagickBooleanType AddValueToSplayTree(SplayTreeInfo *splay_tree,
00139 %        const void *key,const void *value)
00140 %
00141 %  A description of each parameter follows:
00142 %
00143 %    o splay_tree: the splay-tree info.
00144 %
00145 %    o key: the key.
00146 %
00147 %    o value: the value.
00148 %
00149 */
00150 MagickExport MagickBooleanType AddValueToSplayTree(SplayTreeInfo *splay_tree,
00151   const void *key,const void *value)
00152 {
00153   int
00154     compare;
00155 
00156   register NodeInfo
00157     *node;
00158 
00159   (void) LockSemaphoreInfo(splay_tree->semaphore);
00160   SplaySplayTree(splay_tree,key);
00161   compare=0;
00162   if (splay_tree->root != (NodeInfo *) NULL)
00163     {
00164       if (splay_tree->compare != (int (*)(const void *,const void *)) NULL)
00165         compare=splay_tree->compare(splay_tree->root->key,key);
00166       else
00167         compare=(splay_tree->root->key > key) ? 1 :
00168           ((splay_tree->root->key < key) ? -1 : 0);
00169       if (compare == 0)
00170         {
00171           if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
00172               (splay_tree->root->key != (void *) NULL))
00173             splay_tree->root->key=splay_tree->relinquish_key(
00174               splay_tree->root->key);
00175           splay_tree->root->key=(void *) key;
00176           if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
00177               (splay_tree->root->value != (void *) NULL))
00178             splay_tree->root->value=splay_tree->relinquish_value(
00179               splay_tree->root->value);
00180           splay_tree->root->value=(void *) value;
00181           (void) UnlockSemaphoreInfo(splay_tree->semaphore);
00182           return(MagickTrue);
00183         }
00184     }
00185   node=(NodeInfo *) AcquireMagickMemory(sizeof(*node));
00186   if (node == (NodeInfo *) NULL)
00187     {
00188       (void) UnlockSemaphoreInfo(splay_tree->semaphore);
00189       return(MagickFalse);
00190     }
00191   node->key=(void *) key;
00192   node->value=(void *) value;
00193   if (splay_tree->root == (NodeInfo *) NULL)
00194     {
00195       node->left=(NodeInfo *) NULL;
00196       node->right=(NodeInfo *) NULL;
00197     }
00198   else
00199     if (compare < 0)
00200       {
00201         node->left=splay_tree->root;
00202         node->right=node->left->right;
00203         node->left->right=(NodeInfo *) NULL;
00204       }
00205     else
00206       {
00207         node->right=splay_tree->root;
00208         node->left=node->right->left;
00209         node->right->left=(NodeInfo *) NULL;
00210       }
00211   splay_tree->root=node;
00212   splay_tree->key=(void *) NULL;
00213   splay_tree->nodes++;
00214   (void) UnlockSemaphoreInfo(splay_tree->semaphore);
00215   return(MagickTrue);
00216 }
00217 
00218 /*
00219 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00220 %                                                                             %
00221 %                                                                             %
00222 %                                                                             %
00223 %   B a l a n c e S p l a y T r e e                                           %
00224 %                                                                             %
00225 %                                                                             %
00226 %                                                                             %
00227 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00228 %
00229 %  BalanceSplayTree() balances the splay-tree.
00230 %
00231 %  The format of the BalanceSplayTree method is:
00232 %
00233 %      void *BalanceSplayTree(SplayTreeInfo *splay_tree,const void *key)
00234 %
00235 %  A description of each parameter follows:
00236 %
00237 %    o splay_tree: the splay-tree info.
00238 %
00239 %    o key: the key.
00240 %
00241 */
00242 
00243 static NodeInfo *LinkSplayTreeNodes(NodeInfo **nodes,const unsigned long low,
00244   const unsigned long high)
00245 {
00246   register NodeInfo
00247     *node;
00248 
00249   unsigned long
00250     bisect;
00251 
00252   bisect=low+(high-low)/2;
00253   node=nodes[bisect];
00254   if ((low+1) > bisect)
00255     node->left=(NodeInfo *) NULL;
00256   else
00257     node->left=LinkSplayTreeNodes(nodes,low,bisect-1);
00258   if ((bisect+1) > high)
00259     node->right=(NodeInfo *) NULL;
00260   else
00261     node->right=LinkSplayTreeNodes(nodes,bisect+1,high);
00262   return(node);
00263 }
00264 
00265 static int SplayTreeToNodeArray(NodeInfo *node,const void *nodes)
00266 {
00267   register const NodeInfo
00268     ***p;
00269 
00270   p=(const NodeInfo ***) nodes;
00271   *(*p)=node;
00272   (*p)++;
00273   return(0);
00274 }
00275 
00276 static void BalanceSplayTree(SplayTreeInfo *splay_tree)
00277 {
00278   NodeInfo
00279     **node,
00280     **nodes;
00281 
00282   if (splay_tree->nodes <= 2)
00283     {
00284       splay_tree->balance=MagickFalse;
00285       return;
00286     }
00287   nodes=(NodeInfo **) AcquireQuantumMemory((size_t) splay_tree->nodes,
00288     sizeof(*nodes));
00289   if (nodes == (NodeInfo **) NULL)
00290     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
00291   node=nodes;
00292   (void) IterateOverSplayTree(splay_tree,SplayTreeToNodeArray,
00293     (const void *) &node);
00294   splay_tree->root=LinkSplayTreeNodes(nodes,0,splay_tree->nodes-1);
00295   splay_tree->balance=MagickFalse;
00296   nodes=(NodeInfo **) RelinquishMagickMemory(nodes);
00297 }
00298 
00299 /*
00300 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00301 %                                                                             %
00302 %                                                                             %
00303 %                                                                             %
00304 %   C l o n e S p l a y T r e e                                               %
00305 %                                                                             %
00306 %                                                                             %
00307 %                                                                             %
00308 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00309 %
00310 %  CloneSplayTree() clones the splay tree.
00311 %
00312 %  The format of the CloneSplayTree method is:
00313 %
00314 %      SplayTreeInfo *CloneSplayTree(SplayTreeInfo *splay_tree,
00315 %        void *(*clone_key)(void *),void *(*cline_value)(void *))
00316 %
00317 %  A description of each parameter follows:
00318 %
00319 %    o splay_tree: the splay tree.
00320 %
00321 %    o clone_key: the key clone method, typically ConstantString(), called
00322 %      whenever a key is added to the splay-tree.
00323 %
00324 %    o clone_value: the value clone method;  typically ConstantString(), called
00325 %      whenever a value object is added to the splay-tree.
00326 %
00327 */
00328 MagickExport SplayTreeInfo *CloneSplayTree(SplayTreeInfo *splay_tree,
00329   void *(*clone_key)(void *),void *(*clone_value)(void *))
00330 {
00331   SplayTreeInfo
00332     *clone_tree;
00333 
00334   assert(splay_tree != (SplayTreeInfo *) NULL);
00335   assert(splay_tree->signature == MagickSignature);
00336   if (splay_tree->debug != MagickFalse)
00337     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00338   clone_tree=NewSplayTree(splay_tree->compare,splay_tree->relinquish_key,
00339     splay_tree->relinquish_value);
00340   (void) LockSemaphoreInfo(splay_tree->semaphore);
00341   if (splay_tree->root != (NodeInfo *) NULL)
00342     {
00343       register NodeInfo
00344         *active,
00345         *next,
00346         *node;
00347 
00348       void
00349         *key,
00350         *value;
00351 
00352       key=splay_tree->root->key;
00353       if ((clone_key != (void *(*)(void *)) NULL) && (key != (void *) NULL))
00354         key=clone_key(key);
00355       value=splay_tree->root->value;
00356       if ((clone_value != (void *(*)(void *)) NULL) && (value != (void *) NULL))
00357         value=clone_value(value);
00358       (void) AddValueToSplayTree(clone_tree,key,value);
00359       for (node=splay_tree->root; node != (NodeInfo *) NULL; )
00360       {
00361         active=node;
00362         for (node=(NodeInfo *) NULL; active != (NodeInfo *) NULL; )
00363         {
00364           next=(NodeInfo *) NULL;
00365           if (active->left != (NodeInfo *) NULL)
00366             {
00367               next=node;
00368               key=active->left->key;
00369               if ((clone_key != (void *(*)(void *)) NULL) &&
00370                   (key != (void *) NULL))
00371                 key=clone_key(key);
00372               value=active->left->value;
00373               if ((clone_value != (void *(*)(void *)) NULL) &&
00374                   (value != (void *) NULL))
00375                 value=clone_value(value);
00376               (void) AddValueToSplayTree(clone_tree,key,value);
00377               node=active->left;
00378             }
00379           if (active->right != (NodeInfo *) NULL)
00380             {
00381               next=node;
00382               key=active->right->key;
00383               if ((clone_key != (void *(*)(void *)) NULL) &&
00384                   (key != (void *) NULL))
00385                 key=clone_key(key);
00386               value=active->right->value;
00387               if ((clone_value != (void *(*)(void *)) NULL) &&
00388                   (value != (void *) NULL))
00389                 value=clone_value(value);
00390               (void) AddValueToSplayTree(clone_tree,key,value);
00391               node=active->right;
00392             }
00393           active=next;
00394         }
00395       }
00396     }
00397   (void) UnlockSemaphoreInfo(splay_tree->semaphore);
00398   return(clone_tree);
00399 }
00400 
00401 /*
00402 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00403 %                                                                             %
00404 %                                                                             %
00405 %                                                                             %
00406 %   C o m p a r e S p l a y T r e e S t r i n g                               %
00407 %                                                                             %
00408 %                                                                             %
00409 %                                                                             %
00410 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00411 %
00412 %  CompareSplayTreeString() method finds a node in a splay-tree based on the
00413 %  contents of a string.
00414 %
00415 %  The format of the CompareSplayTreeString method is:
00416 %
00417 %      int CompareSplayTreeString(const void *target,const void *source)
00418 %
00419 %  A description of each parameter follows:
00420 %
00421 %    o target: the target string.
00422 %
00423 %    o source: the source string.
00424 %
00425 */
00426 MagickExport int CompareSplayTreeString(const void *target,const void *source)
00427 {
00428   const char
00429     *p,
00430     *q;
00431 
00432   p=(const char *) target;
00433   q=(const char *) source;
00434   return(LocaleCompare(p,q));
00435 }
00436 
00437 /*
00438 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00439 %                                                                             %
00440 %                                                                             %
00441 %                                                                             %
00442 %   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                       %
00443 %                                                                             %
00444 %                                                                             %
00445 %                                                                             %
00446 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00447 %
00448 %  CompareSplayTreeStringInfo() finds a node in a splay-tree based on the
00449 %  contents of a string.
00450 %
00451 %  The format of the CompareSplayTreeStringInfo method is:
00452 %
00453 %      int CompareSplayTreeStringInfo(const void *target,const void *source)
00454 %
00455 %  A description of each parameter follows:
00456 %
00457 %    o target: the target string.
00458 %
00459 %    o source: the source string.
00460 %
00461 */
00462 MagickExport int CompareSplayTreeStringInfo(const void *target,
00463   const void *source)
00464 {
00465   const StringInfo
00466     *p,
00467     *q;
00468 
00469   p=(const StringInfo *) target;
00470   q=(const StringInfo *) source;
00471   return(CompareStringInfo(p,q));
00472 }
00473 
00474 /*
00475 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00476 %                                                                             %
00477 %                                                                             %
00478 %                                                                             %
00479 %   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               %
00480 %                                                                             %
00481 %                                                                             %
00482 %                                                                             %
00483 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00484 %
00485 %  DeleteNodeByValueFromSplayTree() deletes a node by value from the
00486 %  splay-tree.
00487 %
00488 %  The format of the DeleteNodeByValueFromSplayTree method is:
00489 %
00490 %      MagickBooleanType DeleteNodeByValueFromSplayTree(
00491 %        SplayTreeInfo *splay_tree,const void *value)
00492 %
00493 %  A description of each parameter follows:
00494 %
00495 %    o splay_tree: the splay-tree info.
00496 %
00497 %    o value: the value.
00498 %
00499 */
00500 
00501 static void *GetFirstSplayTreeNode(SplayTreeInfo *splay_tree)
00502 {
00503   register NodeInfo
00504     *node;
00505 
00506   node=splay_tree->root;
00507   if (splay_tree->root == (NodeInfo *) NULL)
00508     return((NodeInfo *) NULL);
00509   while (node->left != (NodeInfo *) NULL)
00510     node=node->left;
00511   return(node->key);
00512 }
00513 
00514 MagickExport MagickBooleanType DeleteNodeByValueFromSplayTree(
00515   SplayTreeInfo *splay_tree,const void *value)
00516 {
00517   register NodeInfo
00518     *next,
00519     *node;
00520 
00521   assert(splay_tree != (SplayTreeInfo *) NULL);
00522   assert(splay_tree->signature == MagickSignature);
00523   if (splay_tree->debug != MagickFalse)
00524     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00525   if (splay_tree->root == (NodeInfo *) NULL)
00526     return(MagickFalse);
00527   (void) LockSemaphoreInfo(splay_tree->semaphore);
00528   next=(NodeInfo *) GetFirstSplayTreeNode(splay_tree);
00529   while (next != (NodeInfo *) NULL)
00530   {
00531     SplaySplayTree(splay_tree,next);
00532     next=(NodeInfo *) NULL;
00533     node=splay_tree->root->right;
00534     if (node != (NodeInfo *) NULL)
00535       {
00536         while (node->left != (NodeInfo *) NULL)
00537           node=node->left;
00538         next=(NodeInfo *) node->key;
00539       }
00540     if (splay_tree->root->value == value)
00541       {
00542         int
00543           compare;
00544 
00545         register NodeInfo
00546           *left,
00547           *right;
00548 
00549         void
00550           *key;
00551 
00552         /*
00553           We found the node that matches the value; now delete it.
00554         */
00555         key=splay_tree->root->key;
00556         SplaySplayTree(splay_tree,key);
00557         splay_tree->key=(void *) NULL;
00558         if (splay_tree->compare != (int (*)(const void *,const void *)) NULL)
00559           compare=splay_tree->compare(splay_tree->root->key,key);
00560         else
00561           compare=(splay_tree->root->key > key) ? 1 :
00562             ((splay_tree->root->key < key) ? -1 : 0);
00563         if (compare != 0)
00564           {
00565             (void) UnlockSemaphoreInfo(splay_tree->semaphore);
00566             return(MagickFalse);
00567           }
00568         left=splay_tree->root->left;
00569         right=splay_tree->root->right;
00570         if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
00571             (splay_tree->root->key != (void *) NULL))
00572           splay_tree->root->key=splay_tree->relinquish_key(
00573             splay_tree->root->key);
00574         if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
00575             (splay_tree->root->value != (void *) NULL))
00576           splay_tree->root->value=splay_tree->relinquish_value(
00577             splay_tree->root->value);
00578         splay_tree->root=(NodeInfo *) RelinquishMagickMemory(splay_tree->root);
00579         splay_tree->nodes--;
00580         if (left == (NodeInfo *) NULL)
00581           {
00582             splay_tree->root=right;
00583             (void) UnlockSemaphoreInfo(splay_tree->semaphore);
00584             return(MagickTrue);
00585           }
00586         splay_tree->root=left;
00587         if (right != (NodeInfo *) NULL)
00588           {
00589             while (left->right != (NodeInfo *) NULL)
00590               left=left->right;
00591             left->right=right;
00592           }
00593         (void) UnlockSemaphoreInfo(splay_tree->semaphore);
00594         return(MagickTrue);
00595       }
00596   }
00597   (void) UnlockSemaphoreInfo(splay_tree->semaphore);
00598   return(MagickFalse);
00599 }
00600 
00601 /*
00602 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00603 %                                                                             %
00604 %                                                                             %
00605 %                                                                             %
00606 %   D e l e t e N o d e F r o m S p l a y T r e e                             %
00607 %                                                                             %
00608 %                                                                             %
00609 %                                                                             %
00610 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00611 %
00612 %  DeleteNodeFromSplayTree() deletes a node from the splay-tree.
00613 %
00614 %  The format of the DeleteNodeFromSplayTree method is:
00615 %
00616 %      MagickBooleanType DeleteNodeFromSplayTree(SplayTreeInfo *splay_tree,
00617 %        const void *key)
00618 %
00619 %  A description of each parameter follows:
00620 %
00621 %    o splay_tree: the splay-tree info.
00622 %
00623 %    o key: the key.
00624 %
00625 */
00626 MagickExport MagickBooleanType DeleteNodeFromSplayTree(
00627   SplayTreeInfo *splay_tree,const void *key)
00628 {
00629   int
00630     compare;
00631 
00632   register NodeInfo
00633     *left,
00634     *right;
00635 
00636   assert(splay_tree != (SplayTreeInfo *) NULL);
00637   assert(splay_tree->signature == MagickSignature);
00638   if (splay_tree->debug != MagickFalse)
00639     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00640   if (splay_tree->root == (NodeInfo *) NULL)
00641     return(MagickFalse);
00642   (void) LockSemaphoreInfo(splay_tree->semaphore);
00643   SplaySplayTree(splay_tree,key);
00644   splay_tree->key=(void *) NULL;
00645   if (splay_tree->compare != (int (*)(const void *,const void *)) NULL)
00646     compare=splay_tree->compare(splay_tree->root->key,key);
00647   else
00648     compare=(splay_tree->root->key > key) ? 1 :
00649       ((splay_tree->root->key < key) ? -1 : 0);
00650   if (compare != 0)
00651     {
00652       (void) UnlockSemaphoreInfo(splay_tree->semaphore);
00653       return(MagickFalse);
00654     }
00655   left=splay_tree->root->left;
00656   right=splay_tree->root->right;
00657   if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
00658       (splay_tree->root->value != (void *) NULL))
00659     splay_tree->root->value=splay_tree->relinquish_value(
00660       splay_tree->root->value);
00661   if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
00662       (splay_tree->root->key != (void *) NULL))
00663     splay_tree->root->key=splay_tree->relinquish_key(splay_tree->root->key);
00664   splay_tree->root=(NodeInfo *) RelinquishMagickMemory(splay_tree->root);
00665   splay_tree->nodes--;
00666   if (left == (NodeInfo *) NULL)
00667     {
00668       splay_tree->root=right;
00669       (void) UnlockSemaphoreInfo(splay_tree->semaphore);
00670       return(MagickTrue);
00671     }
00672   splay_tree->root=left;
00673   if (right != (NodeInfo *) NULL)
00674     {
00675       while (left->right != (NodeInfo *) NULL)
00676         left=left->right;
00677       left->right=right;
00678     }
00679   (void) UnlockSemaphoreInfo(splay_tree->semaphore);
00680   return(MagickTrue);
00681 }
00682 
00683 /*
00684 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00685 %                                                                             %
00686 %                                                                             %
00687 %                                                                             %
00688 %   D e s t r o y S p l a y T r e e                                           %
00689 %                                                                             %
00690 %                                                                             %
00691 %                                                                             %
00692 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00693 %
00694 %  DestroySplayTree() destroys the splay-tree.
00695 %
00696 %  The format of the DestroySplayTree method is:
00697 %
00698 %      SplayTreeInfo *DestroySplayTree(SplayTreeInfo *splay_tree)
00699 %
00700 %  A description of each parameter follows:
00701 %
00702 %    o splay_tree: the splay tree.
00703 %
00704 */
00705 MagickExport SplayTreeInfo *DestroySplayTree(SplayTreeInfo *splay_tree)
00706 {
00707   NodeInfo
00708     *node;
00709 
00710   register NodeInfo
00711     *active,
00712     *pend;
00713 
00714   (void) LockSemaphoreInfo(splay_tree->semaphore);
00715   if (splay_tree->root != (NodeInfo *) NULL)
00716     {
00717       if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
00718           (splay_tree->root->key != (void *) NULL))
00719         splay_tree->root->key=splay_tree->relinquish_key(splay_tree->root->key);
00720       splay_tree->root->key=(void *) NULL;
00721       if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
00722           (splay_tree->root->value != (void *) NULL))
00723         splay_tree->root->value=splay_tree->relinquish_value(
00724           splay_tree->root->value);
00725       for (pend=splay_tree->root; pend != (NodeInfo *) NULL; )
00726       {
00727         active=pend;
00728         for (pend=(NodeInfo *) NULL; active != (NodeInfo *) NULL; )
00729         {
00730           if (active->left != (NodeInfo *) NULL)
00731             {
00732               if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
00733                   (active->left->key != (void *) NULL))
00734                 active->left->key=splay_tree->relinquish_key(active->left->key);
00735               active->left->key=(void *) pend;
00736               if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
00737                   (active->left->value != (void *) NULL))
00738                 active->left->value=splay_tree->relinquish_value(
00739                   active->left->value);
00740               pend=active->left;
00741             }
00742           if (active->right != (NodeInfo *) NULL)
00743             {
00744               if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
00745                   (active->right->key != (void *) NULL))
00746                 active->right->key=splay_tree->relinquish_key(
00747                   active->right->key);
00748               active->right->key=(void *) pend;
00749               if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
00750                   (active->right->value != (void *) NULL))
00751                 active->right->value=splay_tree->relinquish_value(
00752                   active->right->value);
00753               pend=active->right;
00754             }
00755           node=active;
00756           active=(NodeInfo *) node->key;
00757           node=(NodeInfo *) RelinquishMagickMemory(node);
00758         }
00759       }
00760     }
00761   splay_tree->signature=(~MagickSignature);
00762   (void) UnlockSemaphoreInfo(splay_tree->semaphore);
00763   DestroySemaphoreInfo(&splay_tree->semaphore);
00764   splay_tree=(SplayTreeInfo *) RelinquishMagickMemory(splay_tree);
00765   return(splay_tree);
00766 }
00767 
00768 /*
00769 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00770 %                                                                             %
00771 %                                                                             %
00772 %                                                                             %
00773 %   G e t N e x t K e y I n S p l a y T r e e                                 %
00774 %                                                                             %
00775 %                                                                             %
00776 %                                                                             %
00777 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00778 %
00779 %  GetNextKeyInSplayTree() gets the next key in the splay-tree.
00780 %
00781 %  The format of the GetNextKeyInSplayTree method is:
00782 %
00783 %      void *GetNextKeyInSplayTree(SplayTreeInfo *splay_tree)
00784 %
00785 %  A description of each parameter follows:
00786 %
00787 %    o splay_tree: the splay tree.
00788 %
00789 %    o key: the key.
00790 %
00791 */
00792 MagickExport void *GetNextKeyInSplayTree(SplayTreeInfo *splay_tree)
00793 {
00794   register NodeInfo
00795     *node;
00796 
00797   void
00798     *key;
00799 
00800   assert(splay_tree != (SplayTreeInfo *) NULL);
00801   assert(splay_tree->signature == MagickSignature);
00802   if (splay_tree->debug != MagickFalse)
00803     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00804   if ((splay_tree->root == (NodeInfo *) NULL) ||
00805       (splay_tree->next == (void *) NULL))
00806     return((void *) NULL);
00807   (void) LockSemaphoreInfo(splay_tree->semaphore);
00808   SplaySplayTree(splay_tree,splay_tree->next);
00809   splay_tree->next=(void *) NULL;
00810   node=splay_tree->root->right;
00811   if (node != (NodeInfo *) NULL)
00812     {
00813       while (node->left != (NodeInfo *) NULL)
00814         node=node->left;
00815       splay_tree->next=node->key;
00816     }
00817   key=splay_tree->root->key;
00818   (void) UnlockSemaphoreInfo(splay_tree->semaphore);
00819   return(key);
00820 }
00821 
00822 /*
00823 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00824 %                                                                             %
00825 %                                                                             %
00826 %                                                                             %
00827 %   G e t N e x t V a l u e I n S p l a y T r e e                             %
00828 %                                                                             %
00829 %                                                                             %
00830 %                                                                             %
00831 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00832 %
00833 %  GetNextValueInSplayTree() gets the next value in the splay-tree.
00834 %
00835 %  The format of the GetNextValueInSplayTree method is:
00836 %
00837 %      void *GetNextValueInSplayTree(SplayTreeInfo *splay_tree)
00838 %
00839 %  A description of each parameter follows:
00840 %
00841 %    o splay_tree: the splay tree.
00842 %
00843 %    o key: the key.
00844 %
00845 */
00846 MagickExport void *GetNextValueInSplayTree(SplayTreeInfo *splay_tree)
00847 {
00848   register NodeInfo
00849     *node;
00850 
00851   void
00852     *value;
00853 
00854   assert(splay_tree != (SplayTreeInfo *) NULL);
00855   assert(splay_tree->signature == MagickSignature);
00856   if (splay_tree->debug != MagickFalse)
00857     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00858   if ((splay_tree->root == (NodeInfo *) NULL) ||
00859       (splay_tree->next == (void *) NULL))
00860     return((void *) NULL);
00861   (void) LockSemaphoreInfo(splay_tree->semaphore);
00862   SplaySplayTree(splay_tree,splay_tree->next);
00863   splay_tree->next=(void *) NULL;
00864   node=splay_tree->root->right;
00865   if (node != (NodeInfo *) NULL)
00866     {
00867       while (node->left != (NodeInfo *) NULL)
00868         node=node->left;
00869       splay_tree->next=node->key;
00870     }
00871   value=splay_tree->root->value;
00872   (void) UnlockSemaphoreInfo(splay_tree->semaphore);
00873   return(value);
00874 }
00875 
00876 /*
00877 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00878 %                                                                             %
00879 %                                                                             %
00880 %                                                                             %
00881 %   G e t V a l u e F r o m S p l a y T r e e                                 %
00882 %                                                                             %
00883 %                                                                             %
00884 %                                                                             %
00885 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00886 %
00887 %  GetValueFromSplayTree() gets a value from the splay-tree by its key.
00888 %
00889 %  The format of the GetValueFromSplayTree method is:
00890 %
00891 %      void *GetValueFromSplayTree(SplayTreeInfo *splay_tree,const void *key)
00892 %
00893 %  A description of each parameter follows:
00894 %
00895 %    o splay_tree: the splay tree.
00896 %
00897 %    o key: the key.
00898 %
00899 */
00900 MagickExport void *GetValueFromSplayTree(SplayTreeInfo *splay_tree,
00901   const void *key)
00902 {
00903   int
00904     compare;
00905 
00906   void
00907     *value;
00908 
00909   assert(splay_tree != (SplayTreeInfo *) NULL);
00910   assert(splay_tree->signature == MagickSignature);
00911   if (splay_tree->debug != MagickFalse)
00912     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00913   if (splay_tree->root == (NodeInfo *) NULL)
00914     return((void *) NULL);
00915   (void) LockSemaphoreInfo(splay_tree->semaphore);
00916   SplaySplayTree(splay_tree,key);
00917   if (splay_tree->compare != (int (*)(const void *,const void *)) NULL)
00918     compare=splay_tree->compare(splay_tree->root->key,key);
00919   else
00920     compare=(splay_tree->root->key > key) ? 1 :
00921       ((splay_tree->root->key < key) ? -1 : 0);
00922   if (compare != 0)
00923     {
00924       (void) UnlockSemaphoreInfo(splay_tree->semaphore);
00925       return((void *) NULL);
00926     }
00927   value=splay_tree->root->value;
00928   (void) UnlockSemaphoreInfo(splay_tree->semaphore);
00929   return(value);
00930 }
00931 
00932 /*
00933 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00934 %                                                                             %
00935 %                                                                             %
00936 %                                                                             %
00937 %   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                     %
00938 %                                                                             %
00939 %                                                                             %
00940 %                                                                             %
00941 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00942 %
00943 %  GetNumberOfNodesInSplayTree() returns the number of nodes in the splay-tree.
00944 %
00945 %  The format of the GetNumberOfNodesInSplayTree method is:
00946 %
00947 %      unsigned long GetNumberOfNodesInSplayTree(
00948 %        const SplayTreeInfo *splay_tree)
00949 %
00950 %  A description of each parameter follows:
00951 %
00952 %    o splay_tree: the splay tree.
00953 %
00954 */
00955 MagickExport unsigned long GetNumberOfNodesInSplayTree(
00956   const SplayTreeInfo *splay_tree)
00957 {
00958   assert(splay_tree != (SplayTreeInfo *) NULL);
00959   assert(splay_tree->signature == MagickSignature);
00960   if (splay_tree->debug != MagickFalse)
00961     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00962   return(splay_tree->nodes);
00963 }
00964 
00965 /*
00966 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00967 %                                                                             %
00968 %                                                                             %
00969 %                                                                             %
00970 %   I t e r a t e O v e r S p l a y T r e e                                   %
00971 %                                                                             %
00972 %