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-2009 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   (void) LockSemaphoreInfo(splay_tree->semaphore);
00526   if (splay_tree->root == (NodeInfo *) NULL)
00527     {
00528       (void) UnlockSemaphoreInfo(splay_tree->semaphore);
00529       return(MagickFalse);
00530     }
00531   next=(NodeInfo *) GetFirstSplayTreeNode(splay_tree);
00532   while (next != (NodeInfo *) NULL)
00533   {
00534     SplaySplayTree(splay_tree,next);
00535     next=(NodeInfo *) NULL;
00536     node=splay_tree->root->right;
00537     if (node != (NodeInfo *) NULL)
00538       {
00539         while (node->left != (NodeInfo *) NULL)
00540           node=node->left;
00541         next=(NodeInfo *) node->key;
00542       }
00543     if (splay_tree->root->value == value)
00544       {
00545         int
00546           compare;
00547 
00548         register NodeInfo
00549           *left,
00550           *right;
00551 
00552         void
00553           *key;
00554 
00555         /*
00556           We found the node that matches the value; now delete it.
00557         */
00558         key=splay_tree->root->key;
00559         SplaySplayTree(splay_tree,key);
00560         splay_tree->key=(void *) NULL;
00561         if (splay_tree->compare != (int (*)(const void *,const void *)) NULL)
00562           compare=splay_tree->compare(splay_tree->root->key,key);
00563         else
00564           compare=(splay_tree->root->key > key) ? 1 :
00565             ((splay_tree->root->key < key) ? -1 : 0);
00566         if (compare != 0)
00567           {
00568             (void) UnlockSemaphoreInfo(splay_tree->semaphore);
00569             return(MagickFalse);
00570           }
00571         left=splay_tree->root->left;
00572         right=splay_tree->root->right;
00573         if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
00574             (splay_tree->root->key != (void *) NULL))
00575           splay_tree->root->key=splay_tree->relinquish_key(
00576             splay_tree->root->key);
00577         if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
00578             (splay_tree->root->value != (void *) NULL))
00579           splay_tree->root->value=splay_tree->relinquish_value(
00580             splay_tree->root->value);
00581         splay_tree->root=(NodeInfo *) RelinquishMagickMemory(splay_tree->root);
00582         splay_tree->nodes--;
00583         if (left == (NodeInfo *) NULL)
00584           {
00585             splay_tree->root=right;
00586             (void) UnlockSemaphoreInfo(splay_tree->semaphore);
00587             return(MagickTrue);
00588           }
00589         splay_tree->root=left;
00590         if (right != (NodeInfo *) NULL)
00591           {
00592             while (left->right != (NodeInfo *) NULL)
00593               left=left->right;
00594             left->right=right;
00595           }
00596         (void) UnlockSemaphoreInfo(splay_tree->semaphore);
00597         return(MagickTrue);
00598       }
00599   }
00600   (void) UnlockSemaphoreInfo(splay_tree->semaphore);
00601   return(MagickFalse);
00602 }
00603 
00604 /*
00605 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00606 %                                                                             %
00607 %                                                                             %
00608 %                                                                             %
00609 %   D e l e t e N o d e F r o m S p l a y T r e e                             %
00610 %                                                                             %
00611 %                                                                             %
00612 %                                                                             %
00613 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00614 %
00615 %  DeleteNodeFromSplayTree() deletes a node from the splay-tree.
00616 %
00617 %  The format of the DeleteNodeFromSplayTree method is:
00618 %
00619 %      MagickBooleanType DeleteNodeFromSplayTree(SplayTreeInfo *splay_tree,
00620 %        const void *key)
00621 %
00622 %  A description of each parameter follows:
00623 %
00624 %    o splay_tree: the splay-tree info.
00625 %
00626 %    o key: the key.
00627 %
00628 */
00629 MagickExport MagickBooleanType DeleteNodeFromSplayTree(
00630   SplayTreeInfo *splay_tree,const void *key)
00631 {
00632   int
00633     compare;
00634 
00635   register NodeInfo
00636     *left,
00637     *right;
00638 
00639   assert(splay_tree != (SplayTreeInfo *) NULL);
00640   assert(splay_tree->signature == MagickSignature);
00641   if (splay_tree->debug != MagickFalse)
00642     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00643   if (splay_tree->root == (NodeInfo *) NULL)
00644     return(MagickFalse);
00645   (void) LockSemaphoreInfo(splay_tree->semaphore);
00646   SplaySplayTree(splay_tree,key);
00647   splay_tree->key=(void *) NULL;
00648   if (splay_tree->compare != (int (*)(const void *,const void *)) NULL)
00649     compare=splay_tree->compare(splay_tree->root->key,key);
00650   else
00651     compare=(splay_tree->root->key > key) ? 1 :
00652       ((splay_tree->root->key < key) ? -1 : 0);
00653   if (compare != 0)
00654     {
00655       (void) UnlockSemaphoreInfo(splay_tree->semaphore);
00656       return(MagickFalse);
00657     }
00658   left=splay_tree->root->left;
00659   right=splay_tree->root->right;
00660   if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
00661       (splay_tree->root->value != (void *) NULL))
00662     splay_tree->root->value=splay_tree->relinquish_value(
00663       splay_tree->root->value);
00664   if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
00665       (splay_tree->root->key != (void *) NULL))
00666     splay_tree->root->key=splay_tree->relinquish_key(splay_tree->root->key);
00667   splay_tree->root=(NodeInfo *) RelinquishMagickMemory(splay_tree->root);
00668   splay_tree->nodes--;
00669   if (left == (NodeInfo *) NULL)
00670     {
00671       splay_tree->root=right;
00672       (void) UnlockSemaphoreInfo(splay_tree->semaphore);
00673       return(MagickTrue);
00674     }
00675   splay_tree->root=left;
00676   if (right != (NodeInfo *) NULL)
00677     {
00678       while (left->right != (NodeInfo *) NULL)
00679         left=left->right;
00680       left->right=right;
00681     }
00682   (void) UnlockSemaphoreInfo(splay_tree->semaphore);
00683   return(MagickTrue);
00684 }
00685 
00686 /*
00687 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00688 %                                                                             %
00689 %                                                                             %
00690 %                                                                             %
00691 %   D e s t r o y S p l a y T r e e                                           %
00692 %                                                                             %
00693 %                                                                             %
00694 %                                                                             %
00695 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00696 %
00697 %  DestroySplayTree() destroys the splay-tree.
00698 %
00699 %  The format of the DestroySplayTree method is:
00700 %
00701 %      SplayTreeInfo *DestroySplayTree(SplayTreeInfo *splay_tree)
00702 %
00703 %  A description of each parameter follows:
00704 %
00705 %    o splay_tree: the splay tree.
00706 %
00707 */
00708 MagickExport SplayTreeInfo *DestroySplayTree(SplayTreeInfo *splay_tree)
00709 {
00710   NodeInfo
00711     *node;
00712 
00713   register NodeInfo
00714     *active,
00715     *pend;
00716 
00717   (void) LockSemaphoreInfo(splay_tree->semaphore);
00718   if (splay_tree->root != (NodeInfo *) NULL)
00719     {
00720       if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
00721           (splay_tree->root->key != (void *) NULL))
00722         splay_tree->root->key=splay_tree->relinquish_key(splay_tree->root->key);
00723       splay_tree->root->key=(void *) NULL;
00724       if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
00725           (splay_tree->root->value != (void *) NULL))
00726         splay_tree->root->value=splay_tree->relinquish_value(
00727           splay_tree->root->value);
00728       for (pend=splay_tree->root; pend != (NodeInfo *) NULL; )
00729       {
00730         active=pend;
00731         for (pend=(NodeInfo *) NULL; active != (NodeInfo *) NULL; )
00732         {
00733           if (active->left != (NodeInfo *) NULL)
00734             {
00735               if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
00736                   (active->left->key != (void *) NULL))
00737                 active->left->key=splay_tree->relinquish_key(active->left->key);
00738               active->left->key=(void *) pend;
00739               if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
00740                   (active->left->value != (void *) NULL))
00741                 active->left->value=splay_tree->relinquish_value(
00742                   active->left->value);
00743               pend=active->left;
00744             }
00745           if (active->right != (NodeInfo *) NULL)
00746             {
00747               if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
00748                   (active->right->key != (void *) NULL))
00749                 active->right->key=splay_tree->relinquish_key(
00750                   active->right->key);
00751               active->right->key=(void *) pend;
00752               if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
00753                   (active->right->value != (void *) NULL))
00754                 active->right->value=splay_tree->relinquish_value(
00755                   active->right->value);
00756               pend=active->right;
00757             }
00758           node=active;
00759           active=(NodeInfo *) node->key;
00760           node=(NodeInfo *) RelinquishMagickMemory(node);
00761         }
00762       }
00763     }
00764   splay_tree->signature=(~MagickSignature);
00765   (void) UnlockSemaphoreInfo(splay_tree->semaphore);
00766   DestroySemaphoreInfo(&splay_tree->semaphore);
00767   splay_tree=(SplayTreeInfo *) RelinquishMagickMemory(splay_tree);
00768   return(splay_tree);
00769 }
00770 
00771 /*
00772 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00773 %                                                                             %
00774 %                                                                             %
00775 %                                                                             %
00776 %   G e t N e x t K e y I n S p l a y T r e e                                 %
00777 %                                                                             %
00778 %                                                                             %
00779 %                                                                             %
00780 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00781 %
00782 %  GetNextKeyInSplayTree() gets the next key in the splay-tree.
00783 %
00784 %  The format of the GetNextKeyInSplayTree method is:
00785 %
00786 %      void *GetNextKeyInSplayTree(SplayTreeInfo *splay_tree)
00787 %
00788 %  A description of each parameter follows:
00789 %
00790 %    o splay_tree: the splay tree.
00791 %
00792 %    o key: the key.
00793 %
00794 */
00795 MagickExport void *GetNextKeyInSplayTree(SplayTreeInfo *splay_tree)
00796 {
00797   register NodeInfo
00798     *node;
00799 
00800   void
00801     *key;
00802 
00803   assert(splay_tree != (SplayTreeInfo *) NULL);
00804   assert(splay_tree->signature == MagickSignature);
00805   if (splay_tree->debug != MagickFalse)
00806     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00807   if ((splay_tree->root == (NodeInfo *) NULL) ||
00808       (splay_tree->next == (void *) NULL))
00809     return((void *) NULL);
00810   (void) LockSemaphoreInfo(splay_tree->semaphore);
00811   SplaySplayTree(splay_tree,splay_tree->next);
00812   splay_tree->next=(void *) NULL;
00813   node=splay_tree->root->right;
00814   if (node != (NodeInfo *) NULL)
00815     {
00816       while (node->left != (NodeInfo *) NULL)
00817         node=node->left;
00818       splay_tree->next=node->key;
00819     }
00820   key=splay_tree->root->key;
00821   (void) UnlockSemaphoreInfo(splay_tree->semaphore);
00822   return(key);
00823 }
00824 
00825 /*
00826 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00827 %                                                                             %
00828 %                                                                             %
00829 %                                                                             %
00830 %   G e t N e x t V a l u e I n S p l a y T r e e                             %
00831 %                                                                             %
00832 %                                                                             %
00833 %                                                                             %
00834 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00835 %
00836 %  GetNextValueInSplayTree() gets the next value in the splay-tree.
00837 %
00838 %  The format of the GetNextValueInSplayTree method is:
00839 %
00840 %      void *GetNextValueInSplayTree(SplayTreeInfo *splay_tree)
00841 %
00842 %  A description of each parameter follows:
00843 %
00844 %    o splay_tree: the splay tree.
00845 %
00846 %    o key: the key.
00847 %
00848 */
00849 MagickExport void *GetNextValueInSplayTree(SplayTreeInfo *splay_tree)
00850 {
00851   register NodeInfo
00852     *node;
00853 
00854   void
00855     *value;
00856 
00857   assert(splay_tree != (SplayTreeInfo *) NULL);
00858   assert(splay_tree->signature == MagickSignature);
00859   if (splay_tree->debug != MagickFalse)
00860     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00861   if ((splay_tree->root == (NodeInfo *) NULL) ||
00862       (splay_tree->next == (void *) NULL))
00863     return((void *) NULL);
00864   (void) LockSemaphoreInfo(splay_tree->semaphore);
00865   SplaySplayTree(splay_tree,splay_tree->next);
00866   splay_tree->next=(void *) NULL;
00867   node=splay_tree->root->right;
00868   if (node != (NodeInfo *) NULL)
00869     {
00870       while (node->left != (NodeInfo *) NULL)
00871         node=node->left;
00872       splay_tree->next=node->key;
00873     }
00874   value=splay_tree->root->value;
00875   (void) UnlockSemaphoreInfo(splay_tree->semaphore);
00876   return(value);
00877 }
00878 
00879 /*
00880 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00881 %                                                                             %
00882 %                                                                             %
00883 %                                                                             %
00884 %   G e t V a l u e F r o m S p l a y T r e e                                 %
00885 %                                                                             %
00886 %                                                                             %
00887 %                                                                             %
00888 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00889 %
00890 %  GetValueFromSplayTree() gets a value from the splay-tree by its key.
00891 %
00892 %  The format of the GetValueFromSplayTree method is:
00893 %
00894 %      void *GetValueFromSplayTree(SplayTreeInfo *splay_tree,const void *key)
00895 %
00896 %  A description of each parameter follows:
00897 %
00898 %    o splay_tree: the splay tree.
00899 %
00900 %    o key: the key.
00901 %
00902 */
00903 MagickExport void *GetValueFromSplayTree(SplayTreeInfo *splay_tree,
00904   const void *key)
00905 {
00906   int
00907     compare;
00908 
00909   void
00910     *value;
00911 
00912   assert(splay_tree != (SplayTreeInfo *) NULL);
00913   assert(splay_tree->signature == MagickSignature);
00914   if (splay_tree->debug != MagickFalse)
00915     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00916   if (splay_tree->root == (NodeInfo *) NULL)
00917     return((void *) NULL);
00918   (void) LockSemaphoreInfo(splay_tree->semaphore);
00919   SplaySplayTree(splay_tree,key);
00920   if (splay_tree->compare != (int (*)(const void *,const void *)) NULL)
00921     compare=splay_tree->compare(splay_tree->root->key,key);
00922   else
00923     compare=(splay_tree->root->key > key) ? 1 :
00924       ((splay_tree->root->key < key) ? -1 : 0);
00925   if (compare != 0)
00926     {
00927       (void) UnlockSemaphoreInfo(splay_tree->semaphore);
00928       return((void *) NULL);
00929     }
00930   value=splay_tree->root->value;
00931   (void) UnlockSemaphoreInfo(splay_tree->semaphore);
00932   return(value);
00933 }
00934 
00935 /*
00936 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00937 %                                                                             %
00938 %                                                                             %
00939 %                                                                             %
00940 %   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                     %
00941 %                                                                             %
00942 %                                                                             %
00943 %                                                                             %
00944 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00945 %
00946 %  GetNumberOfNodesInSplayTree() returns the number of nodes in the splay-tree.
00947 %
00948 %  The format of the GetNumberOfNodesInSplayTree method is:
00949 %
00950 %      unsigned long GetNumberOfNodesInSplayTree(
00951 %        const SplayTreeInfo *splay_tree)
00952 %
00953 %  A description of each parameter follows:
00954 %
00955 %    o splay_tree: the splay tree.
00956 %
00957 */
00958 MagickExport unsigned long GetNumberOfNodesInSplayTree(
00959   const SplayTreeInfo *splay_tree)
00960 {
00961   assert(splay_tree != (SplayTreeInfo *) NULL);
00962   assert(splay_tree->signature == MagickSignature);
00963   if (splay_tree->debug != MagickFalse)
00964     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00965   return(splay_tree->nodes);
00966 }
00967 
00968 /*
00969 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00970 %                                                                             %
00971 %                                                                             %
00972 %                                                                             %
00973 %   I t e r a t e O v e r S p l a y T r e e                                   %
00974 %                                                                             %
00975 %                                                                             %
00976 %                                                                             %
00977 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00978 %
00979 %  IterateOverSplayTree() iterates over the splay-tree.
00980 %
00981 %  The format of the IterateOverSplayTree method is:
00982 %
00983 %      int IterateOverSplayTree(SplayTreeInfo *splay_tree,
00984 %        int (*method)(NodeInfo *,void *),const void *value)
00985 %
00986 %  A description of each parameter follows:
00987 %
00988 %    o splay_tree: the splay-tree info.
00989 %
00990 %    o method: the method.
00991 %
00992 %    o value: the value.
00993 %
00994 */
00995 static int IterateOverSplayTree(SplayTreeInfo *splay_tree,
00996   int (*method)(NodeInfo *,const void *),const void *value)
00997 {
00998   typedef enum
00999   {
01000     LeftTransition,
01001     RightTransition,
01002     DownTransition,
01003     UpTransition
01004   } TransitionType;
01005 
01006   int
01007     status;
01008 
01009   MagickBooleanType
01010     final_transition;
01011 
01012   NodeInfo
01013     **nodes;
01014 
01015   register long
01016     i;
01017 
01018   register NodeInfo
01019     *node;
01020 
01021   TransitionType
01022     transition;
01023 
01024   unsigned char
01025     *transitions;
01026 
01027   if (splay_tree->root == (NodeInfo *) NULL)
01028     return(0);
01029   nodes=(NodeInfo **) AcquireQuantumMemory((size_t) splay_tree->nodes,
01030     sizeof(*nodes));
01031   transitions=(unsigned char *) AcquireQuantumMemory((size_t) splay_tree->nodes,
01032     sizeof(*transitions));
01033   if ((nodes == (NodeInfo **) NULL) || (transitions == (unsigned char *) NULL))
01034     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
01035   status=0;
01036   final_transition=MagickFalse;
01037   nodes[0]=splay_tree->root;
01038   transitions[0]=(unsigned char) LeftTransition;
01039   for (i=0; final_transition == MagickFalse; )
01040   {
01041     node=nodes[i];
01042     transition=(TransitionType) transitions[i];
01043     switch (transition)
01044     {
01045       case LeftTransition:
01046       {
01047         transitions[i]=(unsigned char) DownTransition;
01048         if (node->left == (NodeInfo *) NULL)
01049           break;
01050         i++;
01051         nodes[i]=node->left;
01052         transitions[i]=(unsigned char) LeftTransition;
01053         break;
01054       }
01055       case RightTransition:
01056       {
01057         transitions[i]=(unsigned char) UpTransition;
01058         if (node->right == (NodeInfo *) NULL)
01059           break;
01060         i++;
01061         nodes[i]=node->right;
01062         transitions[i]=(unsigned char) LeftTransition;
01063         break;
01064       }
01065       case DownTransition:
01066       default:
01067       {
01068         transitions[i]=(unsigned char) RightTransition;
01069         status=(*method)(node,value);
01070         if (status != 0)
01071           final_transition=MagickTrue;
01072         break;
01073       }
01074       case UpTransition:
01075       {
01076         if (i == 0)
01077           {
01078             final_transition=MagickTrue;
01079             break;
01080           }
01081         i--;
01082         break;
01083       }
01084     }
01085   }
01086   nodes=(NodeInfo **) RelinquishMagickMemory(nodes);
01087   transitions=(unsigned char *) RelinquishMagickMemory(transitions);
01088   return(status);
01089 }
01090 
01091 /*
01092 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01093 %                                                                             %
01094 %                                                                             %
01095 %                                                                             %
01096 %   N e w S p l a y T r e e                                                   %
01097 %                                                                             %
01098 %                                                                             %
01099 %                                                                             %
01100 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01101 %
01102 %  NewSplayTree() returns a pointer to a SplayTreeInfo structure initialized
01103 %  to default values.
01104 %
01105 %  The format of the NewSplayTree method is:
01106 %
01107 %      SplayTreeInfo *NewSplayTree(int (*compare)(const void *,const void *),
01108 %        void *(*relinquish_key)(void *),void *(*relinquish_value)(void *))
01109 %
01110 %  A description of each parameter follows:
01111 %
01112 %    o compare: the compare method.
01113 %
01114 %    o relinquish_key: the key deallocation method, typically
01115 %      RelinquishMagickMemory(), called whenever a key is removed from the
01116 %      splay-tree.
01117 %
01118 %    o relinquish_value: the value deallocation method;  typically
01119 %      RelinquishMagickMemory(), called whenever a value object is removed from
01120 %      the splay-tree.
01121 %
01122 */
01123 MagickExport SplayTreeInfo *NewSplayTree(
01124   int (*compare)(const void *,const void *),void *(*relinquish_key)(void *),
01125   void *(*relinquish_value)(void *))
01126 {
01127   SplayTreeInfo
01128     *splay_tree;
01129 
01130   splay_tree=(SplayTreeInfo *) AcquireMagickMemory(sizeof(*splay_tree));
01131   if (splay_tree == (SplayTreeInfo *) NULL)
01132     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
01133   (void) ResetMagickMemory(splay_tree,0,sizeof(*splay_tree));
01134   splay_tree->root=(NodeInfo *) NULL;
01135   splay_tree->compare=compare;
01136   splay_tree->relinquish_key=relinquish_key;
01137   splay_tree->relinquish_value=relinquish_value;
01138   splay_tree->balance=MagickFalse;
01139   splay_tree->key=(void *) NULL;
01140   splay_tree->next=(void *) NULL;
01141   splay_tree->nodes=0;
01142   splay_tree->debug=IsEventLogging();
01143   splay_tree->semaphore=AllocateSemaphoreInfo();
01144   splay_tree->signature=MagickSignature;
01145   return(splay_tree);
01146 }
01147 
01148 /*
01149 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01150 %                                                                             %
01151 %                                                                             %
01152 %                                                                             %
01153 %   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               %
01154 %                                                                             %
01155 %                                                                             %
01156 %                                                                             %
01157 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01158 %
01159 %  RemoveNodeByValueFromSplayTree() removes a node by value from the splay-tree
01160 %  and returns its key.
01161 %
01162 %  The format of the RemoveNodeByValueFromSplayTree method is:
01163 %
01164 %      void *RemoveNodeByValueFromSplayTree(SplayTreeInfo *splay_tree,
01165 %        const void *value)
01166 %
01167 %  A description of each parameter follows:
01168 %
01169 %    o splay_tree: the splay-tree info.
01170 %
01171 %    o value: the value.
01172 %
01173 */
01174 MagickExport void *RemoveNodeByValueFromSplayTree(SplayTreeInfo *splay_tree,
01175   const void *value)
01176 {
01177   register NodeInfo
01178     *next,
01179     *node;
01180 
01181   void
01182     *key;
01183 
01184   assert(splay_tree != (SplayTreeInfo *) NULL);
01185   assert(splay_tree->signature == MagickSignature);
01186   if (splay_tree->debug != MagickFalse)
01187     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
01188   key=(void *) NULL;
01189   if (splay_tree->root == (NodeInfo *) NULL)
01190     return(key);
01191   (void) LockSemaphoreInfo(splay_tree->semaphore);
01192   next=(NodeInfo *) GetFirstSplayTreeNode(splay_tree);
01193   while (next != (NodeInfo *) NULL)
01194   {
01195     SplaySplayTree(splay_tree,next);
01196     next=(NodeInfo *) NULL;
01197     node=splay_tree->root->right;
01198     if (node != (NodeInfo *) NULL)
01199       {
01200         while (node->left != (NodeInfo *) NULL)
01201           node=node->left;
01202         next=(NodeInfo *) node->key;
01203       }
01204     if (splay_tree->root->value == value)
01205       {
01206         int
01207           compare;
01208 
01209         register NodeInfo
01210           *left,
01211           *right;
01212 
01213         /*
01214           We found the node that matches the value; now remove it.
01215         */
01216         key=splay_tree->root->key;
01217         SplaySplayTree(splay_tree,key);
01218         splay_tree->key=(void *) NULL;
01219         if (splay_tree->compare != (int (*)(const void *,const void *)) NULL)
01220           compare=splay_tree->compare(splay_tree->root->key,key);
01221         else
01222           compare=(splay_tree->root->key > key) ? 1 :
01223             ((splay_tree->root->key < key) ? -1 : 0);
01224         if (compare != 0)
01225           {
01226             (void) UnlockSemaphoreInfo(splay_tree->semaphore);
01227             return(key);
01228           }
01229         left=splay_tree->root->left;
01230         right=splay_tree->root->right;
01231         if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
01232             (splay_tree->root->value != (void *) NULL))
01233           splay_tree->root->value=splay_tree->relinquish_value(
01234             splay_tree->root->value);
01235         splay_tree->root=(NodeInfo *) RelinquishMagickMemory(splay_tree->root);
01236         splay_tree->nodes--;
01237         if (left == (NodeInfo *) NULL)
01238           {
01239             splay_tree->root=right;
01240             (void) UnlockSemaphoreInfo(splay_tree->semaphore);
01241             return(key);
01242           }
01243         splay_tree->root=left;
01244         if (right != (NodeInfo *) NULL)
01245           {
01246             while (left->right != (NodeInfo *) NULL)
01247               left=left->right;
01248             left->right=right;
01249           }
01250         (void) UnlockSemaphoreInfo(splay_tree->semaphore);
01251         return(key);
01252       }
01253   }
01254   (void) UnlockSemaphoreInfo(splay_tree->semaphore);
01255   return(key);
01256 }
01257 
01258 /*
01259 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01260 %                                                                             %
01261 %                                                                             %
01262 %                                                                             %
01263 %   R e m o v e N o d e F r o m S p l a y T r e e                             %
01264 %                                                                             %
01265 %                                                                             %
01266 %                                                                             %
01267 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01268 %
01269 %  RemoveNodeFromSplayTree() removes a node from the splay-tree and returns its
01270 %  value.
01271 %
01272 %  The format of the RemoveNodeFromSplayTree method is:
01273 %
01274 %      void *RemoveNodeFromSplayTree(SplayTreeInfo *splay_tree,const void *key)
01275 %
01276 %  A description of each parameter follows:
01277 %
01278 %    o splay_tree: the splay-tree info.
01279 %
01280 %    o key: the key.
01281 %
01282 */
01283 MagickExport void *RemoveNodeFromSplayTree(SplayTreeInfo *splay_tree,
01284   const void *key)
01285 {
01286   int
01287     compare;
01288 
01289   register NodeInfo
01290     *left,
01291     *right;
01292 
01293   void
01294     *value;
01295 
01296   assert(splay_tree != (SplayTreeInfo *) NULL);
01297   assert(splay_tree->signature == MagickSignature);
01298   if (splay_tree->debug != MagickFalse)
01299     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
01300   value=(void *) NULL;
01301   if (splay_tree->root == (NodeInfo *) NULL)
01302     return(value);
01303   (void) LockSemaphoreInfo(splay_tree->semaphore);
01304   SplaySplayTree(splay_tree,key);
01305   splay_tree->key=(void *) NULL;
01306   if (splay_tree->compare != (int (*)(const void *,const void *)) NULL)
01307     compare=splay_tree->compare(splay_tree->root->key,key);
01308   else
01309     compare=(splay_tree->root->key > key) ? 1 :
01310       ((splay_tree->root->key < key) ? -1 : 0);
01311   if (compare != 0)
01312     {
01313       (void) UnlockSemaphoreInfo(splay_tree->semaphore);
01314       return(value);
01315     }
01316   left=splay_tree->root->left;
01317   right=splay_tree->root->right;
01318   value=splay_tree->root->value;
01319   if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
01320       (splay_tree->root->key != (void *) NULL))
01321     splay_tree->root->key=splay_tree->relinquish_key(splay_tree->root->key);
01322   splay_tree->root=(NodeInfo *) RelinquishMagickMemory(splay_tree->root);
01323   splay_tree->nodes--;
01324   if (left == (NodeInfo *) NULL)
01325     {
01326       splay_tree->root=right;
01327       (void) UnlockSemaphoreInfo(splay_tree->semaphore);
01328       return(value);
01329     }
01330   splay_tree->root=left;
01331   if (right != (NodeInfo *) NULL)
01332     {
01333       while (left->right != (NodeInfo *) NULL)
01334         left=left->right;
01335       left->right=right;
01336     }
01337   (void) UnlockSemaphoreInfo(splay_tree->semaphore);
01338   return(value);
01339 }
01340 
01341 /*
01342 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01343 %                                                                             %
01344 %                                                                             %
01345 %                                                                             %
01346 %   R e s e t S p l a y T r e e                                               %
01347 %                                                                             %
01348 %                                                                             %
01349 %                                                                             %
01350 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01351 %
01352 %  ResetSplayTree() resets the splay-tree.  That is, it deletes all the nodes
01353 %  from the tree.
01354 %
01355 %  The format of the ResetSplayTree method is:
01356 %
01357 %      ResetSplayTree(SplayTreeInfo *splay_tree)
01358 %
01359 %  A description of each parameter follows:
01360 %
01361 %    o splay_tree: the splay tree.
01362 %
01363 */
01364 MagickExport void ResetSplayTree(SplayTreeInfo *splay_tree)
01365 {
01366   NodeInfo
01367     *node;
01368 
01369   register NodeInfo
01370     *active,
01371     *pend;
01372 
01373   assert(splay_tree != (SplayTreeInfo *) NULL);
01374   assert(splay_tree->signature == MagickSignature);
01375   if (splay_tree->debug != MagickFalse)
01376     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
01377   (void) LockSemaphoreInfo(splay_tree->semaphore);
01378   if (splay_tree->root != (NodeInfo *) NULL)
01379     {
01380       if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
01381           (splay_tree->root->key != (void *) NULL))
01382         splay_tree->root->key=splay_tree->relinquish_key(splay_tree->root->key);
01383       splay_tree->root->key=(void *) NULL;
01384       if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
01385           (splay_tree->root->value != (void *) NULL))
01386         splay_tree->root->value=splay_tree->relinquish_value(
01387           splay_tree->root->value);
01388       for (pend=splay_tree->root; pend != (NodeInfo *) NULL; )
01389       {
01390         active=pend;
01391         for (pend=(NodeInfo *) NULL; active != (NodeInfo *) NULL; )
01392         {
01393           if (active->left != (NodeInfo *) NULL)
01394             {
01395               if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
01396                   (active->left->key != (void *) NULL))
01397                 active->left->key=splay_tree->relinquish_key(active->left->key);
01398               active->left->key=(void *) pend;
01399               if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
01400                   (active->left->value != (void *) NULL))
01401                 active->left->value=splay_tree->relinquish_value(
01402                   active->left->value);
01403               pend=active->left;
01404             }
01405           if (active->right != (NodeInfo *) NULL)
01406             {
01407               if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
01408                   (active->right->key != (void *) NULL))
01409                 active->right->key=splay_tree->relinquish_key(
01410                   active->right->key);
01411               active->right->key=(void *) pend;
01412               if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
01413                   (active->right->value != (void *) NULL))
01414                 active->right->value=splay_tree->relinquish_value(
01415                   active->right->value);
01416               pend=active->right;
01417             }
01418           node=active;
01419           active=(NodeInfo *) node->key;
01420           node=(NodeInfo *) RelinquishMagickMemory(node);
01421         }
01422       }
01423     }
01424   splay_tree->root=(NodeInfo *) NULL;
01425   splay_tree->key=(void *) NULL;
01426   splay_tree->next=(void *) NULL;
01427   splay_tree->nodes=0;
01428   splay_tree->balance=MagickFalse;
01429   (void) UnlockSemaphoreInfo(splay_tree->semaphore);
01430 }
01431 
01432 /*
01433 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01434 %                                                                             %
01435 %                                                                             %
01436 %                                                                             %
01437 %   R e s e t S p l a y T r e e I t e r a t o r                               %
01438 %                                                                             %
01439 %                                                                             %
01440 %                                                                             %
01441 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01442 %
01443 %  ResetSplayTreeIterator() resets the splay-tree iterator.  Use it in
01444 %  conjunction with GetNextValueInSplayTree() to iterate over all the nodes in
01445 %  the splay-tree.
01446 %
01447 %  The format of the ResetSplayTreeIterator method is:
01448 %
01449 %      ResetSplayTreeIterator(SplayTreeInfo *splay_tree)
01450 %
01451 %  A description of each parameter follows:
01452 %
01453 %    o splay_tree: the splay tree.
01454 %
01455 */
01456 MagickExport void ResetSplayTreeIterator(SplayTreeInfo *splay_tree)
01457 {
01458   assert(splay_tree != (SplayTreeInfo *) NULL);
01459   assert(splay_tree->signature == MagickSignature);
01460   if (splay_tree->debug != MagickFalse)
01461     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
01462   (void) LockSemaphoreInfo(splay_tree->semaphore);
01463   splay_tree->next=GetFirstSplayTreeNode(splay_tree);
01464   (void) UnlockSemaphoreInfo(splay_tree->semaphore);
01465 }
01466 
01467 /*
01468 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01469 %                                                                             %
01470 %                                                                             %
01471 %                                                                             %
01472 %   S p l a y S p l a y T r e e                                               %
01473 %                                                                             %
01474 %                                                                             %
01475 %                                                                             %
01476 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01477 %
01478 %  SplaySplayTree() splays the splay-tree.
01479 %
01480 %  The format of the SplaySplayTree method is:
01481 %
01482 %      void SplaySplayTree(SplayTreeInfo *splay_tree,const void *key,
01483 %        NodeInfo **node,NodeInfo **parent,NodeInfo **grandparent)
01484 %
01485 %  A description of each parameter follows:
01486 %
01487 %    o splay_tree: the splay-tree info.
01488 %
01489 %    o key: the key.
01490 %
01491 %    o node: the node.
01492 %
01493 %    o parent: the parent node.
01494 %
01495 %    o grandparent: the grandparent node.
01496 %
01497 */
01498 
01499 static NodeInfo *Splay(SplayTreeInfo *splay_tree,const unsigned long depth,
01500   const void *key,NodeInfo **node,NodeInfo **parent,NodeInfo **grandparent)
01501 {
01502   int
01503     compare;
01504 
01505   NodeInfo
01506     **next;
01507 
01508   register NodeInfo
01509     *n,
01510     *p;
01511 
01512   n=(*node);
01513   if (n == (NodeInfo *) NULL)
01514     return(*parent);
01515   if (splay_tree->compare != (int (*)(const void *,const void *)) NULL)
01516     compare=splay_tree->compare(n->key,key);
01517   else
01518     compare=(n->key > key) ? 1 : ((n->key < key) ? -1 : 0);
01519   next=(NodeInfo **) NULL;
01520   if (compare > 0)
01521     next=(&n->left);
01522   else
01523     if (compare < 0)
01524       next=(&n->right);
01525   if (next != (NodeInfo **) NULL)
01526     {
01527       if (depth >= MaxSplayTreeDepth)
01528         {
01529           splay_tree->balance=MagickTrue;
01530           return(n);
01531         }
01532       n=Splay(splay_tree,depth+1,key,next,node,parent);
01533       if ((n != *node) || (splay_tree->balance != MagickFalse))
01534         return(n);
01535     }
01536   if (parent == (NodeInfo **) NULL)
01537     return(n);
01538   if (grandparent == (NodeInfo **) NULL)
01539     {
01540       if (n == (*parent)->left)
01541         {
01542           *node=n->right;
01543           n->right=(*parent);
01544         }
01545       else
01546         {
01547           *node=n->left;
01548           n->left=(*parent);
01549         }
01550       *parent=n;
01551       return(n);
01552     }
01553   if ((n == (*parent)->left) && (*parent == (*grandparent)->left))
01554     {
01555       p=(*parent);
01556       (*grandparent)->left=p->right;
01557       p->right=(*grandparent);
01558       p->left=n->right;
01559       n->right=p;
01560       *grandparent=n;
01561       return(n);
01562     }
01563   if ((n == (*parent)->right) && (*parent == (*grandparent)->right))
01564     {
01565       p=(*parent);
01566       (*grandparent)->right=p->left;
01567       p->left=(*grandparent);
01568       p->right=n->left;
01569       n->left=p;
01570       *grandparent=n;
01571       return(n);
01572     }
01573   if (n == (*parent)->left)
01574     {
01575       (*parent)->left=n->right;
01576       n->right=(*parent);
01577       (*grandparent)->right=n->left;
01578       n->left=(*grandparent);
01579       *grandparent=n;
01580       return(n);
01581     }
01582   (*parent)->right=n->left;
01583   n->left=(*parent);
01584   (*grandparent)->left=n->right;
01585   n->right=(*grandparent);
01586   *grandparent=n;
01587   return(n);
01588 }
01589 
01590 static void SplaySplayTree(SplayTreeInfo *splay_tree,const void *key)
01591 {
01592   if (splay_tree->root == (NodeInfo *) NULL)
01593     return;
01594   if (splay_tree->key != (void *) NULL)
01595     {
01596       int
01597         compare;
01598 
01599       if (splay_tree->compare != (int (*)(const void *,const void *)) NULL)
01600         compare=splay_tree->compare(splay_tree->root->key,key);
01601       else
01602         compare=(splay_tree->key > key) ? 1 :
01603           ((splay_tree->key < key) ? -1 : 0);
01604       if (compare == 0)
01605         return;
01606     }
01607   (void) Splay(splay_tree,0UL,key,&splay_tree->root,(NodeInfo **) NULL,
01608     (NodeInfo **) NULL);
01609   if (splay_tree->balance != MagickFalse)
01610     {
01611       BalanceSplayTree(splay_tree);
01612       (void) Splay(splay_tree,0UL,key,&splay_tree->root,(NodeInfo **) NULL,
01613         (NodeInfo **) NULL);
01614       if (splay_tree->balance != MagickFalse)
01615         ThrowFatalException(ResourceLimitFatalError,
01616           "MemoryAllocationFailed");
01617     }
01618   splay_tree->key=(void *) key;
01619 }

Generated on 19 Nov 2009 for MagickCore by  doxygen 1.6.1