WizardsToolkit  1.0.7
hashmap.c
Go to the documentation of this file.
00001 /*
00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00003 %                                                                             %
00004 %                                                                             %
00005 %                                                                             %
00006 %                H   H   AAA   SSSSS  H   H  M   M   AAA   PPPP               %
00007 %                H   H  A   A  SS     H   H  MM MM  A   A  P   P              %
00008 %                HHHHH  AAAAA   SSS   HHHHH  M M M  AAAAA  PPPP               %
00009 %                H   H  A   A     SS  H   H  M   M  A   A  P                  %
00010 %                H   H  A   A  SSSSS  H   H  M   M  A   A  P                  %
00011 %                                                                             %
00012 %                                                                             %
00013 %                Wizard's Toolkit Hash-map and Linked-list Methods            %
00014 %                                                                             %
00015 %                              Software Design                                %
00016 %                                John Cristy                                  %
00017 %                               December 2002                                 %
00018 %                                                                             %
00019 %                                                                             %
00020 %  Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization      %
00021 %  dedicated to making software imaging solutions freely available.           %
00022 %                                                                             %
00023 %  You may not use this file except in compliance with the License.  You may  %
00024 %  obtain a copy of the License at                                            %
00025 %                                                                             %
00026 %    http://www.wizards-toolkit.org/script/license.php                        %
00027 %                                                                             %
00028 %  Unless required by applicable law or agreed to in writing, software        %
00029 %  distributed under the License is distributed on an "AS IS" BASIS,          %
00030 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
00031 %  See the License for the specific language governing permissions and        %
00032 %  limitations under the License.                                             %
00033 %                                                                             %
00034 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00035 %
00036 %  This module implements the standard handy hash and linked-list methods for
00037 %  storing and retrieving large numbers of data elements.  It is loosely based
00038 %  on the Java implementation of these algorithms.
00039 %
00040 */
00041 
00042 /*
00043   Increde declarations.
00044 */
00045 #include "wizard/studio.h"
00046 #include "wizard/exception.h"
00047 #include "wizard/exception-private.h"
00048 #include "wizard/hash.h"
00049 #include "wizard/hashmap.h"
00050 #include "wizard/memory_.h"
00051 #include "wizard/semaphore.h"
00052 #include "wizard/string_.h"
00053 
00054 /*
00055   Typedef declarations.
00056 */
00057 typedef struct _ElementInfo
00058 {
00059   void
00060     *value;
00061 
00062   struct _ElementInfo
00063     *next;
00064 } ElementInfo;
00065 
00066 typedef struct _EntryInfo
00067 {
00068   size_t
00069     hash;
00070 
00071   void
00072     *key,
00073     *value;
00074 } EntryInfo;
00075 
00076 struct _LinkedListInfo
00077 {
00078   size_t
00079     capacity,
00080     elements;
00081 
00082   ElementInfo
00083     *head,
00084     *tail,
00085     *next;
00086 
00087   WizardBooleanType
00088     debug;
00089 
00090   SemaphoreInfo
00091     *semaphore;
00092 
00093   size_t
00094     signature;
00095 };
00096 
00097 struct _HashmapInfo
00098 {
00099   size_t
00100     (*hash)(const void *);
00101 
00102   WizardBooleanType
00103     (*compare)(const void *,const void *);
00104 
00105   void
00106     *(*relinquish_key)(void *),
00107     *(*relinquish_value)(void *);
00108 
00109   size_t
00110     capacity,
00111     entries,
00112     next;
00113 
00114   WizardBooleanType
00115     head_of_list;
00116 
00117   LinkedListInfo
00118     **map;
00119 
00120   WizardBooleanType
00121     debug;
00122 
00123   SemaphoreInfo
00124     *semaphore;
00125 
00126   size_t
00127     signature;
00128 };
00129 
00130 /*
00131 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00132 %                                                                             %
00133 %                                                                             %
00134 %                                                                             %
00135 %   A p p e n d V a l u e T o L i n k e d L i s t                             %
00136 %                                                                             %
00137 %                                                                             %
00138 %                                                                             %
00139 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00140 %
00141 %  AppendValueToLinkedList() appends a value to the end of the linked-list.
00142 %
00143 %  The format of the AppendValueToLinkedList method is:
00144 %
00145 %      WizardBooleanType AppendValueToLinkedList(LinkedListInfo *list_info,
00146 %        const void *value)
00147 %
00148 %  A description of each parameter follows:
00149 %
00150 %    o list_info: The linked-list info.
00151 %
00152 %    o value: The value.
00153 %
00154 */
00155 WizardExport WizardBooleanType AppendValueToLinkedList(
00156   LinkedListInfo *list_info,const void *value)
00157 {
00158   register ElementInfo
00159     *next;
00160 
00161   assert(list_info != (LinkedListInfo *) NULL);
00162   assert(list_info->signature == WizardSignature);
00163   if (list_info->debug != WizardFalse)
00164     (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00165   if (list_info->elements == list_info->capacity)
00166     return(WizardFalse);
00167   next=(ElementInfo *) AcquireWizardMemory(sizeof(*next));
00168   if (next == (ElementInfo *) NULL)
00169     return(WizardFalse);
00170   next->value=(void *) value;
00171   next->next=(ElementInfo *) NULL;
00172   LockSemaphoreInfo(list_info->semaphore);
00173   if (list_info->next == (ElementInfo *) NULL)
00174     list_info->next=next;
00175   if (list_info->elements == 0)
00176     list_info->head=next;
00177   else
00178     list_info->tail->next=next;
00179   list_info->tail=next;
00180   list_info->elements++;
00181   UnlockSemaphoreInfo(list_info->semaphore);
00182   return(WizardTrue);
00183 }
00184 
00185 /*
00186 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00187 %                                                                             %
00188 %                                                                             %
00189 %                                                                             %
00190 %   C l e a r L i n k e d L i s t                                             %
00191 %                                                                             %
00192 %                                                                             %
00193 %                                                                             %
00194 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00195 %
00196 %  ClearLinkedList() clears all the elements from the linked-list.
00197 %
00198 %  The format of the ClearLinkedList method is:
00199 %
00200 %      void ClearLinkedList(LinkedListInfo *list_info,
00201 %        void *(*relinquish_value)(void *))
00202 %
00203 %  A description of each parameter follows:
00204 %
00205 %    o list_info: The linked-list info.
00206 %
00207 %    o relinquish_value: The value deallocation method; typically
00208 %      RelinquishWizardMemory().
00209 %
00210 */
00211 WizardExport void ClearLinkedList(LinkedListInfo *list_info,
00212   void *(*relinquish_value)(void *))
00213 {
00214   ElementInfo
00215     *element;
00216 
00217   register ElementInfo
00218     *next;
00219 
00220   assert(list_info != (LinkedListInfo *) NULL);
00221   assert(list_info->signature == WizardSignature);
00222   if (list_info->debug != WizardFalse)
00223     (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00224   LockSemaphoreInfo(list_info->semaphore);
00225   next=list_info->head;
00226   while (next != (ElementInfo *) NULL)
00227   {
00228     if (relinquish_value != (void *(*)(void *)) NULL)
00229       next->value=relinquish_value(next->value);
00230     element=next;
00231     next=next->next;
00232     element=(ElementInfo *) RelinquishWizardMemory(element);
00233   }
00234   list_info->head=(ElementInfo *) NULL;
00235   list_info->tail=(ElementInfo *) NULL;
00236   list_info->next=(ElementInfo *) NULL;
00237   list_info->elements=0;
00238   UnlockSemaphoreInfo(list_info->semaphore);
00239 }
00240 
00241 /*
00242 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00243 %                                                                             %
00244 %                                                                             %
00245 %                                                                             %
00246 %   C o m p a r e H a s h m a p S t r i n g                                   %
00247 %                                                                             %
00248 %                                                                             %
00249 %                                                                             %
00250 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00251 %
00252 %  CompareHashmapString() finds an entry in a hash-map based on the contents
00253 %  of a string.
00254 %
00255 %  The format of the CompareHashmapString method is:
00256 %
00257 %      WizardBooleanType CompareHashmapString(const void *target,
00258 %        const void *source)
00259 %
00260 %  A description of each parameter follows:
00261 %
00262 %    o target: The target string.
00263 %
00264 %    o source: The source string.
00265 %
00266 */
00267 WizardExport WizardBooleanType CompareHashmapString(const void *target,
00268   const void *source)
00269 {
00270   char
00271     *p,
00272     *q;
00273 
00274   p=(char *) target;
00275   q=(char *) source;
00276   return(strcmp(p,q) == 0 ? WizardTrue : WizardFalse);
00277 }
00278 
00279 /*
00280 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00281 %                                                                             %
00282 %                                                                             %
00283 %                                                                             %
00284 %   C o m p a r e H a s h m a p S t r i n g I n f o                           %
00285 %                                                                             %
00286 %                                                                             %
00287 %                                                                             %
00288 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00289 %
00290 %  CompareHashmapStringInfo() finds an entry in a hash-map based on the
00291 %  contents of a string.
00292 %
00293 %  The format of the CompareHashmapStringInfo method is:
00294 %
00295 %      WizardBooleanType CompareHashmapStringInfo(const void *target,
00296 %        const void *source)
00297 %
00298 %  A description of each parameter follows:
00299 %
00300 %    o target: The target string.
00301 %
00302 %    o source: The source string.
00303 %
00304 */
00305 WizardExport WizardBooleanType CompareHashmapStringInfo(const void *target,
00306   const void *source)
00307 {
00308   StringInfo
00309     *p,
00310     *q;
00311 
00312   p=(StringInfo *) target;
00313   q=(StringInfo *) source;
00314   return(CompareStringInfo(p,q) == 0 ? WizardTrue : WizardFalse);
00315 }
00316 
00317 /*
00318 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00319 %                                                                             %
00320 %                                                                             %
00321 %                                                                             %
00322 %   D e s t r o y H a s h m a p                                               %
00323 %                                                                             %
00324 %                                                                             %
00325 %                                                                             %
00326 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00327 %
00328 %  DestroyHashmap() frees the hash-map and all associated resources.
00329 %
00330 %  The format of the DestroyHashmap method is:
00331 %
00332 %      HashmapInfo *DestroyHashmap(HashmapInfo *hashmap_info)
00333 %
00334 %  A description of each parameter follows:
00335 %
00336 %    o hashmap_info: The hashmap info.
00337 %
00338 */
00339 WizardExport HashmapInfo *DestroyHashmap(HashmapInfo *hashmap_info)
00340 {
00341   LinkedListInfo
00342     *list_info;
00343 
00344   register EntryInfo
00345     *entry;
00346 
00347   register ssize_t
00348     i;
00349 
00350   assert(hashmap_info != (HashmapInfo *) NULL);
00351   assert(hashmap_info->signature == WizardSignature);
00352   if (hashmap_info->debug != WizardFalse)
00353     (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00354   LockSemaphoreInfo(hashmap_info->semaphore);
00355   for (i=0; i < (ssize_t) hashmap_info->capacity; i++)
00356   {
00357     list_info=hashmap_info->map[i];
00358     if (list_info != (LinkedListInfo *) NULL)
00359       {
00360         list_info->next=list_info->head;
00361         entry=(EntryInfo *) GetNextValueInLinkedList(list_info);
00362         while (entry != (EntryInfo *) NULL)
00363         {
00364           if (hashmap_info->relinquish_key != (void *(*)(void *)) NULL)
00365             entry->key=hashmap_info->relinquish_key(entry->key);
00366           if (hashmap_info->relinquish_value != (void *(*)(void *)) NULL)
00367             entry->value=hashmap_info->relinquish_value(entry->value);
00368           entry=(EntryInfo *) GetNextValueInLinkedList(list_info);
00369         }
00370       }
00371     if (list_info != (LinkedListInfo *) NULL)
00372       list_info=DestroyLinkedList(list_info,RelinquishWizardMemory);
00373   }
00374   hashmap_info->map=(LinkedListInfo **) RelinquishWizardMemory(
00375     hashmap_info->map);
00376   hashmap_info->signature=(~WizardSignature);
00377   UnlockSemaphoreInfo(hashmap_info->semaphore);
00378   DestroySemaphoreInfo(&hashmap_info->semaphore);
00379   hashmap_info=(HashmapInfo *) RelinquishWizardMemory(hashmap_info);
00380   return(hashmap_info);
00381 }
00382 
00383 /*
00384 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00385 %                                                                             %
00386 %                                                                             %
00387 %                                                                             %
00388 %   D e s t r o y L i n k e d L i s t                                         %
00389 %                                                                             %
00390 %                                                                             %
00391 %                                                                             %
00392 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00393 %
00394 %  DestroyLinkedList() frees the linked-list and all associated resources.
00395 %
00396 %  The format of the DestroyLinkedList method is:
00397 %
00398 %      LinkedListInfo *DestroyLinkedList(LinkedListInfo *list_info,
00399 %        void *(*relinquish_value)(void *))
00400 %
00401 %  A description of each parameter follows:
00402 %
00403 %    o list_info: The linked-list info.
00404 %
00405 %    o relinquish_value: The value deallocation method;  typically
00406 %      RelinquishWizardMemory().
00407 %
00408 */
00409 WizardExport LinkedListInfo *DestroyLinkedList(LinkedListInfo *list_info,
00410   void *(*relinquish_value)(void *))
00411 {
00412   ElementInfo
00413     *entry;
00414 
00415   register ElementInfo
00416     *next;
00417 
00418   assert(list_info != (LinkedListInfo *) NULL);
00419   assert(list_info->signature == WizardSignature);
00420   if (list_info->debug != WizardFalse)
00421     (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00422   LockSemaphoreInfo(list_info->semaphore);
00423   for (next=list_info->head; next != (ElementInfo *) NULL; )
00424   {
00425     if (relinquish_value != (void *(*)(void *)) NULL)
00426       next->value=relinquish_value(next->value);
00427     entry=next;
00428     next=next->next;
00429     entry=(ElementInfo *) RelinquishWizardMemory(entry);
00430   }
00431   list_info->signature=(~WizardSignature);
00432   UnlockSemaphoreInfo(list_info->semaphore);
00433   DestroySemaphoreInfo(&list_info->semaphore);
00434   list_info=(LinkedListInfo *) RelinquishWizardMemory(list_info);
00435   return(list_info);
00436 }
00437 
00438 /*
00439 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00440 %                                                                             %
00441 %                                                                             %
00442 %                                                                             %
00443 %   G e t L a s t V a l u e I n L i n k e d L i s t                           %
00444 %                                                                             %
00445 %                                                                             %
00446 %                                                                             %
00447 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00448 %
00449 %  GetLastValueInLinkedList() gets the last value in the linked-list.
00450 %
00451 %  The format of the GetLastValueInLinkedList method is:
00452 %
00453 %      void *GetLastValueInLinkedList(LinkedListInfo *list_info)
00454 %
00455 %  A description of each parameter follows:
00456 %
00457 %    o list_info: The linked_list info.
00458 %
00459 */
00460 WizardExport void *GetLastValueInLinkedList(LinkedListInfo *list_info)
00461 {
00462   void
00463     *value;
00464 
00465   assert(list_info != (LinkedListInfo *) NULL);
00466   assert(list_info->signature == WizardSignature);
00467   if (list_info->debug != WizardFalse)
00468     (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00469   if (list_info->elements == 0)
00470     return((void *) NULL);
00471   LockSemaphoreInfo(list_info->semaphore);
00472   value=list_info->tail->value;
00473   UnlockSemaphoreInfo(list_info->semaphore);
00474   return(value);
00475 }
00476 
00477 /*
00478 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00479 %                                                                             %
00480 %                                                                             %
00481 %                                                                             %
00482 %   G e t N e x t K e y I n H a s h m a p                                     %
00483 %                                                                             %
00484 %                                                                             %
00485 %                                                                             %
00486 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00487 %
00488 %  GetNextKeyInHashmap() gets the next key in the hash-map.
00489 %
00490 %  The format of the GetNextKeyInHashmap method is:
00491 %
00492 %      void *GetNextKeyInHashmap(HashmapInfo *hashmap_info)
00493 %
00494 %  A description of each parameter follows:
00495 %
00496 %    o hashmap_info: The hashmap info.
00497 %
00498 */
00499 WizardExport void *GetNextKeyInHashmap(HashmapInfo *hashmap_info)
00500 {
00501   LinkedListInfo
00502     *list_info;
00503 
00504   register EntryInfo
00505     *entry;
00506 
00507   void
00508     *key;
00509 
00510   assert(hashmap_info != (HashmapInfo *) NULL);
00511   assert(hashmap_info->signature == WizardSignature);
00512   if (hashmap_info->debug != WizardFalse)
00513     (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00514   LockSemaphoreInfo(hashmap_info->semaphore);
00515   while (hashmap_info->next < hashmap_info->capacity)
00516   {
00517     list_info=hashmap_info->map[hashmap_info->next];
00518     if (list_info != (LinkedListInfo *) NULL)
00519       {
00520         if (hashmap_info->head_of_list == WizardFalse)
00521           {
00522             list_info->next=list_info->head;
00523             hashmap_info->head_of_list=WizardTrue;
00524           }
00525         entry=(EntryInfo *) GetNextValueInLinkedList(list_info);
00526         if (entry != (EntryInfo *) NULL)
00527           {
00528             key=entry->key;
00529             UnlockSemaphoreInfo(hashmap_info->semaphore);
00530             return(key);
00531           }
00532         hashmap_info->head_of_list=WizardFalse;
00533       }
00534     hashmap_info->next++;
00535   }
00536   UnlockSemaphoreInfo(hashmap_info->semaphore);
00537   return((void *) NULL);
00538 }
00539 
00540 /*
00541 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00542 %                                                                             %
00543 %                                                                             %
00544 %                                                                             %
00545 %   G e t N e x t V a l u e I n H a s h m a p                                 %
00546 %                                                                             %
00547 %                                                                             %
00548 %                                                                             %
00549 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00550 %
00551 %  GetNextValueInHashmap() gets the next value in the hash-map.
00552 %
00553 %  The format of the GetNextValueInHashmap method is:
00554 %
00555 %      void *GetNextValueInHashmap(HashmapInfo *hashmap_info)
00556 %
00557 %  A description of each parameter follows:
00558 %
00559 %    o hashmap_info: The hashmap info.
00560 %
00561 */
00562 WizardExport void *GetNextValueInHashmap(HashmapInfo *hashmap_info)
00563 {
00564   LinkedListInfo
00565     *list_info;
00566 
00567   register EntryInfo
00568     *entry;
00569 
00570   void
00571     *value;
00572 
00573   assert(hashmap_info != (HashmapInfo *) NULL);
00574   assert(hashmap_info->signature == WizardSignature);
00575   if (hashmap_info->debug != WizardFalse)
00576     (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00577   LockSemaphoreInfo(hashmap_info->semaphore);
00578   while (hashmap_info->next < hashmap_info->capacity)
00579   {
00580     list_info=hashmap_info->map[hashmap_info->next];
00581     if (list_info != (LinkedListInfo *) NULL)
00582       {
00583         if (hashmap_info->head_of_list == WizardFalse)
00584           {
00585             list_info->next=list_info->head;
00586             hashmap_info->head_of_list=WizardTrue;
00587           }
00588         entry=(EntryInfo *) GetNextValueInLinkedList(list_info);
00589         if (entry != (EntryInfo *) NULL)
00590           {
00591             value=entry->value;
00592             UnlockSemaphoreInfo(hashmap_info->semaphore);
00593             return(value);
00594           }
00595         hashmap_info->head_of_list=WizardFalse;
00596       }
00597     hashmap_info->next++;
00598   }
00599   UnlockSemaphoreInfo(hashmap_info->semaphore);
00600   return((void *) NULL);
00601 }
00602 
00603 /*
00604 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00605 %                                                                             %
00606 %                                                                             %
00607 %                                                                             %
00608 %   G e t N e x t V a l u e I n L i n k e d L i s t                           %
00609 %                                                                             %
00610 %                                                                             %
00611 %                                                                             %
00612 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00613 %
00614 %  GetNextValueInLinkedList() gets the next value in the linked-list.
00615 %
00616 %  The format of the GetNextValueInLinkedList method is:
00617 %
00618 %      void *GetNextValueInLinkedList(LinkedListInfo *list_info)
00619 %
00620 %  A description of each parameter follows:
00621 %
00622 %    o list_info: The linked-list info.
00623 %
00624 */
00625 WizardExport void *GetNextValueInLinkedList(LinkedListInfo *list_info)
00626 {
00627   void
00628     *value;
00629 
00630   assert(list_info != (LinkedListInfo *) NULL);
00631   assert(list_info->signature == WizardSignature);
00632   if (list_info->debug != WizardFalse)
00633     (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00634   LockSemaphoreInfo(list_info->semaphore);
00635   if (list_info->next == (ElementInfo *) NULL)
00636     {
00637       UnlockSemaphoreInfo(list_info->semaphore);
00638       return((void *) NULL);
00639     }
00640   value=list_info->next->value;
00641   list_info->next=list_info->next->next;
00642   UnlockSemaphoreInfo(list_info->semaphore);
00643   return(value);
00644 }
00645 
00646 /*
00647 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00648 %                                                                             %
00649 %                                                                             %
00650 %                                                                             %
00651 %   G e t N u m b e r O f E n t r i e s I n H a s h m a p                     %
00652 %                                                                             %
00653 %                                                                             %
00654 %                                                                             %
00655 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00656 %
00657 %  GetNumberOfEntriesInHashmap() returns the number of entries in the hash-map.
00658 %
00659 %  The format of the GetNumberOfEntriesInHashmap method is:
00660 %
00661 %      size_t GetNumberOfEntriesInHashmap(const HashmapInfo *hashmap_info)
00662 %
00663 %  A description of each parameter follows:
00664 %
00665 %    o hashmap_info: The hashmap info.
00666 %
00667 */
00668 WizardExport size_t GetNumberOfEntriesInHashmap(
00669   const HashmapInfo *hashmap_info)
00670 {
00671   assert(hashmap_info != (HashmapInfo *) NULL);
00672   assert(hashmap_info->signature == WizardSignature);
00673   if (hashmap_info->debug != WizardFalse)
00674     (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00675   return(hashmap_info->entries);
00676 }
00677 
00678 /*
00679 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00680 %                                                                             %
00681 %                                                                             %
00682 %                                                                             %
00683 %   G e t N u m b e r O f E l e m e n t s I n L i n k e d L i s t             %
00684 %                                                                             %
00685 %                                                                             %
00686 %                                                                             %
00687 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00688 %
00689 %  GetNumberOfElementsInLinkedList() returns the number of entries in the
00690 %  linked-list.
00691 %
00692 %  The format of the GetNumberOfElementsInLinkedList method is:
00693 %
00694 %      size_t GetNumberOfElementsInLinkedList(
00695 %        const LinkedListInfo *list_info)
00696 %
00697 %  A description of each parameter follows:
00698 %
00699 %    o list_info: The linked-list info.
00700 %
00701 */
00702 WizardExport size_t GetNumberOfElementsInLinkedList(
00703   const LinkedListInfo *list_info)
00704 {
00705   assert(list_info != (LinkedListInfo *) NULL);
00706   assert(list_info->signature == WizardSignature);
00707   if (list_info->debug != WizardFalse)
00708     (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00709   return(list_info->elements);
00710 }
00711 
00712 /*
00713 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00714 %                                                                             %
00715 %                                                                             %
00716 %                                                                             %
00717 %   G e t V a l u e F r o m H a s h m a p                                     %
00718 %                                                                             %
00719 %                                                                             %
00720 %                                                                             %
00721 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00722 %
00723 %  GetValueFromHashmap() gets a value from the hash-map by its key.
00724 %
00725 %  The format of the GetValueFromHashmap method is:
00726 %
00727 %      void *GetValueFromHashmap(HashmapInfo *hashmap_info,const void *key)
00728 %
00729 %  A description of each parameter follows:
00730 %
00731 %    o hashmap_info: The hashmap info.
00732 %
00733 %    o key: The key.
00734 %
00735 */
00736 WizardExport void *GetValueFromHashmap(HashmapInfo *hashmap_info,
00737   const void *key)
00738 {
00739   LinkedListInfo
00740     *list_info;
00741 
00742   register EntryInfo
00743     *entry;
00744 
00745   size_t
00746     hash;
00747 
00748   void
00749     *value;
00750 
00751   assert(hashmap_info != (HashmapInfo *) NULL);
00752   assert(hashmap_info->signature == WizardSignature);
00753   if (hashmap_info->debug != WizardFalse)
00754     (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00755   if (key == NULL)
00756     return((void *) NULL);
00757   LockSemaphoreInfo(hashmap_info->semaphore);
00758   hash=hashmap_info->hash(key);
00759   list_info=hashmap_info->map[hash % hashmap_info->capacity];
00760   if (list_info != (LinkedListInfo *) NULL)
00761     {
00762       list_info->next=list_info->head;
00763       entry=(EntryInfo *) GetNextValueInLinkedList(list_info);
00764       while (entry != (EntryInfo *) NULL)
00765       {
00766         if (entry->hash == hash)
00767           {
00768             WizardBooleanType
00769               compare;
00770 
00771             compare=WizardTrue;
00772             if (hashmap_info->compare !=
00773                 (WizardBooleanType (*)(const void *,const void *)) NULL)
00774               compare=hashmap_info->compare(key,entry->key);
00775             if (compare == WizardTrue)
00776               {
00777                 value=entry->value;
00778                 UnlockSemaphoreInfo(hashmap_info->semaphore);
00779                 return(value);
00780               }
00781           }
00782         entry=(EntryInfo *) GetNextValueInLinkedList(list_info);
00783       }
00784     }
00785   UnlockSemaphoreInfo(hashmap_info->semaphore);
00786   return((void *) NULL);
00787 }
00788 
00789 /*
00790 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00791 %                                                                             %
00792 %                                                                             %
00793 %                                                                             %
00794 %   G e t V a l u e F r o m L i n k e d L i s t                               %
00795 %                                                                             %
00796 %                                                                             %
00797 %                                                                             %
00798 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00799 %
00800 %  GetValueFromLinkedList() gets a vlaue from the linked-list by the specified
00801 %  location.
00802 %
00803 %  The format of the GetValueFromLinkedList method is:
00804 %
00805 %      void *GetValueFromLinkedList(LinkedListInfo *list_info,
00806 %        const size_t index)
00807 %
00808 %  A description of each parameter follows:
00809 %
00810 %    o list_info: The linked_list info.
00811 %
00812 %    o index: The list index.
00813 %
00814 */
00815 WizardExport void *GetValueFromLinkedList(LinkedListInfo *list_info,
00816   const size_t index)
00817 {
00818   register ElementInfo
00819     *next;
00820 
00821   register ssize_t
00822     i;
00823 
00824   void
00825     *value;
00826 
00827   assert(list_info != (LinkedListInfo *) NULL);
00828   assert(list_info->signature == WizardSignature);
00829   if (list_info->debug != WizardFalse)
00830     (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00831   if (index >= list_info->elements)
00832     return((void *) NULL);
00833   LockSemaphoreInfo(list_info->semaphore);
00834   if (index == 0)
00835     {
00836       value=list_info->head->value;
00837       UnlockSemaphoreInfo(list_info->semaphore);
00838       return(value);
00839     }
00840   if (index == (list_info->elements-1))
00841     {
00842       value=list_info->tail->value;
00843       UnlockSemaphoreInfo(list_info->semaphore);
00844       return(value);
00845     }
00846   next=list_info->head;
00847   for (i=0; i < (ssize_t) index; i++)
00848     next=next->next;
00849   value=next->value;
00850   UnlockSemaphoreInfo(list_info->semaphore);
00851   return(value);
00852 }
00853 
00854 /*
00855 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00856 %                                                                             %
00857 %                                                                             %
00858 %                                                                             %
00859 %   H a s h P o i n t e r T y p e                                             %
00860 %                                                                             %
00861 %                                                                             %
00862 %                                                                             %
00863 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00864 %
00865 %  HashPointerType() finds an entry in a hash-map based on the address of a
00866 %  pointer.
00867 %
00868 %  The format of the HashPointerType method is:
00869 %
00870 %      size_t HashPointerType(const void *pointer)
00871 %
00872 %  A description of each parameter follows:
00873 %
00874 %    o pointer: compute the hash entry location from this pointer address.
00875 %
00876 */
00877 WizardExport size_t HashPointerType(const void *pointer)
00878 {
00879   size_t
00880     hash;
00881 
00882   hash=(size_t) pointer;
00883   hash+=(~(hash << 9));
00884   hash^=(hash >> 14);
00885   hash+=(hash << 4);
00886   hash^=(hash >> 10);
00887   return(hash);
00888 }
00889 
00890 /*
00891 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00892 %                                                                             %
00893 %                                                                             %
00894 %                                                                             %
00895 %   H a s h S t r i n g T y p e                                               %
00896 %                                                                             %
00897 %                                                                             %
00898 %                                                                             %
00899 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00900 %
00901 %  HashStringType() finds an entry in a hash-map based on the contents of a
00902 %  string.
00903 %
00904 %  The format of the HashStringType method is:
00905 %
00906 %      size_t HashStringType(const void *string)
00907 %
00908 %  A description of each parameter follows:
00909 %
00910 %    o string: compute the hash entry location from this string.
00911 %
00912 */
00913 WizardExport size_t HashStringType(const void *string)
00914 {
00915   const StringInfo
00916     *digest;
00917 
00918   HashInfo
00919     *hashmap_info;
00920 
00921   register size_t
00922     i;
00923 
00924   size_t
00925     hash;
00926 
00927   StringInfo
00928     *message;
00929 
00930   unsigned char
00931     *datum;
00932 
00933   hashmap_info=AcquireHashInfo(CRC64Hash);
00934   if (hashmap_info == (HashInfo *) NULL)
00935     return((size_t) string);
00936   InitializeHash(hashmap_info);
00937   message=StringToStringInfo((const char *) string);
00938   UpdateHash(hashmap_info,message);
00939   FinalizeHash(hashmap_info);
00940   hash=0;
00941   digest=GetHashDigest(hashmap_info);
00942   datum=GetStringInfoDatum(digest);
00943   for (i=0; i < GetStringInfoLength(digest); i++)
00944     hash^=datum[i];
00945   hashmap_info=DestroyHashInfo(hashmap_info);
00946   return(hash);
00947 }
00948 
00949 /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00950 %                                                                             %
00951 %                                                                             %
00952 %                                                                             %
00953 %   H a s h S t r i n g I n f o T y p e                                       %
00954 %                                                                             %
00955 %                                                                             %
00956 %                                                                             %
00957 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00958 %
00959 %  HashStringInfoType() finds an entry in a hash-map based on the contents of
00960 %  a string.
00961 %
00962 %  The format of the HashStringInfoType method is:
00963 %
00964 %      size_t HashStringInfoType(const void *string)
00965 %
00966 %  A description of each parameter follows:
00967 %
00968 %    o string: compute the hash entry location from this string.
00969 %
00970 */
00971 WizardExport size_t HashStringInfoType(const void *string)
00972 {
00973   register size_t
00974     i;
00975 
00976   size_t
00977     hash;
00978 
00979   StringInfo
00980     *message;
00981 
00982   unsigned char
00983     *datum;
00984 
00985   message=(StringInfo *) string;
00986   hash=0;
00987   datum=GetStringInfoDatum(message);
00988   for (i=0; i < GetStringInfoLength(message); i++)
00989     hash^=datum[i];
00990   return(hash);
00991 }
00992 
00993 /*
00994 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00995 %                                                                             %
00996 %                                                                             %
00997 %                                                                             %
00998 %   I n s e r t V a l u e I n L i n k e d L i s t                             %
00999 %                                                                             %
01000 %                                                                             %
01001 %                                                                             %
01002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01003 %
01004 %  InsertValueInLinkedList() inserts an element in the linked-list at the
01005 %  specified location.
01006 %
01007 %  The format of the InsertValueInLinkedList method is:
01008 %
01009 %      WizardBooleanType InsertValueInLinkedList(ListInfo *list_info,
01010 %        const size_t index,const void *value)
01011 %
01012 %  A description of each parameter follows:
01013 %
01014 %    o list_info: The hashmap info.
01015 %
01016 %    o index: The index.
01017 %
01018 %    o value: The value.
01019 %
01020 */
01021 WizardExport WizardBooleanType InsertValueInLinkedList(
01022   LinkedListInfo *list_info,const size_t index,const void *value)
01023 {
01024   register ElementInfo
01025     *next;
01026 
01027   register ssize_t
01028     i;
01029 
01030   assert(list_info != (LinkedListInfo *) NULL);
01031   assert(list_info->signature == WizardSignature);
01032   if (list_info->debug != WizardFalse)
01033     (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
01034   if (value == NULL)
01035     return(WizardFalse);
01036   if ((index > list_info->elements) ||
01037       (list_info->elements == list_info->capacity))
01038     return(WizardFalse);
01039   next=(ElementInfo *) AcquireWizardMemory(sizeof(*next));
01040   if (next == (ElementInfo *) NULL)
01041     return(WizardFalse);
01042   next->value=(void *) value;
01043   next->next=(ElementInfo *) NULL;
01044   LockSemaphoreInfo(list_info->semaphore);
01045   if (list_info->elements == 0)
01046     {
01047       if (list_info->next == (ElementInfo *) NULL)
01048         list_info->next=next;
01049       list_info->head=next;
01050       list_info->tail=next;
01051     }
01052   else
01053     {
01054       if (index == 0)
01055         {
01056           if (list_info->next == list_info->head)
01057             list_info->next=next;
01058           next->next=list_info->head;
01059           list_info->head=next;
01060         }
01061       else
01062         if (index == list_info->elements)
01063           {
01064             if (list_info->next == (ElementInfo *) NULL)
01065               list_info->next=next;
01066             list_info->tail->next=next;
01067             list_info->tail=next;
01068           }
01069         else
01070           {
01071             ElementInfo
01072               *element;
01073 
01074             element=list_info->head;
01075             next->next=element->next;
01076             for (i=1; i < (ssize_t) index; i++)
01077             {
01078               element=element->next;
01079               next->next=element->next;
01080             }
01081             next=next->next;
01082             element->next=next;
01083             if (list_info->next == next->next)
01084               list_info->next=next;
01085           }
01086     }
01087   list_info->elements++;
01088   UnlockSemaphoreInfo(list_info->semaphore);
01089   return(WizardTrue);
01090 }
01091 
01092 /*
01093 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01094 %                                                                             %
01095 %                                                                             %
01096 %                                                                             %
01097 %   I n s e r t V a l u e I n S o r t e d L i n k e d L i s t                 %
01098 %                                                                             %
01099 %                                                                             %
01100 %                                                                             %
01101 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01102 %
01103 %  InsertValueInSortedLinkedList() inserts a value in the sorted linked-list.
01104 %
01105 %  The format of the InsertValueInSortedLinkedList method is:
01106 %
01107 %      WizardBooleanType InsertValueInSortedLinkedList(ListInfo *list_info,
01108 %        int (*compare)(const void *,const void *),void **replace,
01109 %        const void *value)
01110 %
01111 %  A description of each parameter follows:
01112 %
01113 %    o list_info: The hashmap info.
01114 %
01115 %    o index: The index.
01116 %
01117 %    o compare: The compare method.
01118 %
01119 %    o replace: return previous element here.
01120 %
01121 %    o value: The value.
01122 %
01123 */
01124 WizardExport WizardBooleanType InsertValueInSortedLinkedList(
01125   LinkedListInfo *list_info,int (*compare)(const void *,const void *),
01126   void **replace,const void *value)
01127 {
01128   ElementInfo
01129     *element;
01130 
01131   register ElementInfo
01132     *next;
01133 
01134   register ssize_t
01135     i;
01136 
01137   assert(list_info != (LinkedListInfo *) NULL);
01138   assert(list_info->signature == WizardSignature);
01139   if (list_info->debug != WizardFalse)
01140     (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
01141   if ((compare == (int (*)(const void *,const void *)) NULL) ||
01142       (value == (const void *) NULL))
01143     return(WizardFalse);
01144   if (list_info->elements == list_info->capacity)
01145     return(WizardFalse);
01146   next=(ElementInfo *) AcquireWizardMemory(sizeof(*next));
01147   if (next == (ElementInfo *) NULL)
01148     return(WizardFalse);
01149   next->value=(void *) value;
01150   element=(ElementInfo *) NULL;
01151   LockSemaphoreInfo(list_info->semaphore);
01152   next->next=list_info->head;
01153   while (next->next != (ElementInfo *) NULL)
01154   {
01155     i=compare(value,next->next->value);
01156     if ((i < 0) || ((replace != (void **) NULL) && (i == 0)))
01157       {
01158         if (i == 0)
01159           {
01160             *replace=next->next->value;
01161             next->next=next->next->next;
01162             if (element != (ElementInfo *) NULL)
01163               element->next=(ElementInfo *) RelinquishWizardMemory(
01164                 element->next);
01165             list_info->elements--;
01166           }
01167         if (element != (ElementInfo *) NULL)
01168           element->next=next;
01169         else
01170           list_info->head=next;
01171         break;
01172       }
01173     element=next->next;
01174     next->next=next->next->next;
01175   }
01176   if (next->next == (ElementInfo *) NULL)
01177     {
01178       if (element != (ElementInfo *) NULL)
01179         element->next=next;
01180       else
01181         list_info->head=next;
01182       list_info->tail=next;
01183     }
01184   list_info->elements++;
01185   UnlockSemaphoreInfo(list_info->semaphore);
01186   return(WizardTrue);
01187 }
01188 
01189 /*
01190 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01191 %                                                                             %
01192 %                                                                             %
01193 %                                                                             %
01194 %   I s H a s h m a p E m p t y                                               %
01195 %                                                                             %
01196 %                                                                             %
01197 %                                                                             %
01198 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01199 %
01200 %  IsHashmapEmpty() returns WizardTrue if the hash-map is empty.
01201 %
01202 %  The format of the IsHashmapEmpty method is:
01203 %
01204 %      WizardBooleanType IsHashmapEmpty(const HashmapInfo *hashmap_info)
01205 %
01206 %  A description of each parameter follows:
01207 %
01208 %    o hashmap_info: The hashmap info.
01209 %
01210 */
01211 WizardExport WizardBooleanType IsHashmapEmpty(const HashmapInfo *hashmap_info)
01212 {
01213   assert(hashmap_info != (HashmapInfo *) NULL);
01214   assert(hashmap_info->signature == WizardSignature);
01215   if (hashmap_info->debug != WizardFalse)
01216     (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
01217   return(hashmap_info->entries == 0 ? WizardTrue : WizardFalse);
01218 }
01219 
01220 /*
01221 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01222 %                                                                             %
01223 %                                                                             %
01224 %                                                                             %
01225 %   I s L i n k e d L i s t E m p t y                                         %
01226 %                                                                             %
01227 %                                                                             %
01228 %                                                                             %
01229 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01230 %
01231 %  IsLinkedListEmpty() returns WizardTrue if the linked-list is empty.
01232 %
01233 %  The format of the IsLinkedListEmpty method is:
01234 %
01235 %      WizardBooleanType IsLinkedListEmpty(LinkedListInfo *list_info)
01236 %
01237 %  A description of each parameter follows:
01238 %
01239 %    o list_info: The linked-list info.
01240 %
01241 */
01242 WizardExport WizardBooleanType IsLinkedListEmpty(
01243   const LinkedListInfo *list_info)
01244 {
01245   assert(list_info != (LinkedListInfo *) NULL);
01246   assert(list_info->signature == WizardSignature);
01247   if (list_info->debug != WizardFalse)
01248     (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
01249   return(list_info->elements == 0 ? WizardTrue : WizardFalse);
01250 }
01251 
01252 /*
01253 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01254 %                                                                             %
01255 %                                                                             %
01256 %                                                                             %
01257 %   L i n k e d L i s t T o A r r a y                                         %
01258 %                                                                             %
01259 %                                                                             %
01260 %                                                                             %
01261 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01262 %
01263 %  LinkedListToArray() converts the linked-list to an array.
01264 %
01265 %  The format of the LinkedListToArray method is:
01266 %
01267 %      WizardBooleanType LinkedListToArray(LinkedListInfo *list_info,
01268 %        void **array)
01269 %
01270 %  A description of each parameter follows:
01271 %
01272 %    o list_info: The linked-list info.
01273 %
01274 %    o array: The array.
01275 %
01276 */
01277 WizardExport WizardBooleanType LinkedListToArray(LinkedListInfo *list_info,
01278   void **array)
01279 {
01280   register ElementInfo
01281     *next;
01282 
01283   register ssize_t
01284     i;
01285 
01286   assert(list_info != (LinkedListInfo *) NULL);
01287   assert(list_info->signature == WizardSignature);
01288   if (list_info->debug != WizardFalse)
01289     (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
01290   if (array == (void **) NULL)
01291     return(WizardFalse);
01292   LockSemaphoreInfo(list_info->semaphore);
01293   next=list_info->head;
01294   for (i=0; next != (ElementInfo *) NULL; i++)
01295   {
01296     array[i]=next->value;
01297     next=next->next;
01298   }
01299   UnlockSemaphoreInfo(list_info->semaphore);
01300   return(WizardTrue);
01301 }
01302 
01303 /*
01304 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01305 %                                                                             %
01306 %                                                                             %
01307 %                                                                             %
01308 %   N e w H a s h m a p                                                       %
01309 %                                                                             %
01310 %                                                                             %
01311 %                                                                             %
01312 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01313 %
01314 %  NewHashmap() returns a pointer to a HashmapInfo structure initialized
01315 %  to default values.  The capacity is an initial estimate.  The hashmap will
01316 %  increase capacity dynamically as the demand requires.
01317 %
01318 %  The format of the NewHashmap method is:
01319 %
01320 %      HashmapInfo *NewHashmap(const size_t capacity,
01321 %        size_t (*hash)(const void *),
01322 %        WizardBooleanType (*compare)(const void *,const void *),
01323 %        void *(*relinquish_key)(void *),void *(*relinquish_value)(void *))
01324 %
01325 %  A description of each parameter follows:
01326 %
01327 %    o capacity: The initial number entries in the hash-map: typically
01328 %      SmallHashmapSize, MediumHashmapSize, or LargeHashmapSize.  The
01329 %      hashmap will dynamically increase its capacity on demand.
01330 %
01331 %    o hash: The hash method, typically HashPointerType(), HashStringType(),
01332 %      or HashStringInfoType().
01333 %
01334 %    o compare: The compare method, typically NULL, CompareHashmapString(),
01335 %      or CompareHashmapStringInfo().
01336 %
01337 %    o relinquish_key: The key deallocation method, typically
01338 %      RelinquishWizardMemory(), called whenever a key is removed from the
01339 %      hash-map.
01340 %
01341 %    o relinquish_value: The value deallocation method;  typically
01342 %      RelinquishWizardMemory(), called whenever a value object is removed from
01343 %      the hash-map.
01344 %
01345 */
01346 WizardExport HashmapInfo *NewHashmap(const size_t capacity,
01347   size_t (*hash)(const void *),
01348   WizardBooleanType (*compare)(const void *,const void *),
01349   void *(*relinquish_key)(void *),void *(*relinquish_value)(void *))
01350 {
01351   HashmapInfo
01352     *hashmap_info;
01353 
01354   hashmap_info=(HashmapInfo *) AcquireWizardMemory(sizeof(*hashmap_info));
01355   if (hashmap_info == (HashmapInfo *) NULL)
01356     ThrowWizardFatalError(CacheDomain,MemoryError);
01357   (void) ResetWizardMemory(hashmap_info,0,sizeof(*hashmap_info));
01358   hashmap_info->hash=HashPointerType;
01359   if (hash != (size_t (*)(const void *)) NULL)
01360     hashmap_info->hash=hash;
01361   hashmap_info->compare=(WizardBooleanType (*)(const void *,const void *)) NULL;
01362   if (compare != (WizardBooleanType (*)(const void *,const void *)) NULL)
01363     hashmap_info->compare=compare;
01364   hashmap_info->relinquish_key=relinquish_key;
01365   hashmap_info->relinquish_value=relinquish_value;
01366   hashmap_info->entries=0;
01367   hashmap_info->capacity=capacity;
01368   hashmap_info->map=(LinkedListInfo **) AcquireQuantumMemory((size_t)
01369     capacity+1UL,sizeof(*hashmap_info->map));
01370   if (hashmap_info->map == (LinkedListInfo **) NULL)
01371     ThrowWizardFatalError(CacheDomain,MemoryError);
01372   (void) ResetWizardMemory(hashmap_info->map,0,(size_t) capacity*
01373     sizeof(*hashmap_info->map));
01374   hashmap_info->debug=IsEventLogging();
01375   hashmap_info->semaphore=AllocateSemaphoreInfo();
01376   hashmap_info->signature=WizardSignature;
01377   return(hashmap_info);
01378 }
01379 
01380 /*
01381 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01382 %                                                                             %
01383 %                                                                             %
01384 %                                                                             %
01385 %   N e w L i n k e d L i s t I n f o                                         %
01386 %                                                                             %
01387 %                                                                             %
01388 %                                                                             %
01389 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01390 %
01391 %  NewLinkedList() returns a pointer to a LinkedListInfo structure
01392 %  initialized to default values.
01393 %
01394 %  The format of the Acquirestruct LinkedListInfomethod is:
01395 %
01396 %      LinkedListInfo *NewLinkedList(const size_t capacity)
01397 %
01398 %  A description of each parameter follows:
01399 %
01400 %    o capacity: The maximum number of elements in the list.
01401 %
01402 */
01403 WizardExport LinkedListInfo *NewLinkedList(const size_t capacity)
01404 {
01405   LinkedListInfo
01406     *list_info;
01407 
01408   list_info=(LinkedListInfo *) AcquireWizardMemory(sizeof(*list_info));
01409   if (list_info == (LinkedListInfo *) NULL)
01410     ThrowWizardFatalError(CacheDomain,MemoryError);
01411   (void) ResetWizardMemory(list_info,0,sizeof(*list_info));
01412   list_info->capacity=capacity == 0 ? (size_t) (~0) : capacity;
01413   list_info->elements=0;
01414   list_info->head=(ElementInfo *) NULL;
01415   list_info->tail=(ElementInfo *) NULL;
01416   list_info->next=(ElementInfo *) NULL;
01417   list_info->debug=WizardFalse;
01418   list_info->semaphore=AllocateSemaphoreInfo();
01419   list_info->signature=WizardSignature;
01420   return(list_info);
01421 }
01422 
01423 /*
01424 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01425 %                                                                             %
01426 %                                                                             %
01427 %                                                                             %
01428 %   P u t E n t r y I n H a s h m a p                                         %
01429 %                                                                             %
01430 %                                                                             %
01431 %                                                                             %
01432 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01433 %
01434 %  PutEntryInHashmap() puts an entry in the hash-map.  If the key already
01435 %  exists in the map it is first removed.
01436 %
01437 %  The format of the PutEntryInHashmap method is:
01438 %
01439 %      WizardBooleanType PutEntryInHashmap(HashmapInfo *hashmap_info,
01440 %        const void *key,const void *value)
01441 %
01442 %  A description of each parameter follows:
01443 %
01444 %    o hashmap_info: The hashmap info.
01445 %
01446 %    o key: The key.
01447 %
01448 %    o value: The value.
01449 %
01450 */
01451 
01452 static WizardBooleanType IncreaseHashmapCapacity(HashmapInfo *hashmap_info)
01453 {
01454 #define MaxCapacities  20
01455 
01456   const size_t
01457     capacities[MaxCapacities] =
01458     {
01459       17, 31, 61, 131, 257, 509, 1021, 2053, 4099, 8191, 16381, 32771,
01460       65537, 131071, 262147, 524287, 1048573, 2097143, 4194301, 8388617
01461     };
01462 
01463   ElementInfo
01464     *element;
01465 
01466   EntryInfo
01467     *entry;
01468 
01469   LinkedListInfo
01470     *list_info,
01471     *map_info,
01472     **map;
01473 
01474   register ElementInfo
01475     *next;
01476 
01477   register ssize_t
01478     i;
01479 
01480   size_t
01481     capacity;
01482 
01483   /*
01484     Increase to the next prime capacity.
01485   */
01486   for (i=0; i < MaxCapacities; i++)
01487     if (hashmap_info->capacity < capacities[i])
01488       break;
01489   if (i >= (MaxCapacities-1))
01490     return(WizardFalse);
01491   capacity=capacities[i+1];
01492   map=(LinkedListInfo **) AcquireQuantumMemory((size_t) capacity+1UL,
01493     sizeof(*map));
01494   if (map == (LinkedListInfo **) NULL)
01495     return(WizardFalse);
01496   (void) ResetWizardMemory(map,0,(size_t) capacity*sizeof(*map));
01497   /*
01498     Copy entries to new hashmap with increased capacity.
01499   */
01500   for (i=0; i < (ssize_t) hashmap_info->capacity; i++)
01501   {
01502     list_info=hashmap_info->map[i];
01503     if (list_info == (LinkedListInfo *) NULL)
01504       continue;
01505     LockSemaphoreInfo(list_info->semaphore);
01506     for (next=list_info->head; next != (ElementInfo *) NULL; )
01507     {
01508       element=next;
01509       next=next->next;
01510       entry=(EntryInfo *) element->value;
01511       map_info=map[entry->hash % capacity];
01512       if (map_info == (LinkedListInfo *) NULL)
01513         {
01514           map_info=NewLinkedList(0);
01515           map[entry->hash % capacity]=map_info;
01516         }
01517       map_info->next=element;
01518       element->next=map_info->head;
01519       map_info->head=element;
01520       map_info->elements++;
01521     }
01522     list_info->signature=(~WizardSignature);
01523     UnlockSemaphoreInfo(list_info->semaphore);
01524     DestroySemaphoreInfo(&list_info->semaphore);
01525     list_info=(LinkedListInfo *) RelinquishWizardMemory(list_info);
01526   }
01527   hashmap_info->map=(LinkedListInfo **) RelinquishWizardMemory(hashmap_info->map);
01528   hashmap_info->map=map;
01529   hashmap_info->capacity=capacity;
01530   return(WizardTrue);
01531 }
01532 
01533 WizardExport WizardBooleanType PutEntryInHashmap(HashmapInfo *hashmap_info,
01534   const void *key,const void *value)
01535 {
01536   EntryInfo
01537     *entry,
01538     *next;
01539 
01540   LinkedListInfo
01541     *list_info;
01542 
01543   register size_t
01544     i;
01545 
01546   assert(hashmap_info != (HashmapInfo *) NULL);
01547   assert(hashmap_info->signature == WizardSignature);
01548   if (hashmap_info->debug != WizardFalse)
01549     (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
01550   if ((key == (void *) NULL) || (value == (void *) NULL))
01551     return(WizardFalse);
01552   next=(EntryInfo *) AcquireWizardMemory(sizeof(*next));
01553   if (next == (EntryInfo *) NULL)
01554     return(WizardFalse);
01555   LockSemaphoreInfo(hashmap_info->semaphore);
01556   next->hash=hashmap_info->hash(key);
01557   next->key=(void *) key;
01558   next->value=(void *) value;
01559   list_info=hashmap_info->map[next->hash % hashmap_info->capacity];
01560   if (list_info == (LinkedListInfo *) NULL)
01561     {
01562       list_info=NewLinkedList(0);
01563       hashmap_info->map[next->hash % hashmap_info->capacity]=list_info;
01564     }
01565   else
01566     {
01567       list_info->next=list_info->head;
01568       entry=(EntryInfo *) GetNextValueInLinkedList(list_info);
01569       for (i=0; entry != (EntryInfo *) NULL; i++)
01570       {
01571         if (entry->hash == next->hash)
01572           {
01573             WizardBooleanType
01574               compare;
01575 
01576             compare=WizardTrue;
01577             if (hashmap_info->compare !=
01578                 (WizardBooleanType (*)(const void *,const void *)) NULL)
01579               compare=hashmap_info->compare(key,entry->key);
01580             if (compare == WizardTrue)
01581               {
01582                 (void) RemoveElementFromLinkedList(list_info,i);
01583                 if (hashmap_info->relinquish_key != (void *(*)(void *)) NULL)
01584                   entry->key=hashmap_info->relinquish_key(entry->key);
01585                 if (hashmap_info->relinquish_value != (void *(*)(void *)) NULL)
01586                   entry->value=hashmap_info->relinquish_value(entry->value);
01587                 entry=(EntryInfo *) RelinquishWizardMemory(entry);
01588                 break;
01589               }
01590           }
01591         entry=(EntryInfo *) GetNextValueInLinkedList(list_info);
01592       }
01593     }
01594   if (InsertValueInLinkedList(list_info,0,next) == WizardFalse)
01595     {
01596       next=(EntryInfo *) RelinquishWizardMemory(next);
01597       UnlockSemaphoreInfo(hashmap_info->semaphore);
01598       return(WizardFalse);
01599     }
01600   if (list_info->elements >= (hashmap_info->capacity-1))
01601     if (IncreaseHashmapCapacity(hashmap_info) == WizardFalse)
01602       {
01603         UnlockSemaphoreInfo(hashmap_info->semaphore);
01604         return(WizardFalse);
01605       }
01606   hashmap_info->entries++;
01607   UnlockSemaphoreInfo(hashmap_info->semaphore);
01608   return(WizardTrue);
01609 }
01610 
01611 /*
01612 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01613 %                                                                             %
01614 %                                                                             %
01615 %                                                                             %
01616 %   R e m o v e E l e m e n t B y V a l u e F r o m L i n k e d L i s t       %
01617 %                                                                             %
01618 %                                                                             %
01619 %                                                                             %
01620 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01621 %
01622 %  RemoveElementByValueFromLinkedList() removes an element from the linked-list
01623 %  by value.
01624 %
01625 %  The format of the RemoveElementByValueFromLinkedList method is:
01626 %
01627 %      void *RemoveElementByValueFromLinkedList(LinkedListInfo *list_info,
01628 %        const void *value)
01629 %
01630 %  A description of each parameter follows:
01631 %
01632 %    o list_info: The list info.
01633 %
01634 %    o value: The value.
01635 %
01636 */
01637 WizardExport void *RemoveElementByValueFromLinkedList(LinkedListInfo *list_info,
01638   const void *value)
01639 {
01640   ElementInfo
01641     *next;
01642 
01643   assert(list_info != (LinkedListInfo *) NULL);
01644   assert(list_info->signature == WizardSignature);
01645   if (list_info->debug != WizardFalse)
01646     (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
01647   if ((list_info->elements == 0) || (value == NULL))
01648     return((void *) NULL);
01649   LockSemaphoreInfo(list_info->semaphore);
01650   if (value == list_info->head->value)
01651     {
01652       if (list_info->next == list_info->head)
01653         list_info->next=list_info->head->next;
01654       next=list_info->head;
01655       list_info->head=list_info->head->next;
01656       next=(ElementInfo *) RelinquishWizardMemory(next);
01657     }
01658   else
01659     {
01660       ElementInfo
01661         *element;
01662 
01663       next=list_info->head;
01664       while ((next->next != (ElementInfo *) NULL) &&
01665              (next->next->value != value))
01666         next=next->next;
01667       if (next->next == (ElementInfo *) NULL)
01668         {
01669           UnlockSemaphoreInfo(list_info->semaphore);
01670           return((void *) NULL);
01671         }
01672       element=next->next;
01673       next->next=element->next;
01674       if (element == list_info->tail)
01675         list_info->tail=next;
01676       if (list_info->next == element)
01677         list_info->next=element->next;
01678       element=(ElementInfo *) RelinquishWizardMemory(element);
01679     }
01680   list_info->elements--;
01681   UnlockSemaphoreInfo(list_info->semaphore);
01682   return((void *) value);
01683 }
01684 
01685 /*
01686 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01687 %                                                                             %
01688 %                                                                             %
01689 %                                                                             %
01690 %   R e m o v e E l e m e n t F r o m L i n k e d L i s t                     %
01691 %                                                                             %
01692 %                                                                             %
01693 %                                                                             %
01694 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01695 %
01696 %  RemoveElementFromLinkedList() removes an element from the linked-list at the
01697 %  specified location.
01698 %
01699 %  The format of the RemoveElementFromLinkedList method is:
01700 %
01701 %      void *RemoveElementFromLinkedList(LinkedListInfo *list_info,
01702 %        const size_t index)
01703 %
01704 %  A description of each parameter follows:
01705 %
01706 %    o list_info: The linked-list info.
01707 %
01708 %    o index: The index.
01709 %
01710 */
01711 WizardExport void *RemoveElementFromLinkedList(LinkedListInfo *list_info,
01712   const size_t index)
01713 {
01714   ElementInfo
01715     *next;
01716 
01717   register ssize_t
01718     i;
01719 
01720   void
01721     *value;
01722 
01723   assert(list_info != (LinkedListInfo *) NULL);
01724   assert(list_info->signature == WizardSignature);
01725   if (list_info->debug != WizardFalse)
01726     (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
01727   if (index >= list_info->elements)
01728     return((void *) NULL);
01729   LockSemaphoreInfo(list_info->semaphore);
01730   if (index == 0)
01731     {
01732       if (list_info->next == list_info->head)
01733         list_info->next=list_info->head->next;
01734       value=list_info->head->value;
01735       next=list_info->head;
01736       list_info->head=list_info->head->next;
01737       next=(ElementInfo *) RelinquishWizardMemory(next);
01738     }
01739   else
01740     {
01741       ElementInfo
01742         *element;
01743 
01744       next=list_info->head;
01745       for (i=1; i < (ssize_t) index; i++)
01746         next=next->next;
01747       element=next->next;
01748       next->next=element->next;
01749       if (element == list_info->tail)
01750         list_info->tail=next;
01751       if (list_info->next == element)
01752         list_info->next=element->next;
01753       value=element->value;
01754       element=(ElementInfo *) RelinquishWizardMemory(element);
01755     }
01756   list_info->elements--;
01757   UnlockSemaphoreInfo(list_info->semaphore);
01758   return(value);
01759 }
01760 
01761 /*
01762 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01763 %                                                                             %
01764 %                                                                             %
01765 %                                                                             %
01766 %   R e m o v e E n t r y F r o m H a s h m a p                               %
01767 %                                                                             %
01768 %                                                                             %
01769 %                                                                             %
01770 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01771 %
01772 %  RemoveEntryFromHashmap() removes an entry from the hash-map by its key.
01773 %
01774 %  The format of the RemoveEntryFromHashmap method is:
01775 %
01776 %      void *RemoveEntryFromHashmap(HashmapInfo *hashmap_info,void *key)
01777 %
01778 %  A description of each parameter follows:
01779 %
01780 %    o hashmap_info: The hashmap info.
01781 %
01782 %    o key: The key.
01783 %
01784 */
01785 WizardExport void *RemoveEntryFromHashmap(HashmapInfo *hashmap_info,
01786   const void *key)
01787 {
01788   EntryInfo
01789     *entry;
01790 
01791   LinkedListInfo
01792     *list_info;
01793 
01794   register size_t
01795     i;
01796 
01797   size_t
01798     hash;
01799 
01800   void
01801     *value;
01802 
01803   assert(hashmap_info != (HashmapInfo *) NULL);
01804   assert(hashmap_info->signature == WizardSignature);
01805   if (hashmap_info->debug != WizardFalse)
01806     (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
01807   if (key == NULL)
01808     return((void *) NULL);
01809   LockSemaphoreInfo(hashmap_info->semaphore);
01810   hash=hashmap_info->hash(key);
01811   list_info=hashmap_info->map[hash % hashmap_info->capacity];
01812   if (list_info != (LinkedListInfo *) NULL)
01813     {
01814       list_info->next=list_info->head;
01815       entry=(EntryInfo *) GetNextValueInLinkedList(list_info);
01816       for (i=0; entry != (EntryInfo *) NULL; i++)
01817       {
01818         if (entry->hash == hash)
01819           {
01820             WizardBooleanType
01821               compare;
01822 
01823             compare=WizardTrue;
01824             if (hashmap_info->compare !=
01825                 (WizardBooleanType (*)(const void *,const void *)) NULL)
01826               compare=hashmap_info->compare(key,entry->key);
01827             if (compare == WizardTrue)
01828               {
01829                 entry=(EntryInfo *) RemoveElementFromLinkedList(list_info,i);
01830                 if (entry == (EntryInfo *) NULL)
01831                   {
01832                     UnlockSemaphoreInfo(hashmap_info->semaphore);
01833                     return((void *) NULL);
01834                   }
01835                 if (hashmap_info->relinquish_key != (void *(*)(void *)) NULL)
01836                   entry->key=hashmap_info->relinquish_key(entry->key);
01837                 value=entry->value;
01838                 entry=(EntryInfo *) RelinquishWizardMemory(entry);
01839                 hashmap_info->entries--;
01840                 UnlockSemaphoreInfo(hashmap_info->semaphore);
01841                 return(value);
01842               }
01843           }
01844         entry=(EntryInfo *) GetNextValueInLinkedList(list_info);
01845       }
01846     }
01847   UnlockSemaphoreInfo(hashmap_info->semaphore);
01848   return((void *) NULL);
01849 }
01850 
01851 /*
01852 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01853 %                                                                             %
01854 %                                                                             %
01855 %                                                                             %
01856 %   R e m o v e L a s t E l e m e n t F r o m L i n k e d L i s t             %
01857 %                                                                             %
01858 %                                                                             %
01859 %                                                                             %
01860 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01861 %
01862 %  RemoveLastElementFromLinkedList() removes the last element from the
01863 %  linked-list.
01864 %
01865 %  The format of the RemoveLastElementFromLinkedList method is:
01866 %
01867 %      void *RemoveLastElementFromLinkedList(LinkedListInfo *list_info)
01868 %
01869 %  A description of each parameter follows:
01870 %
01871 %    o list_info: The linked-list info.
01872 %
01873 */
01874 WizardExport void *RemoveLastElementFromLinkedList(LinkedListInfo *list_info)
01875 {
01876   void
01877     *value;
01878 
01879   assert(list_info != (LinkedListInfo *) NULL);
01880   assert(list_info->signature == WizardSignature);
01881   if (list_info->debug != WizardFalse)
01882     (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
01883   if (list_info->elements == 0)
01884     return((void *) NULL);
01885   LockSemaphoreInfo(list_info->semaphore);
01886   if (list_info->next == list_info->tail)
01887     list_info->next=(ElementInfo *) NULL;
01888   if (list_info->elements == 1UL)
01889     {
01890       value=list_info->head->value;
01891       list_info->head=(ElementInfo *) NULL;
01892       list_info->tail=(ElementInfo *) RelinquishWizardMemory(list_info->tail);
01893     }
01894   else
01895     {
01896       ElementInfo
01897         *next;
01898 
01899       value=list_info->tail->value;
01900       next=list_info->head;
01901       while (next->next != list_info->tail)
01902         next=next->next;
01903       list_info->tail=(ElementInfo *) RelinquishWizardMemory(list_info->tail);
01904       list_info->tail=next;
01905       next->next=(ElementInfo *) NULL;
01906     }
01907   list_info->elements--;
01908   UnlockSemaphoreInfo(list_info->semaphore);
01909   return(value);
01910 }
01911 
01912 /*
01913 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01914 %                                                                             %
01915 %                                                                             %
01916 %                                                                             %
01917 %   R e s e t H a s h m a p I t e r a t o r                                   %
01918 %                                                                             %
01919 %                                                                             %
01920 %                                                                             %
01921 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01922 %
01923 %  ResetHashmapIterator() resets the hash-map iterator.  Use it in conjunction
01924 %  with GetNextKeyInHashmap() to iterate over all the keys in the hash-map.
01925 %
01926 %  The format of the ResetHashmapIterator method is:
01927 %
01928 %      ResetHashmapIterator(HashmapInfo *hashmap_info)
01929 %
01930 %  A description of each parameter follows:
01931 %
01932 %    o hashmap_info: The hashmap info.
01933 %
01934 */
01935 WizardExport void ResetHashmapIterator(HashmapInfo *hashmap_info)
01936 {
01937   assert(hashmap_info != (HashmapInfo *) NULL);
01938   assert(hashmap_info->signature == WizardSignature);
01939   if (hashmap_info->debug != WizardFalse)
01940     (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
01941   LockSemaphoreInfo(hashmap_info->semaphore);
01942   hashmap_info->next=0;
01943   hashmap_info->head_of_list=WizardFalse;
01944   UnlockSemaphoreInfo(hashmap_info->semaphore);
01945 }
01946 
01947 /*
01948 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01949 %                                                                             %
01950 %                                                                             %
01951 %                                                                             %
01952 %   R e s e t L i n k e d L i s t I t e r a t o r                             %
01953 %                                                                             %
01954 %                                                                             %
01955 %                                                                             %
01956 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01957 %
01958 %  ResetLinkedListIterator() resets the lined-list iterator.  Use it in
01959 %  conjunction with GetNextValueInLinkedList() to iterate over all the values
01960 %  in the linked-list.
01961 %
01962 %  The format of the ResetLinkedListIterator method is:
01963 %
01964 %      ResetLinkedListIterator(LinkedListInfo *list_info)
01965 %
01966 %  A description of each parameter follows:
01967 %
01968 %    o list_info: The linked-list info.
01969 %
01970 */
01971 WizardExport void ResetLinkedListIterator(LinkedListInfo *list_info)
01972 {
01973   assert(list_info != (LinkedListInfo *) NULL);
01974   assert(list_info->signature == WizardSignature);
01975   if (list_info->debug != WizardFalse)
01976     (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
01977   LockSemaphoreInfo(list_info->semaphore);
01978   list_info->next=list_info->head;
01979   UnlockSemaphoreInfo(list_info->semaphore);
01980 }