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 %          Wizard's Toolkit Self-adjusting Binary Search Tree Methods         %
00020 %                                                                             %
00021 %                              Software Design                                %
00022 %                                John Cristy                                  %
00023 %                               December 2002                                 %
00024 %                                                                             %
00025 %                                                                             %
00026 %  Copyright 1999-2010 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.wizards-toolkit.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 "wizard/studio.h"
00052 #include "wizard/exception.h"
00053 #include "wizard/exception-private.h"
00054 #include "wizard/log.h"
00055 #include "wizard/memory_.h"
00056 #include "wizard/splay-tree.h"
00057 #include "wizard/semaphore.h"
00058 #include "wizard/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   WizardBooleanType
00094     balance;
00095 
00096   void
00097     *key,
00098     *next;
00099 
00100   size_t
00101     nodes;
00102 
00103   WizardBooleanType
00104     debug;
00105 
00106   SemaphoreInfo
00107     *semaphore;
00108 
00109   size_t
00110     signature;
00111 };
00112 
00113 /*
00114   Forward declarations.
00115 */
00116 static int
00117   IterateOverSplayTree(SplayTreeInfo *,int (*)(NodeInfo *,const void *),
00118     const void *);
00119 
00120 static void
00121   SplaySplayTree(SplayTreeInfo *,const void *);
00122 
00123 /*
00124 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00125 %                                                                             %
00126 %                                                                             %
00127 %                                                                             %
00128 %   A d d V a l u e T o S p l a y T r e e                                     %
00129 %                                                                             %
00130 %                                                                             %
00131 %                                                                             %
00132 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00133 %
00134 %  AddValueToSplayTree() adds a value to the splay-tree.
00135 %
00136 %  The format of the AddValueToSplayTree method is:
00137 %
00138 %      WizardBooleanType 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 WizardExport WizardBooleanType AddValueToSplayTree(SplayTreeInfo *splay_tree,
00151   const void *key,const void *value)
00152 {
00153   int
00154     compare;
00155 
00156   register NodeInfo
00157     *node;
00158 
00159   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           UnlockSemaphoreInfo(splay_tree->semaphore);
00182           return(WizardTrue);
00183         }
00184     }
00185   node=(NodeInfo *) AcquireAlignedMemory(1,sizeof(*node));
00186   if (node == (NodeInfo *) NULL)
00187     {
00188       UnlockSemaphoreInfo(splay_tree->semaphore);
00189       return(WizardFalse);
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   UnlockSemaphoreInfo(splay_tree->semaphore);
00215   return(WizardTrue);
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 size_t low,
00244   const size_t high)
00245 {
00246   register NodeInfo
00247     *node;
00248 
00249   size_t
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=WizardFalse;
00285       return;
00286     }
00287   nodes=(NodeInfo **) AcquireQuantumMemory((size_t) splay_tree->nodes,
00288     sizeof(*nodes));
00289   if (nodes == (NodeInfo **) NULL)
00290     ThrowWizardFatalError(CacheDomain,MemoryError);
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=WizardFalse;
00296   nodes=(NodeInfo **) RelinquishWizardMemory(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 
00329 static void *GetFirstSplayTreeNode(SplayTreeInfo *splay_tree)
00330 {
00331   register NodeInfo
00332     *node;
00333 
00334   node=splay_tree->root;
00335   if (splay_tree->root == (NodeInfo *) NULL)
00336     return((NodeInfo *) NULL);
00337   while (node->left != (NodeInfo *) NULL)
00338     node=node->left;
00339   return(node->key);
00340 }
00341 
00342 WizardExport SplayTreeInfo *CloneSplayTree(SplayTreeInfo *splay_tree,
00343   void *(*clone_key)(void *),void *(*clone_value)(void *))
00344 {
00345   register NodeInfo
00346     *next,
00347     *node;
00348 
00349   SplayTreeInfo
00350     *clone_tree;
00351 
00352   WizardAssert(ResourceDomain,splay_tree != (SplayTreeInfo *) NULL);
00353   WizardAssert(ResourceDomain,splay_tree->signature == WizardSignature);
00354   if (splay_tree->debug != WizardFalse)
00355     (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00356   clone_tree=NewSplayTree(splay_tree->compare,splay_tree->relinquish_key,
00357     splay_tree->relinquish_value);
00358   LockSemaphoreInfo(splay_tree->semaphore);
00359   if (splay_tree->root == (NodeInfo *) NULL)
00360     {
00361       UnlockSemaphoreInfo(splay_tree->semaphore);
00362       return(clone_tree);
00363     }
00364   next=(NodeInfo *) GetFirstSplayTreeNode(splay_tree);
00365   while (next != (NodeInfo *) NULL)
00366   {
00367     SplaySplayTree(splay_tree,next);
00368     (void) AddValueToSplayTree(clone_tree,clone_key(splay_tree->root->key),
00369       clone_value(splay_tree->root->value));
00370     next=(NodeInfo *) NULL;
00371     node=splay_tree->root->right;
00372     if (node != (NodeInfo *) NULL)
00373       {
00374         while (node->left != (NodeInfo *) NULL)
00375           node=node->left;
00376         next=(NodeInfo *) node->key;
00377       }
00378   }
00379   UnlockSemaphoreInfo(splay_tree->semaphore);
00380   return(clone_tree);
00381 }
00382 
00383 /*
00384 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00385 %                                                                             %
00386 %                                                                             %
00387 %                                                                             %
00388 %   C o m p a r e S p l a y T r e e S t r i n g                               %
00389 %                                                                             %
00390 %                                                                             %
00391 %                                                                             %
00392 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00393 %
00394 %  CompareSplayTreeString() method finds a node in a splay-tree based on the
00395 %  contents of a string.
00396 %
00397 %  The format of the CompareSplayTreeString method is:
00398 %
00399 %      int CompareSplayTreeString(const void *target,const void *source)
00400 %
00401 %  A description of each parameter follows:
00402 %
00403 %    o target: The target string.
00404 %
00405 %    o source: The source string.
00406 %
00407 */
00408 WizardExport int CompareSplayTreeString(const void *target,const void *source)
00409 {
00410   const char
00411     *p,
00412     *q;
00413 
00414   p=(const char *) target;
00415   q=(const char *) source;
00416   return(LocaleCompare(p,q));
00417 }
00418 
00419 /*
00420 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00421 %                                                                             %
00422 %                                                                             %
00423 %                                                                             %
00424 %   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                       %
00425 %                                                                             %
00426 %                                                                             %
00427 %                                                                             %
00428 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00429 %
00430 %  CompareSplayTreeStringInfo() finds a node in a splay-tree based on the
00431 %  contents of a string.
00432 %
00433 %  The format of the CompareSplayTreeStringInfo method is:
00434 %
00435 %      int CompareSplayTreeStringInfo(const void *target,const void *source)
00436 %
00437 %  A description of each parameter follows:
00438 %
00439 %    o target: The target string.
00440 %
00441 %    o source: The source string.
00442 %
00443 */
00444 WizardExport int CompareSplayTreeStringInfo(const void *target,
00445   const void *source)
00446 {
00447   const StringInfo
00448     *p,
00449     *q;
00450 
00451   p=(const StringInfo *) target;
00452   q=(const StringInfo *) source;
00453   return(CompareStringInfo(p,q));
00454 }
00455 
00456 /*
00457 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00458 %                                                                             %
00459 %                                                                             %
00460 %                                                                             %
00461 %   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               %
00462 %                                                                             %
00463 %                                                                             %
00464 %                                                                             %
00465 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00466 %
00467 %  DeleteNodeByValueFromSplayTree() deletes a node by value from the
00468 %  splay-tree.
00469 %
00470 %  The format of the DeleteNodeByValueFromSplayTree method is:
00471 %
00472 %      WizardBooleanType DeleteNodeByValueFromSplayTree(
00473 %        SplayTreeInfo *splay_tree,const void *value)
00474 %
00475 %  A description of each parameter follows:
00476 %
00477 %    o splay_tree: The splay-tree info.
00478 %
00479 %    o value: The value.
00480 %
00481 */
00482 WizardExport WizardBooleanType DeleteNodeByValueFromSplayTree(
00483   SplayTreeInfo *splay_tree,const void *value)
00484 {
00485   register NodeInfo
00486     *next,
00487     *node;
00488 
00489   WizardAssert(ResourceDomain,splay_tree != (SplayTreeInfo *) NULL);
00490   WizardAssert(ResourceDomain,splay_tree->signature == WizardSignature);
00491   if (splay_tree->debug != WizardFalse)
00492     (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00493   LockSemaphoreInfo(splay_tree->semaphore);
00494   if (splay_tree->root == (NodeInfo *) NULL)
00495     {
00496       UnlockSemaphoreInfo(splay_tree->semaphore);
00497       return(WizardFalse);
00498     }
00499   next=(NodeInfo *) GetFirstSplayTreeNode(splay_tree);
00500   while (next != (NodeInfo *) NULL)
00501   {
00502     SplaySplayTree(splay_tree,next);
00503     next=(NodeInfo *) NULL;
00504     node=splay_tree->root->right;
00505     if (node != (NodeInfo *) NULL)
00506       {
00507         while (node->left != (NodeInfo *) NULL)
00508           node=node->left;
00509         next=(NodeInfo *) node->key;
00510       }
00511     if (splay_tree->root->value == value)
00512       {
00513         int
00514           compare;
00515 
00516         register NodeInfo
00517           *left,
00518           *right;
00519 
00520         void
00521           *key;
00522 
00523         /*
00524           We found the node that matches the value; now delete it.
00525         */
00526         key=splay_tree->root->key;
00527         SplaySplayTree(splay_tree,key);
00528         splay_tree->key=(void *) NULL;
00529         if (splay_tree->compare != (int (*)(const void *,const void *)) NULL)
00530           compare=splay_tree->compare(splay_tree->root->key,key);
00531         else
00532           compare=(splay_tree->root->key > key) ? 1 :
00533             ((splay_tree->root->key < key) ? -1 : 0);
00534         if (compare != 0)
00535           {
00536             UnlockSemaphoreInfo(splay_tree->semaphore);
00537             return(WizardFalse);
00538           }
00539         left=splay_tree->root->left;
00540         right=splay_tree->root->right;
00541         if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
00542             (splay_tree->root->key != (void *) NULL))
00543           splay_tree->root->key=splay_tree->relinquish_key(
00544             splay_tree->root->key);
00545         if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
00546             (splay_tree->root->value != (void *) NULL))
00547           splay_tree->root->value=splay_tree->relinquish_value(
00548             splay_tree->root->value);
00549         splay_tree->root=(NodeInfo *) RelinquishWizardMemory(splay_tree->root);
00550         splay_tree->nodes--;
00551         if (left == (NodeInfo *) NULL)
00552           {
00553             splay_tree->root=right;
00554             UnlockSemaphoreInfo(splay_tree->semaphore);
00555             return(WizardTrue);
00556           }
00557         splay_tree->root=left;
00558         if (right != (NodeInfo *) NULL)
00559           {
00560             while (left->right != (NodeInfo *) NULL)
00561               left=left->right;
00562             left->right=right;
00563           }
00564         UnlockSemaphoreInfo(splay_tree->semaphore);
00565         return(WizardTrue);
00566       }
00567   }
00568   UnlockSemaphoreInfo(splay_tree->semaphore);
00569   return(WizardFalse);
00570 }
00571 
00572 /*
00573 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00574 %                                                                             %
00575 %                                                                             %
00576 %                                                                             %
00577 %   D e l e t e N o d e F r o m S p l a y T r e e                             %
00578 %                                                                             %
00579 %                                                                             %
00580 %                                                                             %
00581 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00582 %
00583 %  DeleteNodeFromSplayTree() deletes a node from the splay-tree.
00584 %
00585 %  The format of the DeleteNodeFromSplayTree method is:
00586 %
00587 %      WizardBooleanType DeleteNodeFromSplayTree(SplayTreeInfo *splay_tree,
00588 %        const void *key)
00589 %
00590 %  A description of each parameter follows:
00591 %
00592 %    o splay_tree: The splay-tree info.
00593 %
00594 %    o key: The key.
00595 %
00596 */
00597 WizardExport WizardBooleanType DeleteNodeFromSplayTree(
00598   SplayTreeInfo *splay_tree,const void *key)
00599 {
00600   int
00601     compare;
00602 
00603   register NodeInfo
00604     *left,
00605     *right;
00606 
00607   WizardAssert(ResourceDomain,splay_tree != (SplayTreeInfo *) NULL);
00608   WizardAssert(ResourceDomain,splay_tree->signature == WizardSignature);
00609   if (splay_tree->debug != WizardFalse)
00610     (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00611   if (splay_tree->root == (NodeInfo *) NULL)
00612     return(WizardFalse);
00613   LockSemaphoreInfo(splay_tree->semaphore);
00614   SplaySplayTree(splay_tree,key);
00615   splay_tree->key=(void *) NULL;
00616   if (splay_tree->compare != (int (*)(const void *,const void *)) NULL)
00617     compare=splay_tree->compare(splay_tree->root->key,key);
00618   else
00619     compare=(splay_tree->root->key > key) ? 1 :
00620       ((splay_tree->root->key < key) ? -1 : 0);
00621   if (compare != 0)
00622     {
00623       UnlockSemaphoreInfo(splay_tree->semaphore);
00624       return(WizardFalse);
00625     }
00626   left=splay_tree->root->left;
00627   right=splay_tree->root->right;
00628   if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
00629       (splay_tree->root->value != (void *) NULL))
00630     splay_tree->root->value=splay_tree->relinquish_value(
00631       splay_tree->root->value);
00632   if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
00633       (splay_tree->root->key != (void *) NULL))
00634     splay_tree->root->key=splay_tree->relinquish_key(splay_tree->root->key);
00635   splay_tree->root=(NodeInfo *) RelinquishWizardMemory(splay_tree->root);
00636   splay_tree->nodes--;
00637   if (left == (NodeInfo *) NULL)
00638     {
00639       splay_tree->root=right;
00640       UnlockSemaphoreInfo(splay_tree->semaphore);
00641       return(WizardTrue);
00642     }
00643   splay_tree->root=left;
00644   if (right != (NodeInfo *) NULL)
00645     {
00646       while (left->right != (NodeInfo *) NULL)
00647         left=left->right;
00648       left->right=right;
00649     }
00650   UnlockSemaphoreInfo(splay_tree->semaphore);
00651   return(WizardTrue);
00652 }
00653 
00654 /*
00655 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00656 %                                                                             %
00657 %                                                                             %
00658 %                                                                             %
00659 %   D e s t r o y S p l a y T r e e                                           %
00660 %                                                                             %
00661 %                                                                             %
00662 %                                                                             %
00663 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00664 %
00665 %  DestroySplayTree() destroys the splay-tree.
00666 %
00667 %  The format of the DestroySplayTree method is:
00668 %
00669 %      SplayTreeInfo *DestroySplayTree(SplayTreeInfo *splay_tree)
00670 %
00671 %  A description of each parameter follows:
00672 %
00673 %    o splay_tree: The splay tree.
00674 %
00675 */
00676 WizardExport SplayTreeInfo *DestroySplayTree(SplayTreeInfo *splay_tree)
00677 {
00678   NodeInfo
00679     *node;
00680 
00681   register NodeInfo
00682     *active,
00683     *pend;
00684 
00685   LockSemaphoreInfo(splay_tree->semaphore);
00686   if (splay_tree->root != (NodeInfo *) NULL)
00687     {
00688       if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
00689           (splay_tree->root->key != (void *) NULL))
00690         splay_tree->root->key=splay_tree->relinquish_key(splay_tree->root->key);
00691       splay_tree->root->key=(void *) NULL;
00692       if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
00693           (splay_tree->root->value != (void *) NULL))
00694         splay_tree->root->value=splay_tree->relinquish_value(
00695           splay_tree->root->value);
00696       for (pend=splay_tree->root; pend != (NodeInfo *) NULL; )
00697       {
00698         active=pend;
00699         for (pend=(NodeInfo *) NULL; active != (NodeInfo *) NULL; )
00700         {
00701           if (active->left != (NodeInfo *) NULL)
00702             {
00703               if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
00704                   (active->left->key != (void *) NULL))
00705                 active->left->key=splay_tree->relinquish_key(active->left->key);
00706               active->left->key=(void *) pend;
00707               if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
00708                   (active->left->value != (void *) NULL))
00709                 active->left->value=splay_tree->relinquish_value(
00710                   active->left->value);
00711               pend=active->left;
00712             }
00713           if (active->right != (NodeInfo *) NULL)
00714             {
00715               if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
00716                   (active->right->key != (void *) NULL))
00717                 active->right->key=splay_tree->relinquish_key(
00718                   active->right->key);
00719               active->right->key=(void *) pend;
00720               if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
00721                   (active->right->value != (void *) NULL))
00722                 active->right->value=splay_tree->relinquish_value(
00723                   active->right->value);
00724               pend=active->right;
00725             }
00726           node=active;
00727           active=(NodeInfo *) node->key;
00728           node=(NodeInfo *) RelinquishWizardMemory(node);
00729         }
00730       }
00731     }
00732   splay_tree->signature=(~WizardSignature);
00733   UnlockSemaphoreInfo(splay_tree->semaphore);
00734   DestroySemaphoreInfo(&splay_tree->semaphore);
00735   splay_tree=(SplayTreeInfo *) RelinquishWizardMemory(splay_tree);
00736   return(splay_tree);
00737 }
00738 
00739 /*
00740 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00741 %                                                                             %
00742 %                                                                             %
00743 %                                                                             %
00744 %   G e t N e x t K e y I n S p l a y T r e e                                 %
00745 %                                                                             %
00746 %                                                                             %
00747 %                                                                             %
00748 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00749 %
00750 %  GetNextKeyInSplayTree() gets the next key in the splay-tree.
00751 %
00752 %  The format of the GetNextKeyInSplayTree method is:
00753 %
00754 %      const void *GetNextKeyInSplayTree(SplayTreeInfo *splay_tree)
00755 %
00756 %  A description of each parameter follows:
00757 %
00758 %    o splay_tree: The splay tree.
00759 %
00760 %    o key: The key.
00761 %
00762 */
00763 WizardExport const void *GetNextKeyInSplayTree(SplayTreeInfo *splay_tree)
00764 {
00765   register NodeInfo
00766     *node;
00767 
00768   void
00769     *key;
00770 
00771   WizardAssert(ResourceDomain,splay_tree != (SplayTreeInfo *) NULL);
00772   WizardAssert(ResourceDomain,splay_tree->signature == WizardSignature);
00773   if (splay_tree->debug != WizardFalse)
00774     (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00775   if ((splay_tree->root == (NodeInfo *) NULL) ||
00776       (splay_tree->next == (void *) NULL))
00777     return((void *) NULL);
00778   LockSemaphoreInfo(splay_tree->semaphore);
00779   SplaySplayTree(splay_tree,splay_tree->next);
00780   splay_tree->next=(void *) NULL;
00781   node=splay_tree->root->right;
00782   if (node != (NodeInfo *) NULL)
00783     {
00784       while (node->left != (NodeInfo *) NULL)
00785         node=node->left;
00786       splay_tree->next=node->key;
00787     }
00788   key=splay_tree->root->key;
00789   UnlockSemaphoreInfo(splay_tree->semaphore);
00790   return(key);
00791 }
00792 
00793 /*
00794 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00795 %                                                                             %
00796 %                                                                             %
00797 %                                                                             %
00798 %   G e t N e x t V a l u e I n S p l a y T r e e                             %
00799 %                                                                             %
00800 %                                                                             %
00801 %                                                                             %
00802 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00803 %
00804 %  GetNextValueInSplayTree() gets the next value in the splay-tree.
00805 %
00806 %  The format of the GetNextValueInSplayTree method is:
00807 %
00808 %      const void *GetNextValueInSplayTree(SplayTreeInfo *splay_tree)
00809 %
00810 %  A description of each parameter follows:
00811 %
00812 %    o splay_tree: The splay tree.
00813 %
00814 %    o key: The key.
00815 %
00816 */
00817 WizardExport const void *GetNextValueInSplayTree(SplayTreeInfo *splay_tree)
00818 {
00819   register NodeInfo
00820     *node;
00821 
00822   void
00823     *value;
00824 
00825   WizardAssert(ResourceDomain,splay_tree != (SplayTreeInfo *) NULL);
00826   WizardAssert(ResourceDomain,splay_tree->signature == WizardSignature);
00827   if (splay_tree->debug != WizardFalse)
00828     (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00829   if ((splay_tree->root == (NodeInfo *) NULL) ||
00830       (splay_tree->next == (void *) NULL))
00831     return((void *) NULL);
00832   LockSemaphoreInfo(splay_tree->semaphore);
00833   SplaySplayTree(splay_tree,splay_tree->next);
00834   splay_tree->next=(void *) NULL;
00835   node=splay_tree->root->right;
00836   if (node != (NodeInfo *) NULL)
00837     {
00838       while (node->left != (NodeInfo *) NULL)
00839         node=node->left;
00840       splay_tree->next=node->key;
00841     }
00842   value=splay_tree->root->value;
00843   UnlockSemaphoreInfo(splay_tree->semaphore);
00844   return(value);
00845 }
00846 
00847 /*
00848 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00849 %                                                                             %
00850 %                                                                             %
00851 %                                                                             %
00852 %   G e t V a l u e F r o m S p l a y T r e e                                 %
00853 %                                                                             %
00854 %                                                                             %
00855 %                                                                             %
00856 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00857 %
00858 %  GetValueFromSplayTree() gets a value from the splay-tree by its key.
00859 %
00860 %  The format of the GetValueFromSplayTree method is:
00861 %
00862 %      const void *GetValueFromSplayTree(SplayTreeInfo *splay_tree,
00863 %        const void *key)
00864 %
00865 %  A description of each parameter follows:
00866 %
00867 %    o splay_tree: The splay tree.
00868 %
00869 %    o key: The key.
00870 %
00871 */
00872 WizardExport const void *GetValueFromSplayTree(SplayTreeInfo *splay_tree,
00873   const void *key)
00874 {
00875   int
00876     compare;
00877 
00878   void
00879     *value;
00880 
00881   WizardAssert(ResourceDomain,splay_tree != (SplayTreeInfo *) NULL);
00882   WizardAssert(ResourceDomain,splay_tree->signature == WizardSignature);
00883   if (splay_tree->debug != WizardFalse)
00884     (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00885   if (splay_tree->root == (NodeInfo *) NULL)
00886     return((void *) NULL);
00887   LockSemaphoreInfo(splay_tree->semaphore);
00888   SplaySplayTree(splay_tree,key);
00889   if (splay_tree->compare != (int (*)(const void *,const void *)) NULL)
00890     compare=splay_tree->compare(splay_tree->root->key,key);
00891   else
00892     compare=(splay_tree->root->key > key) ? 1 :
00893       ((splay_tree->root->key < key) ? -1 : 0);
00894   if (compare != 0)
00895     {
00896       UnlockSemaphoreInfo(splay_tree->semaphore);
00897       return((void *) NULL);
00898     }
00899   value=splay_tree->root->value;
00900   UnlockSemaphoreInfo(splay_tree->semaphore);
00901   return(value);
00902 }
00903 
00904 /*
00905 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00906 %                                                                             %
00907 %                                                                             %
00908 %                                                                             %
00909 %   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                     %
00910 %                                                                             %
00911 %                                                                             %
00912 %                                                                             %
00913 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00914 %
00915 %  GetNumberOfNodesInSplayTree() returns the number of nodes in the splay-tree.
00916 %
00917 %  The format of the GetNumberOfNodesInSplayTree method is:
00918 %
00919 %      size_t GetNumberOfNodesInSplayTree(
00920 %        const SplayTreeInfo *splay_tree)
00921 %
00922 %  A description of each parameter follows:
00923 %
00924 %    o splay_tree: The splay tree.
00925 %
00926 */
00927 WizardExport size_t GetNumberOfNodesInSplayTree(
00928   const SplayTreeInfo *splay_tree)
00929 {
00930   WizardAssert(ResourceDomain,splay_tree != (SplayTreeInfo *) NULL);
00931   WizardAssert(ResourceDomain,splay_tree->signature == WizardSignature);
00932   if (splay_tree->debug != WizardFalse)
00933     (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00934   return(splay_tree->nodes);
00935 }
00936 
00937 /*
00938 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00939 %                                                                             %
00940 %                                                                             %
00941 %                                                                             %
00942 %   I t e r a t e O v e r S p l a y T r e e                                   %
00943 %                                                                             %
00944 %                                                                             %
00945 %                                                                             %
00946 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00947 %
00948 %  IterateOverSplayTree() iterates over the splay-tree.
00949 %
00950 %  The format of the IterateOverSplayTree method is:
00951 %
00952 %      int IterateOverSplayTree(SplayTreeInfo *splay_tree,
00953 %        int (*method)(NodeInfo *,void *),const void *value)
00954 %
00955 %  A description of each parameter follows:
00956 %
00957 %    o splay_tree: The splay-tree info.
00958 %
00959 %    o method: The method.
00960 %
00961 %    o value: The value.
00962 %
00963 */
00964 static int IterateOverSplayTree(SplayTreeInfo *splay_tree,
00965   int (*method)(NodeInfo *,const void *),const void *value)
00966 {
00967   typedef enum
00968   {
00969     LeftTransition,
00970     RightTransition,
00971     DownTransition,
00972     UpTransition
00973   } TransitionType;
00974 
00975   int
00976     status;
00977 
00978   WizardBooleanType
00979     final_transition;
00980 
00981   NodeInfo
00982     **nodes;
00983 
00984   register ssize_t
00985     i;
00986 
00987   register NodeInfo
00988     *node;
00989 
00990   TransitionType
00991     transition;
00992 
00993   unsigned char
00994     *transitions;
00995 
00996   if (splay_tree->root == (NodeInfo *) NULL)
00997     return(0);
00998   nodes=(NodeInfo **) AcquireQuantumMemory((size_t) splay_tree->nodes,
00999     sizeof(*nodes));
01000   transitions=(unsigned char *) AcquireQuantumMemory((size_t) splay_tree->nodes,
01001     sizeof(*transitions));
01002   if ((nodes == (NodeInfo **) NULL) || (transitions == (unsigned char *) NULL))
01003     ThrowWizardFatalError(CacheDomain,MemoryError);
01004   status=0;
01005   final_transition=WizardFalse;
01006   nodes[0]=splay_tree->root;
01007   transitions[0]=(unsigned char) LeftTransition;
01008   for (i=0; final_transition == WizardFalse; )
01009   {
01010     node=nodes[i];
01011     transition=(TransitionType) transitions[i];
01012     switch (transition)
01013     {
01014       case LeftTransition:
01015       {
01016         transitions[i]=(unsigned char) DownTransition;
01017         if (node->left == (NodeInfo *) NULL)
01018           break;
01019         i++;
01020         nodes[i]=node->left;
01021         transitions[i]=(unsigned char) LeftTransition;
01022         break;
01023       }
01024       case RightTransition:
01025       {
01026         transitions[i]=(unsigned char) UpTransition;
01027         if (node->right == (NodeInfo *) NULL)
01028           break;
01029         i++;
01030         nodes[i]=node->right;
01031         transitions[i]=(unsigned char) LeftTransition;
01032         break;
01033       }
01034       case DownTransition:
01035       default:
01036       {
01037         transitions[i]=(unsigned char) RightTransition;
01038         status=(*method)(node,value);
01039         if (status != 0)
01040           final_transition=WizardTrue;
01041         break;
01042       }
01043       case UpTransition:
01044       {
01045         if (i == 0)
01046           {
01047             final_transition=WizardTrue;
01048             break;
01049           }
01050         i--;
01051         break;
01052       }
01053     }
01054   }
01055   nodes=(NodeInfo **) RelinquishWizardMemory(nodes);
01056   transitions=(unsigned char *) RelinquishWizardMemory(transitions);
01057   return(status);
01058 }
01059 
01060 /*
01061 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01062 %                                                                             %
01063 %                                                                             %
01064 %                                                                             %
01065 %   N e w S p l a y T r e e                                                   %
01066 %                                                                             %
01067 %                                                                             %
01068 %                                                                             %
01069 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01070 %
01071 %  NewSplayTree() returns a pointer to a SplayTreeInfo structure initialized
01072 %  to default values.
01073 %
01074 %  The format of the NewSplayTree method is:
01075 %
01076 %      SplayTreeInfo *NewSplayTree(int (*compare)(const void *,const void *),
01077 %        void *(*relinquish_key)(void *),void *(*relinquish_value)(void *))
01078 %
01079 %  A description of each parameter follows:
01080 %
01081 %    o compare: The compare method.
01082 %
01083 %    o relinquish_key: The key deallocation method, typically
01084 %      RelinquishWizardMemory(), called whenever a key is removed from the
01085 %      splay-tree.
01086 %
01087 %    o relinquish_value: The value deallocation method;  typically
01088 %      RelinquishWizardMemory(), called whenever a value object is removed from
01089 %      the splay-tree.
01090 %
01091 */
01092 WizardExport SplayTreeInfo *NewSplayTree(
01093   int (*compare)(const void *,const void *),void *(*relinquish_key)(void *),
01094   void *(*relinquish_value)(void *))
01095 {
01096   SplayTreeInfo
01097     *splay_tree;
01098 
01099   splay_tree=(SplayTreeInfo *) AcquireAlignedMemory(1,sizeof(*splay_tree));
01100   if (splay_tree == (SplayTreeInfo *) NULL)
01101     ThrowWizardFatalError(CacheDomain,MemoryError);
01102   (void) ResetWizardMemory(splay_tree,0,sizeof(*splay_tree));
01103   splay_tree->root=(NodeInfo *) NULL;
01104   splay_tree->compare=compare;
01105   splay_tree->relinquish_key=relinquish_key;
01106   splay_tree->relinquish_value=relinquish_value;
01107   splay_tree->balance=WizardFalse;
01108   splay_tree->key=(void *) NULL;
01109   splay_tree->next=(void *) NULL;
01110   splay_tree->nodes=0;
01111   splay_tree->debug=IsEventLogging();
01112   splay_tree->semaphore=AllocateSemaphoreInfo();
01113   splay_tree->signature=WizardSignature;
01114   return(splay_tree);
01115 }
01116 
01117 /*
01118 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01119 %                                                                             %
01120 %                                                                             %
01121 %                                                                             %
01122 %   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               %
01123 %                                                                             %
01124 %                                                                             %
01125 %                                                                             %
01126 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01127 %
01128 %  RemoveNodeByValueFromSplayTree() removes a node by value from the splay-tree
01129 %  and returns its key.
01130 %
01131 %  The format of the RemoveNodeByValueFromSplayTree method is:
01132 %
01133 %      void *RemoveNodeByValueFromSplayTree(SplayTreeInfo *splay_tree,
01134 %        const void *value)
01135 %
01136 %  A description of each parameter follows:
01137 %
01138 %    o splay_tree: The splay-tree info.
01139 %
01140 %    o value: The value.
01141 %
01142 */
01143 WizardExport void *RemoveNodeByValueFromSplayTree(SplayTreeInfo *splay_tree,
01144   const void *value)
01145 {
01146   register NodeInfo
01147     *next,
01148     *node;
01149 
01150   void
01151     *key;
01152 
01153   WizardAssert(ResourceDomain,splay_tree != (SplayTreeInfo *) NULL);
01154   WizardAssert(ResourceDomain,splay_tree->signature == WizardSignature);
01155   if (splay_tree->debug != WizardFalse)
01156     (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
01157   key=(void *) NULL;
01158   if (splay_tree->root == (NodeInfo *) NULL)
01159     return(key);
01160   LockSemaphoreInfo(splay_tree->semaphore);
01161   next=(NodeInfo *) GetFirstSplayTreeNode(splay_tree);
01162   while (next != (NodeInfo *) NULL)
01163   {
01164     SplaySplayTree(splay_tree,next);
01165     next=(NodeInfo *) NULL;
01166     node=splay_tree->root->right;
01167     if (node != (NodeInfo *) NULL)
01168       {
01169         while (node->left != (NodeInfo *) NULL)
01170           node=node->left;
01171         next=(NodeInfo *) node->key;
01172       }
01173     if (splay_tree->root->value == value)
01174       {
01175         int
01176           compare;
01177 
01178         register NodeInfo
01179           *left,
01180           *right;
01181 
01182         /*
01183           We found the node that matches the value; now remove it.
01184         */
01185         key=splay_tree->root->key;
01186         SplaySplayTree(splay_tree,key);
01187         splay_tree->key=(void *) NULL;
01188         if (splay_tree->compare != (int (*)(const void *,const void *)) NULL)
01189           compare=splay_tree->compare(splay_tree->root->key,key);
01190         else
01191           compare=(splay_tree->root->key > key) ? 1 :
01192             ((splay_tree->root->key < key) ? -1 : 0);
01193         if (compare != 0)
01194           {
01195             UnlockSemaphoreInfo(splay_tree->semaphore);
01196             return(key);
01197           }
01198         left=splay_tree->root->left;
01199         right=splay_tree->root->right;
01200         if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
01201             (splay_tree->root->value != (void *) NULL))
01202           splay_tree->root->value=splay_tree->relinquish_value(
01203             splay_tree->root->value);
01204         splay_tree->root=(NodeInfo *) RelinquishWizardMemory(splay_tree->root);
01205         splay_tree->nodes--;
01206         if (left == (NodeInfo *) NULL)
01207           {
01208             splay_tree->root=right;
01209             UnlockSemaphoreInfo(splay_tree->semaphore);
01210             return(key);
01211           }
01212         splay_tree->root=left;
01213         if (right != (NodeInfo *) NULL)
01214           {
01215             while (left->right != (NodeInfo *) NULL)
01216               left=left->right;
01217             left->right=right;
01218           }
01219         UnlockSemaphoreInfo(splay_tree->semaphore);
01220         return(key);
01221       }
01222   }
01223   UnlockSemaphoreInfo(splay_tree->semaphore);
01224   return(key);
01225 }
01226 
01227 /*
01228 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01229 %                                                                             %
01230 %                                                                             %
01231 %                                                                             %
01232 %   R e m o v e N o d e F r o m S p l a y T r e e                             %
01233 %                                                                             %
01234 %                                                                             %
01235 %                                                                             %
01236 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01237 %
01238 %  RemoveNodeFromSplayTree() removes a node from the splay-tree and returns its
01239 %  value.
01240 %
01241 %  The format of the RemoveNodeFromSplayTree method is:
01242 %
01243 %      void *RemoveNodeFromSplayTree(SplayTreeInfo *splay_tree,const void *key)
01244 %
01245 %  A description of each parameter follows:
01246 %
01247 %    o splay_tree: The splay-tree info.
01248 %
01249 %    o key: The key.
01250 %
01251 */
01252 WizardExport void *RemoveNodeFromSplayTree(SplayTreeInfo *splay_tree,
01253   const void *key)
01254 {
01255   int
01256     compare;
01257 
01258   register NodeInfo
01259     *left,
01260     *right;
01261 
01262   void
01263     *value;
01264 
01265   WizardAssert(ResourceDomain,splay_tree != (SplayTreeInfo *) NULL);
01266   WizardAssert(ResourceDomain,splay_tree->signature == WizardSignature);
01267   if (splay_tree->debug != WizardFalse)
01268     (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
01269   value=(void *) NULL;
01270   if (splay_tree->root == (NodeInfo *) NULL)
01271     return(value);
01272   LockSemaphoreInfo(splay_tree->semaphore);
01273   SplaySplayTree(splay_tree,key);
01274   splay_tree->key=(void *) NULL;
01275   if (splay_tree->compare != (int (*)(const void *,const void *)) NULL)
01276     compare=splay_tree->compare(splay_tree->root->key,key);
01277   else
01278     compare=(splay_tree->root->key > key) ? 1 :
01279       ((splay_tree->root->key < key) ? -1 : 0);
01280   if (compare != 0)
01281     {
01282       UnlockSemaphoreInfo(splay_tree->semaphore);
01283       return(value);
01284     }
01285   left=splay_tree->root->left;
01286   right=splay_tree->root->right;
01287   value=splay_tree->root->value;
01288   if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
01289       (splay_tree->root->key != (void *) NULL))
01290     splay_tree->root->key=splay_tree->relinquish_key(splay_tree->root->key);
01291   splay_tree->root=(NodeInfo *) RelinquishWizardMemory(splay_tree->root);
01292   splay_tree->nodes--;
01293   if (left == (NodeInfo *) NULL)
01294     {
01295       splay_tree->root=right;
01296       UnlockSemaphoreInfo(splay_tree->semaphore);
01297       return(value);
01298     }
01299   splay_tree->root=left;
01300   if (right != (NodeInfo *) NULL)
01301     {
01302       while (left->right != (NodeInfo *) NULL)
01303         left=left->right;
01304       left->right=right;
01305     }
01306   UnlockSemaphoreInfo(splay_tree->semaphore);
01307   return(value);
01308 }
01309 
01310 /*
01311 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01312 %                                                                             %
01313 %                                                                             %
01314 %                                                                             %
01315 %   R e s e t S p l a y T r e e                                               %
01316 %                                                                             %
01317 %                                                                             %
01318 %                                                                             %
01319 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01320 %
01321 %  ResetSplayTree() resets the splay-tree.  That is, it deletes all the nodes
01322 %  from the tree.
01323 %
01324 %  The format of the ResetSplayTree method is:
01325 %
01326 %      ResetSplayTree(SplayTreeInfo *splay_tree)
01327 %
01328 %  A description of each parameter follows:
01329 %
01330 %    o splay_tree: the splay tree.
01331 %
01332 */
01333 WizardExport void ResetSplayTree(SplayTreeInfo *splay_tree)
01334 {
01335   NodeInfo
01336     *node;
01337 
01338   register NodeInfo
01339     *active,
01340     *pend;
01341 
01342   WizardAssert(ResourceDomain,splay_tree != (SplayTreeInfo *) NULL);
01343   WizardAssert(ResourceDomain,splay_tree->signature == WizardSignature);
01344   if (splay_tree->debug != WizardFalse)
01345     (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
01346   LockSemaphoreInfo(splay_tree->semaphore);
01347   if (splay_tree->root != (NodeInfo *) NULL)
01348     {
01349       if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
01350           (splay_tree->root->key != (void *) NULL))
01351         splay_tree->root->key=splay_tree->relinquish_key(splay_tree->root->key);
01352       splay_tree->root->key=(void *) NULL;
01353       if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
01354           (splay_tree->root->value != (void *) NULL))
01355         splay_tree->root->value=splay_tree->relinquish_value(
01356           splay_tree->root->value);
01357       for (pend=splay_tree->root; pend != (NodeInfo *) NULL; )
01358       {
01359         active=pend;
01360         for (pend=(NodeInfo *) NULL; active != (NodeInfo *) NULL; )
01361         {
01362           if (active->left != (NodeInfo *) NULL)
01363             {
01364               if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
01365                   (active->left->key != (void *) NULL))
01366                 active->left->key=splay_tree->relinquish_key(active->left->key);
01367               active->left->key=(void *) pend;
01368               if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
01369                   (active->left->value != (void *) NULL))
01370                 active->left->value=splay_tree->relinquish_value(
01371                   active->left->value);
01372               pend=active->left;
01373             }
01374           if (active->right != (NodeInfo *) NULL)
01375             {
01376               if ((splay_tree->relinquish_key != (void *(*)(void *)) NULL) &&
01377                   (active->right->key != (void *) NULL))
01378                 active->right->key=splay_tree->relinquish_key(
01379                   active->right->key);
01380               active->right->key=(void *) pend;
01381               if ((splay_tree->relinquish_value != (void *(*)(void *)) NULL) &&
01382                   (active->right->value != (void *) NULL))
01383                 active->right->value=splay_tree->relinquish_value(
01384                   active->right->value);
01385               pend=active->right;
01386             }
01387           node=active;
01388           active=(NodeInfo *) node->key;
01389           node=(NodeInfo *) RelinquishWizardMemory(node);
01390         }
01391       }
01392     }
01393   splay_tree->root=(NodeInfo *) NULL;
01394   splay_tree->key=(void *) NULL;
01395   splay_tree->next=(void *) NULL;
01396   splay_tree->nodes=0;
01397   splay_tree->balance=WizardFalse;
01398   UnlockSemaphoreInfo(splay_tree->semaphore);
01399 }
01400 
01401 /*
01402 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01403 %                                                                             %
01404 %                                                                             %
01405 %                                                                             %
01406 %   R e s e t S p l a y T r e e I t e r a t o r                               %
01407 %                                                                             %
01408 %                                                                             %
01409 %                                                                             %
01410 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01411 %
01412 %  ResetSplayTreeIterator() resets the splay-tree iterator.  Use it in
01413 %  conjunction with GetNextValueInSplayTree() to iterate over all the nodes in
01414 %  the splay-tree.
01415 %
01416 %  The format of the ResetSplayTreeIterator method is:
01417 %
01418 %      ResetSplayTreeIterator(SplayTreeInfo *splay_tree)
01419 %
01420 %  A description of each parameter follows:
01421 %
01422 %    o splay_tree: The splay tree.
01423 %
01424 */
01425 WizardExport void ResetSplayTreeIterator(SplayTreeInfo *splay_tree)
01426 {
01427   WizardAssert(ResourceDomain,splay_tree != (SplayTreeInfo *) NULL);
01428   WizardAssert(ResourceDomain,splay_tree->signature == WizardSignature);
01429   if (splay_tree->debug != WizardFalse)
01430     (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
01431   LockSemaphoreInfo(splay_tree->semaphore);
01432   splay_tree->next=GetFirstSplayTreeNode(splay_tree);
01433   UnlockSemaphoreInfo(splay_tree->semaphore);
01434 }
01435 
01436 /*
01437 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01438 %                                                                             %
01439 %                                                                             %
01440 %                                                                             %
01441 %   S p l a y S p l a y T r e e                                               %
01442 %                                                                             %
01443 %                                                                             %
01444 %                                                                             %
01445 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01446 %
01447 %  SplaySplayTree() splays the splay-tree.
01448 %
01449 %  The format of the SplaySplayTree method is:
01450 %
01451 %      void SplaySplayTree(SplayTreeInfo *splay_tree,const void *key,
01452 %        NodeInfo **node,NodeInfo **parent,NodeInfo **grandparent)
01453 %
01454 %  A description of each parameter follows:
01455 %
01456 %    o splay_tree: The splay-tree info.
01457 %
01458 %    o key: The key.
01459 %
01460 %    o node: The node.
01461 %
01462 %    o parent: The parent node.
01463 %
01464 %    o grandparent: The grandparent node.
01465 %
01466 */
01467 
01468 static NodeInfo *Splay(SplayTreeInfo *splay_tree,const size_t depth,
01469   const void *key,NodeInfo **node,NodeInfo **parent,NodeInfo **grandparent)
01470 {
01471   int
01472     compare;
01473 
01474   NodeInfo
01475     **next;
01476 
01477   register NodeInfo
01478     *n,
01479     *p;
01480 
01481   n=(*node);
01482   if (n == (NodeInfo *) NULL)
01483     return(*parent);
01484   if (splay_tree->compare != (int (*)(const void *,const void *)) NULL)
01485     compare=splay_tree->compare(n->key,key);
01486   else
01487     compare=(n->key > key) ? 1 : ((n->key < key) ? -1 : 0);
01488   next=(NodeInfo **) NULL;
01489   if (compare > 0)
01490     next=(&n->left);
01491   else
01492     if (compare < 0)
01493       next=(&n->right);
01494   if (next != (NodeInfo **) NULL)
01495     {
01496       if (depth >= MaxSplayTreeDepth)
01497         {
01498           splay_tree->balance=WizardTrue;
01499           return(n);
01500         }
01501       n=Splay(splay_tree,depth+1,key,next,node,parent);
01502       if ((n != *node) || (splay_tree->balance != WizardFalse))
01503         return(n);
01504     }
01505   if (parent == (NodeInfo **) NULL)
01506     return(n);
01507   if (grandparent == (NodeInfo **) NULL)
01508     {
01509       if (n == (*parent)->left)
01510         {
01511           *node=n->right;
01512           n->right=(*parent);
01513         }
01514       else
01515         {
01516           *node=n->left;
01517           n->left=(*parent);
01518         }
01519       *parent=n;
01520       return(n);
01521     }
01522   if ((n == (*parent)->left) && (*parent == (*grandparent)->left))
01523     {
01524       p=(*parent);
01525       (*grandparent)->left=p->right;
01526       p->right=(*grandparent);
01527       p->left=n->right;
01528       n->right=p;
01529       *grandparent=n;
01530       return(n);
01531     }
01532   if ((n == (*parent)->right) && (*parent == (*grandparent)->right))
01533     {
01534       p=(*parent);
01535       (*grandparent)->right=p->left;
01536       p->left=(*grandparent);
01537       p->right=n->left;
01538       n->left=p;
01539       *grandparent=n;
01540       return(n);
01541     }
01542   if (n == (*parent)->left)
01543     {
01544       (*parent)->left=n->right;
01545       n->right=(*parent);
01546       (*grandparent)->right=n->left;
01547       n->left=(*grandparent);
01548       *grandparent=n;
01549       return(n);
01550     }
01551   (*parent)->right=n->left;
01552   n->left=(*parent);
01553   (*grandparent)->left=n->right;
01554   n->right=(*grandparent);
01555   *grandparent=n;
01556   return(n);
01557 }
01558 
01559 static void SplaySplayTree(SplayTreeInfo *splay_tree,const void *key)
01560 {
01561   if (splay_tree->root == (NodeInfo *) NULL)
01562     return;
01563   if (splay_tree->key != (void *) NULL)
01564     {
01565       int
01566         compare;
01567 
01568       if (splay_tree->compare != (int (*)(const void *,const void *)) NULL)
01569         compare=splay_tree->compare(splay_tree->root->key,key);
01570       else
01571         compare=(splay_tree->key > key) ? 1 :
01572           ((splay_tree->key < key) ? -1 : 0);
01573       if (compare == 0)
01574         return;
01575     }
01576   (void) Splay(splay_tree,0UL,key,&splay_tree->root,(NodeInfo **) NULL,
01577     (NodeInfo **) NULL);
01578   if (splay_tree->balance != WizardFalse)
01579     {
01580       BalanceSplayTree(splay_tree);
01581       (void) Splay(splay_tree,0UL,key,&splay_tree->root,(NodeInfo **) NULL,
01582         (NodeInfo **) NULL);
01583       if (splay_tree->balance != WizardFalse)
01584         ThrowWizardFatalError(CacheDomain,MemoryError);
01585     }
01586   splay_tree->key=(void *) key;
01587 }
Generated by  doxygen 1.6.2-20100208