00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
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
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
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
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
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
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
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
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
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
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
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
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
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
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
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
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
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
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
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
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
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
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
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
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
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
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
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
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
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
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
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
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
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
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
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
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
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
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
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
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
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
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
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
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
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
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
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344
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
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399
01400
01401
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
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440
01441
01442
01443
01444
01445
01446
01447
01448
01449
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
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
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
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632
01633
01634
01635
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
01692
01693
01694
01695
01696
01697
01698
01699
01700
01701
01702
01703
01704
01705
01706
01707
01708
01709
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
01768
01769
01770
01771
01772
01773
01774
01775
01776
01777
01778
01779
01780
01781
01782
01783
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
01858
01859
01860
01861
01862
01863
01864
01865
01866
01867
01868
01869
01870
01871
01872
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
01919
01920
01921
01922
01923
01924
01925
01926
01927
01928
01929
01930
01931
01932
01933
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
01954
01955
01956
01957
01958
01959
01960
01961
01962
01963
01964
01965
01966
01967
01968
01969
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 }