|
WizardsToolkit
1.0.7
|
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 }