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-2010 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 *) AcquireAlignedMemory(1,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 %  Specify the CompareHashmapString() method in NewHashmap() to find an entry
00253 %  in a hash-map based on the contents 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 %  Specify the CompareHashmapStringInfo() method in NewHashmap() to find an
00291 %  entry in a hash-map based on the 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 %  Specify the HashPointerType() method in NewHashmap() to find an entry
00866 %  in a hash-map based on the address of a 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 %  Specify the HashStringType() method in NewHashmap() to find an entry
00902 %  in a hash-map based on the contents of a 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 %                                                                             %
00954 %   H a s h S t r i n g I n f o T y p e                                       %
00955 %                                                                             %
00956 %                                                                             %
00957 %                                                                             %
00958 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00959 %
00960 %  Specify the HashStringInfoType() method in NewHashmap() to find an entry
00961 %  in a hash-map based on the contents of a string.
00962 %
00963 %  The format of the HashStringInfoType method is:
00964 %
00965 %      size_t HashStringInfoType(const void *string)
00966 %
00967 %  A description of each parameter follows:
00968 %
00969 %    o string: compute the hash entry location from this string.
00970 %
00971 */
00972 WizardExport size_t HashStringInfoType(const void *string)
00973 {
00974   register size_t
00975     i;
00976 
00977   size_t
00978     hash;
00979 
00980   StringInfo
00981     *message;
00982 
00983   unsigned char
00984     *datum;
00985 
00986   message=(StringInfo *) string;
00987   hash=0;
00988   datum=GetStringInfoDatum(message);
00989   for (i=0; i < GetStringInfoLength(message); i++)
00990     hash^=datum[i];
00991   return(hash);
00992 }
00993 
00994 /*
00995 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00996 %                                                                             %
00997 %                                                                             %
00998 %                                                                             %
00999 %   I n s e r t V a l u e I n L i n k e d L i s t                             %
01000 %                                                                             %
01001 %                                                                             %
01002 %                                                                             %
01003 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01004 %
01005 %  InsertValueInLinkedList() inserts an element in the linked-list at the
01006 %  specified location.
01007 %
01008 %  The format of the InsertValueInLinkedList method is:
01009 %
01010 %      WizardBooleanType InsertValueInLinkedList(ListInfo *list_info,
01011 %        const size_t index,const void *value)
01012 %
01013 %  A description of each parameter follows:
01014 %
01015 %    o list_info: The hashmap info.
01016 %
01017 %    o index: The index.
01018 %
01019 %    o value: The value.
01020 %
01021 */
01022 WizardExport WizardBooleanType InsertValueInLinkedList(
01023   LinkedListInfo *list_info,const size_t index,const void *value)
01024 {
01025   register ElementInfo
01026     *next;
01027 
01028   register ssize_t
01029     i;
01030 
01031   assert(list_info != (LinkedListInfo *) NULL);
01032   assert(list_info->signature == WizardSignature);
01033   if (list_info->debug != WizardFalse)
01034     (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
01035   if (value == NULL)
01036     return(WizardFalse);
01037   if ((index > list_info->elements) ||
01038       (list_info->elements == list_info->capacity))
01039     return(WizardFalse);
01040   next=(ElementInfo *) AcquireAlignedMemory(1,sizeof(*next));
01041   if (next == (ElementInfo *) NULL)
01042     return(WizardFalse);
01043   next->value=(void *) value;
01044   next->next=(ElementInfo *) NULL;
01045   LockSemaphoreInfo(list_info->semaphore);
01046   if (list_info->elements == 0)
01047     {
01048       if (list_info->next == (ElementInfo *) NULL)
01049         list_info->next=next;
01050       list_info->head=next;
01051       list_info->tail=next;
01052     }
01053   else
01054     {
01055       if (index == 0)
01056         {
01057           if (list_info->next == list_info->head)
01058             list_info->next=next;
01059           next->next=list_info->head;
01060           list_info->head=next;
01061         }
01062       else
01063         if (index == list_info->elements)
01064           {
01065             if (list_info->next == (ElementInfo *) NULL)
01066               list_info->next=next;
01067             list_info->tail->next=next;
01068             list_info->tail=next;
01069           }
01070         else
01071           {
01072             ElementInfo
01073               *element;
01074 
01075             element=list_info->head;
01076             next->next=element->next;
01077             for (i=1; i < (ssize_t) index; i++)
01078             {
01079               element=element->next;
01080               next->next=element->next;
01081             }
01082             next=next->next;
01083             element->next=next;
01084             if (list_info->next == next->next)
01085               list_info->next=next;
01086           }
01087     }
01088   list_info->elements++;
01089   UnlockSemaphoreInfo(list_info->semaphore);
01090   return(WizardTrue);
01091 }
01092 
01093 /*
01094 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01095 %                                                                             %
01096 %                                                                             %
01097 %                                                                             %
01098 %   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                 %
01099 %                                                                             %
01100 %                                                                             %
01101 %                                                                             %
01102 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01103 %
01104 %  InsertValueInSortedLinkedList() inserts a value in the sorted linked-list.
01105 %
01106 %  The format of the InsertValueInSortedLinkedList method is:
01107 %
01108 %      WizardBooleanType InsertValueInSortedLinkedList(ListInfo *list_info,
01109 %        int (*compare)(const void *,const void *),void **replace,
01110 %        const void *value)
01111 %
01112 %  A description of each parameter follows:
01113 %
01114 %    o list_info: The hashmap info.
01115 %
01116 %    o index: The index.
01117 %
01118 %    o compare: The compare method.
01119 %
01120 %    o replace: return previous element here.
01121 %
01122 %    o value: The value.
01123 %
01124 */
01125 WizardExport WizardBooleanType InsertValueInSortedLinkedList(
01126   LinkedListInfo *list_info,int (*compare)(const void *,const void *),
01127   void **replace,const void *value)
01128 {
01129   ElementInfo
01130     *element;
01131 
01132   register ElementInfo
01133     *next;
01134 
01135   register ssize_t
01136     i;
01137 
01138   assert(list_info != (LinkedListInfo *) NULL);
01139   assert(list_info->signature == WizardSignature);
01140   if (list_info->debug != WizardFalse)
01141     (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
01142   if ((compare == (int (*)(const void *,const void *)) NULL) ||
01143       (value == (const void *) NULL))
01144     return(WizardFalse);
01145   if (list_info->elements == list_info->capacity)
01146     return(WizardFalse);
01147   next=(ElementInfo *) AcquireAlignedMemory(1,sizeof(*next));
01148   if (next == (ElementInfo *) NULL)
01149     return(WizardFalse);
01150   next->value=(void *) value;
01151   element=(ElementInfo *) NULL;
01152   LockSemaphoreInfo(list_info->semaphore);
01153   next->next=list_info->head;
01154   while (next->next != (ElementInfo *) NULL)
01155   {
01156     i=compare(value,next->next->value);
01157     if ((i < 0) || ((replace != (void **) NULL) && (i == 0)))
01158       {
01159         if (i == 0)
01160           {
01161             *replace=next->next->value;
01162             next->next=next->next->next;
01163             if (element != (ElementInfo *) NULL)
01164               element->next=(ElementInfo *) RelinquishWizardMemory(
01165                 element->next);
01166             list_info->elements--;
01167           }
01168         if (element != (ElementInfo *) NULL)
01169           element->next=next;
01170         else
01171           list_info->head=next;
01172         break;
01173       }
01174     element=next->next;
01175     next->next=next->next->next;
01176   }
01177   if (next->next == (ElementInfo *) NULL)
01178     {
01179       if (element != (ElementInfo *) NULL)
01180         element->next=next;
01181       else
01182         list_info->head=next;
01183       list_info->tail=next;
01184     }
01185   list_info->elements++;
01186   UnlockSemaphoreInfo(list_info->semaphore);
01187   return(WizardTrue);
01188 }
01189 
01190 /*
01191 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01192 %                                                                             %
01193 %                                                                             %
01194 %                                                                             %
01195 %   I s H a s h m a p E m p t y                                               %
01196 %                                                                             %
01197 %                                                                             %
01198 %                                                                             %
01199 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01200 %
01201 %  IsHashmapEmpty() returns WizardTrue if the hash-map is empty.
01202 %
01203 %  The format of the IsHashmapEmpty method is:
01204 %
01205 %      WizardBooleanType IsHashmapEmpty(const HashmapInfo *hashmap_info)
01206 %
01207 %  A description of each parameter follows:
01208 %
01209 %    o hashmap_info: The hashmap info.
01210 %
01211 */
01212 WizardExport WizardBooleanType IsHashmapEmpty(const HashmapInfo *hashmap_info)
01213 {
01214   assert(hashmap_info != (HashmapInfo *) NULL);
01215   assert(hashmap_info->signature == WizardSignature);
01216   if (hashmap_info->debug != WizardFalse)
01217     (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
01218   return(hashmap_info->entries == 0 ? WizardTrue : WizardFalse);
01219 }
01220 
01221 /*
01222 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01223 %                                                                             %
01224 %                                                                             %
01225 %                                                                             %
01226 %   I s L i n k e d L i s t E m p t y                                         %
01227 %                                                                             %
01228 %                                                                             %
01229 %                                                                             %
01230 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01231 %
01232 %  IsLinkedListEmpty() returns WizardTrue if the linked-list is empty.
01233 %
01234 %  The format of the IsLinkedListEmpty method is:
01235 %
01236 %      WizardBooleanType IsLinkedListEmpty(LinkedListInfo *list_info)
01237 %
01238 %  A description of each parameter follows:
01239 %
01240 %    o list_info: The linked-list info.
01241 %
01242 */
01243 WizardExport WizardBooleanType IsLinkedListEmpty(
01244   const LinkedListInfo *list_info)
01245 {
01246   assert(list_info != (LinkedListInfo *) NULL);
01247   assert(list_info->signature == WizardSignature);
01248   if (list_info->debug != WizardFalse)
01249     (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
01250   return(list_info->elements == 0 ? WizardTrue : WizardFalse);
01251 }
01252 
01253 /*
01254 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01255 %                                                                             %
01256 %                                                                             %
01257 %                                                                             %
01258 %   L i n k e d L i s t T o A r r a y                                         %
01259 %                                                                             %
01260 %                                                                             %
01261 %                                                                             %
01262 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01263 %
01264 %  LinkedListToArray() converts the linked-list to an array.
01265 %
01266 %  The format of the LinkedListToArray method is:
01267 %
01268 %      WizardBooleanType LinkedListToArray(LinkedListInfo *list_info,
01269 %        void **array)
01270 %
01271 %  A description of each parameter follows:
01272 %
01273 %    o list_info: The linked-list info.
01274 %
01275 %    o array: The array.
01276 %
01277 */
01278 WizardExport WizardBooleanType LinkedListToArray(LinkedListInfo *list_info,
01279   void **array)
01280 {
01281   register ElementInfo
01282     *next;
01283 
01284   register ssize_t
01285     i;
01286 
01287   assert(list_info != (LinkedListInfo *) NULL);
01288   assert(list_info->signature == WizardSignature);
01289   if (list_info->debug != WizardFalse)
01290     (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
01291   if (array == (void **) NULL)
01292     return(WizardFalse);
01293   LockSemaphoreInfo(list_info->semaphore);
01294   next=list_info->head;
01295   for (i=0; next != (ElementInfo *) NULL; i++)
01296   {
01297     array[i]=next->value;
01298     next=next->next;
01299   }
01300   UnlockSemaphoreInfo(list_info->semaphore);
01301   return(WizardTrue);
01302 }
01303 
01304 /*
01305 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01306 %                                                                             %
01307 %                                                                             %
01308 %                                                                             %
01309 %   N e w H a s h m a p                                                       %
01310 %                                                                             %
01311 %                                                                             %
01312 %                                                                             %
01313 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01314 %
01315 %  NewHashmap() returns a pointer to a HashmapInfo structure initialized
01316 %  to default values.  The capacity is an initial estimate.  The hashmap will
01317 %  increase capacity dynamically as the demand requires.
01318 %
01319 %  The format of the NewHashmap method is:
01320 %
01321 %      HashmapInfo *NewHashmap(const size_t capacity,
01322 %        size_t (*hash)(const void *),
01323 %        WizardBooleanType (*compare)(const void *,const void *),
01324 %        void *(*relinquish_key)(void *),void *(*relinquish_value)(void *))
01325 %
01326 %  A description of each parameter follows:
01327 %
01328 %    o capacity: The initial number entries in the hash-map: typically
01329 %      SmallHashmapSize, MediumHashmapSize, or LargeHashmapSize.  The
01330 %      hashmap will dynamically increase its capacity on demand.
01331 %
01332 %    o hash: The hash method, typically HashPointerType(), HashStringType(),
01333 %      or HashStringInfoType().
01334 %
01335 %    o compare: The compare method, typically NULL, CompareHashmapString(),
01336 %      or CompareHashmapStringInfo().
01337 %
01338 %    o relinquish_key: The key deallocation method, typically
01339 %      RelinquishWizardMemory(), called whenever a key is removed from the
01340 %      hash-map.
01341 %
01342 %    o relinquish_value: The value deallocation method;  typically
01343 %      RelinquishWizardMemory(), called whenever a value object is removed from
01344 %      the hash-map.
01345 %
01346 */
01347 WizardExport HashmapInfo *NewHashmap(const size_t capacity,
01348   size_t (*hash)(const void *),
01349   WizardBooleanType (*compare)(const void *,const void *),
01350   void *(*relinquish_key)(void *),void *(*relinquish_value)(void *))
01351 {
01352   HashmapInfo
01353     *hashmap_info;
01354 
01355   hashmap_info=(HashmapInfo *) AcquireAlignedMemory(1,sizeof(*hashmap_info));
01356   if (hashmap_info == (HashmapInfo *) NULL)
01357     ThrowWizardFatalError(CacheDomain,MemoryError);
01358   (void) ResetWizardMemory(hashmap_info,0,sizeof(*hashmap_info));
01359   hashmap_info->hash=HashPointerType;
01360   if (hash != (size_t (*)(const void *)) NULL)
01361     hashmap_info->hash=hash;
01362   hashmap_info->compare=(WizardBooleanType (*)(const void *,const void *)) NULL;
01363   if (compare != (WizardBooleanType (*)(const void *,const void *)) NULL)
01364     hashmap_info->compare=compare;
01365   hashmap_info->relinquish_key=relinquish_key;
01366   hashmap_info->relinquish_value=relinquish_value;
01367   hashmap_info->entries=0;
01368   hashmap_info->capacity=capacity;
01369   hashmap_info->map=(LinkedListInfo **) AcquireQuantumMemory((size_t)
01370     capacity+1UL,sizeof(*hashmap_info->map));
01371   if (hashmap_info->map == (LinkedListInfo **) NULL)
01372     ThrowWizardFatalError(CacheDomain,MemoryError);
01373   (void) ResetWizardMemory(hashmap_info->map,0,(size_t) capacity*
01374     sizeof(*hashmap_info->map));
01375   hashmap_info->debug=IsEventLogging();
01376   hashmap_info->semaphore=AllocateSemaphoreInfo();
01377   hashmap_info->signature=WizardSignature;
01378   return(hashmap_info);
01379 }
01380 
01381 /*
01382 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01383 %                                                                             %
01384 %                                                                             %
01385 %                                                                             %
01386 %   N e w L i n k e d L i s t I n f o                                         %
01387 %                                                                             %
01388 %                                                                             %
01389 %                                                                             %
01390 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01391 %
01392 %  NewLinkedList() returns a pointer to a LinkedListInfo structure
01393 %  initialized to default values.
01394 %
01395 %  The format of the Acquirestruct LinkedListInfomethod is:
01396 %
01397 %      LinkedListInfo *NewLinkedList(const size_t capacity)
01398 %
01399 %  A description of each parameter follows:
01400 %
01401 %    o capacity: The maximum number of elements in the list.
01402 %
01403 */
01404 WizardExport LinkedListInfo *NewLinkedList(const size_t capacity)
01405 {
01406   LinkedListInfo
01407     *list_info;
01408 
01409   list_info=(LinkedListInfo *) AcquireAlignedMemory(1,sizeof(*list_info));
01410   if (list_info == (LinkedListInfo *) NULL)
01411     ThrowWizardFatalError(CacheDomain,MemoryError);
01412   (void) ResetWizardMemory(list_info,0,sizeof(*list_info));
01413   list_info->capacity=capacity == 0 ? (size_t) (~0) : capacity;
01414   list_info->elements=0;
01415   list_info->head=(ElementInfo *) NULL;
01416   list_info->tail=(ElementInfo *) NULL;
01417   list_info->next=(ElementInfo *) NULL;
01418   list_info->debug=WizardFalse;
01419   list_info->semaphore=AllocateSemaphoreInfo();
01420   list_info->signature=WizardSignature;
01421   return(list_info);
01422 }
01423 
01424 /*
01425 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01426 %                                                                             %
01427 %                                                                             %
01428 %                                                                             %
01429 %   P u t E n t r y I n H a s h m a p                                         %
01430 %                                                                             %
01431 %                                                                             %
01432 %                                                                             %
01433 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01434 %
01435 %  PutEntryInHashmap() puts an entry in the hash-map.  If the key already
01436 %  exists in the map it is first removed.
01437 %
01438 %  The format of the PutEntryInHashmap method is:
01439 %
01440 %      WizardBooleanType PutEntryInHashmap(HashmapInfo *hashmap_info,
01441 %        const void *key,const void *value)
01442 %
01443 %  A description of each parameter follows:
01444 %
01445 %    o hashmap_info: The hashmap info.
01446 %
01447 %    o key: The key.
01448 %
01449 %    o value: The value.
01450 %
01451 */
01452 
01453 static WizardBooleanType IncreaseHashmapCapacity(HashmapInfo *hashmap_info)
01454 {
01455 #define MaxCapacities  20
01456 
01457   const size_t
01458     capacities[MaxCapacities] =
01459     {
01460       17, 31, 61, 131, 257, 509, 1021, 2053, 4099, 8191, 16381, 32771,
01461       65537, 131071, 262147, 524287, 1048573, 2097143, 4194301, 8388617
01462     };
01463 
01464   ElementInfo
01465     *element;
01466 
01467   EntryInfo
01468     *entry;
01469 
01470   LinkedListInfo
01471     *list_info,
01472     *map_info,
01473     **map;
01474 
01475   register ElementInfo
01476     *next;
01477 
01478   register ssize_t
01479     i;
01480 
01481   size_t
01482     capacity;
01483 
01484   /*
01485     Increase to the next prime capacity.
01486   */
01487   for (i=0; i < MaxCapacities; i++)
01488     if (hashmap_info->capacity < capacities[i])
01489       break;
01490   if (i >= (MaxCapacities-1))
01491     return(WizardFalse);
01492   capacity=capacities[i+1];
01493   map=(LinkedListInfo **) AcquireQuantumMemory((size_t) capacity+1UL,
01494     sizeof(*map));
01495   if (map == (LinkedListInfo **) NULL)
01496     return(WizardFalse);
01497   (void) ResetWizardMemory(map,0,(size_t) capacity*sizeof(*map));
01498   /*
01499     Copy entries to new hashmap with increased capacity.
01500   */
01501   for (i=0; i < (ssize_t) hashmap_info->capacity; i++)
01502   {
01503     list_info=hashmap_info->map[i];
01504     if (list_info == (LinkedListInfo *) NULL)
01505       continue;
01506     LockSemaphoreInfo(list_info->semaphore);
01507     for (next=list_info->head; next != (ElementInfo *) NULL; )
01508     {
01509       element=next;
01510       next=next->next;
01511       entry=(EntryInfo *) element->value;
01512       map_info=map[entry->hash % capacity];
01513       if (map_info == (LinkedListInfo *) NULL)
01514         {
01515           map_info=NewLinkedList(0);
01516           map[entry->hash % capacity]=map_info;
01517         }
01518       map_info->next=element;
01519       element->next=map_info->head;
01520       map_info->head=element;
01521       map_info->elements++;
01522     }
01523     list_info->signature=(~WizardSignature);
01524     UnlockSemaphoreInfo(list_info->semaphore);
01525     DestroySemaphoreInfo(&list_info->semaphore);
01526     list_info=(LinkedListInfo *) RelinquishWizardMemory(list_info);
01527   }
01528   hashmap_info->map=(LinkedListInfo **) RelinquishWizardMemory(hashmap_info->map);
01529   hashmap_info->map=map;
01530   hashmap_info->capacity=capacity;
01531   return(WizardTrue);
01532 }
01533 
01534 WizardExport WizardBooleanType PutEntryInHashmap(HashmapInfo *hashmap_info,
01535   const void *key,const void *value)
01536 {
01537   EntryInfo
01538     *entry,
01539     *next;
01540 
01541   LinkedListInfo
01542     *list_info;
01543 
01544   register size_t
01545     i;
01546 
01547   assert(hashmap_info != (HashmapInfo *) NULL);
01548   assert(hashmap_info->signature == WizardSignature);
01549   if (hashmap_info->debug != WizardFalse)
01550     (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
01551   if ((key == (void *) NULL) || (value == (void *) NULL))
01552     return(WizardFalse);
01553   next=(EntryInfo *) AcquireAlignedMemory(1,sizeof(*next));
01554   if (next == (EntryInfo *) NULL)
01555     return(WizardFalse);
01556   LockSemaphoreInfo(hashmap_info->semaphore);
01557   next->hash=hashmap_info->hash(key);
01558   next->key=(void *) key;
01559   next->value=(void *) value;
01560   list_info=hashmap_info->map[next->hash % hashmap_info->capacity];
01561   if (list_info == (LinkedListInfo *) NULL)
01562     {
01563       list_info=NewLinkedList(0);
01564       hashmap_info->map[next->hash % hashmap_info->capacity]=list_info;
01565     }
01566   else
01567     {
01568       list_info->next=list_info->head;
01569       entry=(EntryInfo *) GetNextValueInLinkedList(list_info);
01570       for (i=0; entry != (EntryInfo *) NULL; i++)
01571       {
01572         if (entry->hash == next->hash)
01573           {
01574             WizardBooleanType
01575               compare;
01576 
01577             compare=WizardTrue;
01578             if (hashmap_info->compare !=
01579                 (WizardBooleanType (*)(const void *,const void *)) NULL)
01580               compare=hashmap_info->compare(key,entry->key);
01581             if (compare == WizardTrue)
01582               {
01583                 (void) RemoveElementFromLinkedList(list_info,i);
01584                 if (hashmap_info->relinquish_key != (void *(*)(void *)) NULL)
01585                   entry->key=hashmap_info->relinquish_key(entry->key);
01586                 if (hashmap_info->relinquish_value != (void *(*)(void *)) NULL)
01587                   entry->value=hashmap_info->relinquish_value(entry->value);
01588                 entry=(EntryInfo *) RelinquishWizardMemory(entry);
01589                 break;
01590               }
01591           }
01592         entry=(EntryInfo *) GetNextValueInLinkedList(list_info);
01593       }
01594     }
01595   if (InsertValueInLinkedList(list_info,0,next) == WizardFalse)
01596     {
01597       next=(EntryInfo *) RelinquishWizardMemory(next);
01598       UnlockSemaphoreInfo(hashmap_info->semaphore);
01599       return(WizardFalse);
01600     }
01601   if (list_info->elements >= (hashmap_info->capacity-1))
01602     if (IncreaseHashmapCapacity(hashmap_info) == WizardFalse)
01603       {
01604         UnlockSemaphoreInfo(hashmap_info->semaphore);
01605         return(WizardFalse);
01606       }
01607   hashmap_info->entries++;
01608   UnlockSemaphoreInfo(hashmap_info->semaphore);
01609   return(WizardTrue);
01610 }
01611 
01612 /*
01613 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01614 %                                                                             %
01615 %                                                                             %
01616 %                                                                             %
01617 %   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       %
01618 %                                                                             %
01619 %                                                                             %
01620 %                                                                             %
01621 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01622 %
01623 %  RemoveElementByValueFromLinkedList() removes an element from the linked-list
01624 %  by value.
01625 %
01626 %  The format of the RemoveElementByValueFromLinkedList method is:
01627 %
01628 %      void *RemoveElementByValueFromLinkedList(LinkedListInfo *list_info,
01629 %        const void *value)
01630 %
01631 %  A description of each parameter follows:
01632 %
01633 %    o list_info: The list info.
01634 %
01635 %    o value: The value.
01636 %
01637 */
01638 WizardExport void *RemoveElementByValueFromLinkedList(LinkedListInfo *list_info,
01639   const void *value)
01640 {
01641   ElementInfo
01642     *next;
01643 
01644   assert(list_info != (LinkedListInfo *) NULL);
01645   assert(list_info->signature == WizardSignature);
01646   if (list_info->debug != WizardFalse)
01647     (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
01648   if ((list_info->elements == 0) || (value == NULL))
01649     return((void *) NULL);
01650   LockSemaphoreInfo(list_info->semaphore);
01651   if (value == list_info->head->value)
01652     {
01653       if (list_info->next == list_info->head)
01654         list_info->next=list_info->head->next;
01655       next=list_info->head;
01656       list_info->head=list_info->head->next;
01657       next=(ElementInfo *) RelinquishWizardMemory(next);
01658     }
01659   else
01660     {
01661       ElementInfo
01662         *element;
01663 
01664       next=list_info->head;
01665       while ((next->next != (ElementInfo *) NULL) &&
01666              (next->next->value != value))
01667         next=next->next;
01668       if (next->next == (ElementInfo *) NULL)
01669         {
01670           UnlockSemaphoreInfo(list_info->semaphore);
01671           return((void *) NULL);
01672         }
01673       element=next->next;
01674       next->next=element->next;
01675       if (element == list_info->tail)
01676         list_info->tail=next;
01677       if (list_info->next == element)
01678         list_info->next=element->next;
01679       element=(ElementInfo *) RelinquishWizardMemory(element);
01680     }
01681   list_info->elements--;
01682   UnlockSemaphoreInfo(list_info->semaphore);
01683   return((void *) value);
01684 }
01685 
01686 /*
01687 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01688 %                                                                             %
01689 %                                                                             %
01690 %                                                                             %
01691 %   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                     %
01692 %                                                                             %
01693 %                                                                             %
01694 %                                                                             %
01695 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01696 %
01697 %  RemoveElementFromLinkedList() removes an element from the linked-list at the
01698 %  specified location.
01699 %
01700 %  The format of the RemoveElementFromLinkedList method is:
01701 %
01702 %      void *RemoveElementFromLinkedList(LinkedListInfo *list_info,
01703 %        const size_t index)
01704 %
01705 %  A description of each parameter follows:
01706 %
01707 %    o list_info: The linked-list info.
01708 %
01709 %    o index: The index.
01710 %
01711 */
01712 WizardExport void *RemoveElementFromLinkedList(LinkedListInfo *list_info,
01713   const size_t index)
01714 {
01715   ElementInfo
01716     *next;
01717 
01718   register ssize_t
01719     i;
01720 
01721   void
01722     *value;
01723 
01724   assert(list_info != (LinkedListInfo *) NULL);
01725   assert(list_info->signature == WizardSignature);
01726   if (list_info->debug != WizardFalse)
01727     (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
01728   if (index >= list_info->elements)
01729     return((void *) NULL);
01730   LockSemaphoreInfo(list_info->semaphore);
01731   if (index == 0)
01732     {
01733       if (list_info->next == list_info->head)
01734         list_info->next=list_info->head->next;
01735       value=list_info->head->value;
01736       next=list_info->head;
01737       list_info->head=list_info->head->next;
01738       next=(ElementInfo *) RelinquishWizardMemory(next);
01739     }
01740   else
01741     {
01742       ElementInfo
01743         *element;
01744 
01745       next=list_info->head;
01746       for (i=1; i < (ssize_t) index; i++)
01747         next=next->next;
01748       element=next->next;
01749       next->next=element->next;
01750       if (element == list_info->tail)
01751         list_info->tail=next;
01752       if (list_info->next == element)
01753         list_info->next=element->next;
01754       value=element->value;
01755       element=(ElementInfo *) RelinquishWizardMemory(element);
01756     }
01757   list_info->elements--;
01758   UnlockSemaphoreInfo(list_info->semaphore);
01759   return(value);
01760 }
01761 
01762 /*
01763 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01764 %                                                                             %
01765 %                                                                             %
01766 %                                                                             %
01767 %   R e m o v e E n t r y F r o m H a s h m a p                               %
01768 %                                                                             %
01769 %                                                                             %
01770 %                                                                             %
01771 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01772 %
01773 %  RemoveEntryFromHashmap() removes an entry from the hash-map by its key.
01774 %
01775 %  The format of the RemoveEntryFromHashmap method is:
01776 %
01777 %      void *RemoveEntryFromHashmap(HashmapInfo *hashmap_info,void *key)
01778 %
01779 %  A description of each parameter follows:
01780 %
01781 %    o hashmap_info: The hashmap info.
01782 %
01783 %    o key: The key.
01784 %
01785 */
01786 WizardExport void *RemoveEntryFromHashmap(HashmapInfo *hashmap_info,
01787   const void *key)
01788 {
01789   EntryInfo
01790     *entry;
01791 
01792   LinkedListInfo
01793     *list_info;
01794 
01795   register size_t
01796     i;
01797 
01798   size_t
01799     hash;
01800 
01801   void
01802     *value;
01803 
01804   assert(hashmap_info != (HashmapInfo *) NULL);
01805   assert(hashmap_info->signature == WizardSignature);
01806   if (hashmap_info->debug != WizardFalse)
01807     (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
01808   if (key == NULL)
01809     return((void *) NULL);
01810   LockSemaphoreInfo(hashmap_info->semaphore);
01811   hash=hashmap_info->hash(key);
01812   list_info=hashmap_info->map[hash % hashmap_info->capacity];
01813   if (list_info != (LinkedListInfo *) NULL)
01814     {
01815       list_info->next=list_info->head;
01816       entry=(EntryInfo *) GetNextValueInLinkedList(list_info);
01817       for (i=0; entry != (EntryInfo *) NULL; i++)
01818       {
01819         if (entry->hash == hash)
01820           {
01821             WizardBooleanType
01822               compare;
01823 
01824             compare=WizardTrue;
01825             if (hashmap_info->compare !=
01826                 (WizardBooleanType (*)(const void *,const void *)) NULL)
01827               compare=hashmap_info->compare(key,entry->key);
01828             if (compare == WizardTrue)
01829               {
01830                 entry=(EntryInfo *) RemoveElementFromLinkedList(list_info,i);
01831                 if (entry == (EntryInfo *) NULL)
01832                   {
01833                     UnlockSemaphoreInfo(hashmap_info->semaphore);
01834                     return((void *) NULL);
01835                   }
01836                 if (hashmap_info->relinquish_key != (void *(*)(void *)) NULL)
01837                   entry->key=hashmap_info->relinquish_key(entry->key);
01838                 value=entry->value;
01839                 entry=(EntryInfo *) RelinquishWizardMemory(entry);
01840                 hashmap_info->entries--;
01841                 UnlockSemaphoreInfo(hashmap_info->semaphore);
01842                 return(value);
01843               }
01844           }
01845         entry=(EntryInfo *) GetNextValueInLinkedList(list_info);
01846       }
01847     }
01848   UnlockSemaphoreInfo(hashmap_info->semaphore);
01849   return((void *) NULL);
01850 }
01851 
01852 /*
01853 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01854 %                                                                             %
01855 %                                                                             %
01856 %                                                                             %
01857 %   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             %
01858 %                                                                             %
01859 %                                                                             %
01860 %                                                                             %
01861 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01862 %
01863 %  RemoveLastElementFromLinkedList() removes the last element from the
01864 %  linked-list.
01865 %
01866 %  The format of the RemoveLastElementFromLinkedList method is:
01867 %
01868 %      void *RemoveLastElementFromLinkedList(LinkedListInfo *list_info)
01869 %
01870 %  A description of each parameter follows:
01871 %
01872 %    o list_info: The linked-list info.
01873 %
01874 */
01875 WizardExport void *RemoveLastElementFromLinkedList(LinkedListInfo *list_info)
01876 {
01877   void
01878     *value;
01879 
01880   assert(list_info != (LinkedListInfo *) NULL);
01881   assert(list_info->signature == WizardSignature);
01882   if (list_info->debug != WizardFalse)
01883     (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
01884   if (list_info->elements == 0)
01885     return((void *) NULL);
01886   LockSemaphoreInfo(list_info->semaphore);
01887   if (list_info->next == list_info->tail)
01888     list_info->next=(ElementInfo *) NULL;
01889   if (list_info->elements == 1UL)
01890     {
01891       value=list_info->head->value;
01892       list_info->head=(ElementInfo *) NULL;
01893       list_info->tail=(ElementInfo *) RelinquishWizardMemory(list_info->tail);
01894     }
01895   else
01896     {
01897       ElementInfo
01898         *next;
01899 
01900       value=list_info->tail->value;
01901       next=list_info->head;
01902       while (next->next != list_info->tail)
01903         next=next->next;
01904       list_info->tail=(ElementInfo *) RelinquishWizardMemory(list_info->tail);
01905       list_info->tail=next;
01906       next->next=(ElementInfo *) NULL;
01907     }
01908   list_info->elements--;
01909   UnlockSemaphoreInfo(list_info->semaphore);
01910   return(value);
01911 }
01912 
01913 /*
01914 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01915 %                                                                             %
01916 %                                                                             %
01917 %                                                                             %
01918 %   R e s e t H a s h m a p I t e r a t o r                                   %
01919 %                                                                             %
01920 %                                                                             %
01921 %                                                                             %
01922 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01923 %
01924 %  ResetHashmapIterator() resets the hash-map iterator.  Use it in conjunction
01925 %  with GetNextKeyInHashmap() to iterate over all the keys in the hash-map.
01926 %
01927 %  The format of the ResetHashmapIterator method is:
01928 %
01929 %      ResetHashmapIterator(HashmapInfo *hashmap_info)
01930 %
01931 %  A description of each parameter follows:
01932 %
01933 %    o hashmap_info: The hashmap info.
01934 %
01935 */
01936 WizardExport void ResetHashmapIterator(HashmapInfo *hashmap_info)
01937 {
01938   assert(hashmap_info != (HashmapInfo *) NULL);
01939   assert(hashmap_info->signature == WizardSignature);
01940   if (hashmap_info->debug != WizardFalse)
01941     (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
01942   LockSemaphoreInfo(hashmap_info->semaphore);
01943   hashmap_info->next=0;
01944   hashmap_info->head_of_list=WizardFalse;
01945   UnlockSemaphoreInfo(hashmap_info->semaphore);
01946 }
01947 
01948 /*
01949 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01950 %                                                                             %
01951 %                                                                             %
01952 %                                                                             %
01953 %   R e s e t L i n k e d L i s t I t e r a t o r                             %
01954 %                                                                             %
01955 %                                                                             %
01956 %                                                                             %
01957 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01958 %
01959 %  ResetLinkedListIterator() resets the lined-list iterator.  Use it in
01960 %  conjunction with GetNextValueInLinkedList() to iterate over all the values
01961 %  in the linked-list.
01962 %
01963 %  The format of the ResetLinkedListIterator method is:
01964 %
01965 %      ResetLinkedListIterator(LinkedListInfo *list_info)
01966 %
01967 %  A description of each parameter follows:
01968 %
01969 %    o list_info: The linked-list info.
01970 %
01971 */
01972 WizardExport void ResetLinkedListIterator(LinkedListInfo *list_info)
01973 {
01974   assert(list_info != (LinkedListInfo *) NULL);
01975   assert(list_info->signature == WizardSignature);
01976   if (list_info->debug != WizardFalse)
01977     (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
01978   LockSemaphoreInfo(list_info->semaphore);
01979   list_info->next=list_info->head;
01980   UnlockSemaphoreInfo(list_info->semaphore);
01981 }
Generated by  doxygen 1.6.2-20100208