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 #include <assert.h>
00034 #include <stdlib.h>
00035 #include <string.h>
00036 #include "list.h"
00037 #include "mempool.h"
00038 #include "ram.h"
00039 #include "crc32.h"
00040
00041
00042
00043
00044 #ifdef DO_TIMER
00045 #include "timer.h"
00046
00047 TIMER_VARS(List_Ram);
00048 TIMER_VARS(List_RadixWalk);
00049 TIMER_VARS(List_RadixInit);
00050
00051 #else
00052
00053 #define TIMER_P(x)
00054 #define TIMER_Q(X)
00055
00056 #endif // DO_TIMER
00057
00058 #ifdef _DEBUG
00059 #define Debug(func) func;
00060 #define DebugAlert() do { __asm { int 03h } } while(0)
00061 #else
00062 #define Debug(func)
00063 #define DebugAlert()
00064 #endif
00065
00066 #define MemAlloc(size) geRam_AllocateClear(size)
00067 #define MemFree(mem) geRam_Free(mem)
00068
00069 #ifdef DO_TIMER // {
00070 #undef new
00071 #define new(type) mymalloc(sizeof(type))
00072 #undef destroy
00073 #define destroy(mem) if ( mem ) myfree(mem)
00074
00075 void * mymalloc(int size)
00076 {
00077 void *ret;
00078 TIMER_P(List_Ram);
00079 ret = MemAlloc(size);
00080 TIMER_Q(List_Ram);
00081 return ret;
00082 }
00083 void myfree(void *mem)
00084 {
00085 TIMER_P(List_Ram);
00086 MemFree(mem);
00087 TIMER_Q(List_Ram);
00088 }
00089
00090 #undef MemAlloc
00091 #define MemAlloc mymalloc
00092 #undef MemFree
00093 #define MemFree myfree
00094
00095 #else // }{ DO_TIMER
00096
00097 #undef new
00098 #define new(type) MemAlloc(sizeof(type))
00099 #undef destroy
00100 #define destroy(mem) if ( mem ) MemFree(mem)
00101
00102 #endif // } DO_TIMER
00103
00104
00105
00106 static MemPool *ListPool_g = NULL, *LinkPool_g = NULL, *HashNodePool_g = NULL;
00107 static int UsageCount = 0;
00108
00109
00110
00111 int LN_ListLen(LinkNode *pList)
00112 {
00113 LinkNode *pNode;
00114 int Len=0;
00115 if ( ! pList )
00116 return 0;
00117 LN_Walk(pNode,pList) {
00118 Len++;
00119 }
00120 return Len;
00121 }
00122
00123 LinkNode * LISTCALL LN_CutHead(LinkNode *pList)
00124 {
00125 LinkNode * LN;
00126 assert(pList);
00127 LN = pList->Next;
00128 if ( LN == pList ) return NULL;
00129 LN_Cut(LN);
00130 return LN;
00131 }
00132
00133 LinkNode * LISTCALL LN_CutTail(LinkNode *pList)
00134 {
00135 LinkNode * LN;
00136 assert(pList);
00137 LN = pList->Prev;
00138 if ( LN == pList ) return NULL;
00139 LN_Cut(LN);
00140 return LN;
00141 }
00142
00143
00144
00145 struct List
00146 {
00147 List *Next,*Prev;
00148 void * Data;
00149 };
00150
00151 void LISTCALL List_Destroy(List * pList)
00152 {
00153 List * pNode;
00154 assert(pList);
00155 pNode = pList->Next;
00156 while( pNode != pList )
00157 {
00158 List *Next;
00159 Next = pNode->Next;
00160 MemPool_FreeHunk(ListPool_g,pNode);
00161 pNode = Next;
00162 }
00163 MemPool_FreeHunk(ListPool_g,pList);
00164 }
00165
00166 List * LISTCALL List_Create(void)
00167 {
00168 List * pNew;
00169
00170 pNew = MemPool_GetHunk(ListPool_g);
00171 assert(pNew);
00172 pNew->Data = NULL;
00173 pNew->Next = pNew->Prev = pNew;
00174 return pNew;
00175 }
00176
00177 List * LISTCALL List_AddTail(List *pList,void * Data)
00178 {
00179 List * pNew;
00180
00181 pNew = MemPool_GetHunk(ListPool_g);
00182 assert(pNew);
00183
00184 pNew->Next = pList;
00185 pNew->Prev = pList->Prev;
00186 pNew->Next->Prev = pNew;
00187 pNew->Prev->Next = pNew;
00188
00189 pNew->Data= Data;
00190 return pNew;
00191 }
00192
00193 List * LISTCALL List_AddHead(List *pList,void * Data)
00194 {
00195 List * pNew;
00196
00197 pNew = MemPool_GetHunk(ListPool_g);
00198 assert(pNew);
00199 pNew->Data= Data;
00200
00201 pNew->Prev = pList;
00202 pNew->Next = pList->Next;
00203 pNew->Next->Prev = pNew;
00204 pNew->Prev->Next = pNew;
00205 return pNew;
00206 }
00207
00208 void * LISTCALL List_CutHead(List *pList)
00209 {
00210 List * pNode;
00211 void * pData;
00212 pNode = pList->Next;
00213 if ( pNode == pList ) return NULL;
00214 pData = pNode->Data;
00215
00216 pList->Next = pNode->Next;
00217 pList->Next->Prev = pList;
00218
00219 MemPool_FreeHunk(ListPool_g,pNode);
00220
00221 return pData;
00222 }
00223
00224 void * LISTCALL List_CutTail(List *pList)
00225 {
00226 List * pNode;
00227 void * pData;
00228 pNode = pList->Prev;
00229 if ( pNode == pList ) return NULL;
00230 pData = pNode->Data;
00231
00232 pList->Prev = pNode->Prev;
00233 pList->Prev->Next = pList;
00234
00235 MemPool_FreeHunk(ListPool_g,pNode);
00236
00237 return pData;
00238 }
00239
00240
00241 void * LISTCALL List_PeekHead(List *pList)
00242 {
00243 List * pNode;
00244 pNode = pList->Next;
00245 if ( pNode == pList ) return NULL;
00246 return pNode->Data;
00247 }
00248
00249 void * LISTCALL List_PeekTail(List *pList)
00250 {
00251 List * pNode;
00252 pNode = pList->Prev;
00253 if ( pNode == pList ) return NULL;
00254 return pNode->Data;
00255 }
00256
00257 void LISTCALL List_CutNode(List *pNode)
00258 {
00259 pNode->Prev->Next = pNode->Next;
00260 pNode->Next->Prev = pNode->Prev;
00261
00262 pNode->Next = pNode->Prev = pNode;
00263 }
00264
00265 void LISTCALL List_DeleteNode(List *pNode)
00266 {
00267 List_CutNode(pNode);
00268 List_FreeNode(pNode);
00269 }
00270
00271 void LISTCALL List_FreeNode(List *pNode)
00272 {
00273 assert(pNode);
00274 MemPool_FreeHunk(ListPool_g,pNode);
00275 }
00276
00277 void * LISTCALL List_NodeData(List *pNode)
00278 {
00279 assert(pNode);
00280 return pNode->Data;
00281 }
00282
00283 List * LISTCALL List_Next(List *pNode)
00284 {
00285 return pNode->Next;
00286 }
00287 List * LISTCALL List_Prev(List *pNode)
00288 {
00289 return pNode->Prev;
00290 }
00291
00292 List * List_Find(List *pList,void *Data)
00293 {
00294 List *pNode;
00295 assert(pList);
00296 for(pNode = pList->Next; pNode != pList; pNode = pNode->Next )
00297 {
00298 if ( pNode->Data == Data )
00299 return pNode;
00300 }
00301 return NULL;
00302 }
00303
00304
00305
00306
00307 struct Link
00308 {
00309 Link * Next;
00310 void * Data;
00311 };
00312
00313 void LISTCALL Link_Destroy(Link * pLink)
00314 {
00315 while( pLink )
00316 {
00317 Link *Next;
00318 Next = pLink->Next;
00319 MemPool_FreeHunk(LinkPool_g,pLink);
00320 pLink = Next;
00321 }
00322 }
00323
00324 Link * LISTCALL Link_Create(void)
00325 {
00326 Link * pLink;
00327 pLink = MemPool_GetHunk(LinkPool_g);
00328 assert(pLink);
00329 pLink->Next = NULL;
00330 pLink->Data = NULL;
00331 return pLink;
00332 }
00333
00334 void LISTCALL Link_Push(Link *pLink,void * Data)
00335 {
00336 Link * pNode;
00337 assert(pLink);
00338 pNode = MemPool_GetHunk(LinkPool_g);
00339 assert(pNode);
00340
00341
00342 pNode->Data = Data;
00343
00344 pNode->Next = pLink->Next;
00345 pLink->Next = pNode;
00346 }
00347
00348 void * LISTCALL Link_Pop(Link *pLink)
00349 {
00350 void *pData;
00351 Link * pNode;
00352 if ( ! pLink ) return NULL;
00353
00354 pNode = pLink->Next;
00355 if ( ! pNode ) return NULL;
00356
00357 pData = pNode->Data;
00358 pLink->Next = pNode->Next;
00359 MemPool_FreeHunk(LinkPool_g,pNode);
00360 return pData;
00361 }
00362
00363 void * LISTCALL Link_Peek(Link *pLink)
00364 {
00365 void *pData;
00366 Link * pNode;
00367 if ( ! pLink ) return NULL;
00368
00369 pNode = pLink->Next;
00370 if ( ! pNode ) return NULL;
00371
00372 pData = pNode->Data;
00373 return pData;
00374 }
00375
00376
00377
00378 #ifdef _DEBUG // else it's in list.h
00379 struct Stack
00380 {
00381 void ** Buffer, **End;
00382 void ** Head;
00383 int members;
00384 };
00385 #endif
00386
00387 void LISTCALL Stack_Destroy(Stack * pStack)
00388 {
00389 if ( pStack )
00390 {
00391 destroy(pStack->Buffer);
00392 destroy(pStack);
00393 }
00394 }
00395
00396 Stack * LISTCALL Stack_Create(void)
00397 {
00398 Stack * pStack;
00399 pStack = new(Stack);
00400 assert(pStack);
00401 pStack->members = 4096;
00402 pStack->Buffer = MemAlloc(sizeof(void *)*(pStack->members));
00403 assert(pStack->Buffer);
00404 pStack->End = pStack->Buffer + (pStack->members);
00405 pStack->Head = pStack->Buffer;
00406 return pStack;
00407 }
00408
00409 int LISTCALL Stack_Extend(Stack *pStack)
00410 {
00411 void ** NewBuffer;
00412 int newmembers;
00413
00414 newmembers = pStack->members + 4096;
00415 NewBuffer = MemAlloc(sizeof(void *)*newmembers);
00416 assert(NewBuffer);
00417 memcpy(NewBuffer,pStack->Buffer, sizeof(void *)*(pStack->members));
00418 pStack->Head = NewBuffer + pStack->members;
00419 pStack->members = newmembers;
00420 MemFree(pStack->Buffer);
00421 pStack->Buffer = NewBuffer;
00422
00423 pStack->End = pStack->Buffer + (pStack->members);
00424 return newmembers;
00425 }
00426
00427 void LISTCALL Stack_Push_Func(Stack *pStack,void * Data)
00428 {
00429 assert(pStack);
00430 *(pStack->Head)++ = Data;
00431 if ( pStack->Head == pStack->End )
00432 Stack_Extend(pStack);
00433 }
00434
00435 void * LISTCALL Stack_Pop_Func(Stack *pStack)
00436 {
00437 assert(pStack);
00438 if ( pStack->Head == pStack->Buffer )
00439 return NULL;
00440 pStack->Head --;
00441 return *(pStack->Head);
00442 }
00443
00444
00445
00446 struct RadixList
00447 {
00448 int NumLists;
00449 int Min,Max;
00450 List ** Lists;
00451 };
00452
00453 RadixList * RadixList_Create(int RadixListMax)
00454 {
00455 RadixList * pRadixList;
00456 int r;
00457 pRadixList = new(RadixList);
00458 assert(pRadixList);
00459 pRadixList->NumLists = RadixListMax+1;
00460 pRadixList->Lists = MemAlloc(sizeof(List *)*(pRadixList->NumLists));
00461 assert(pRadixList->Lists);
00462 for(r=0;r<(pRadixList->NumLists);r++)
00463 {
00464 pRadixList->Lists[r] = List_Create();
00465 assert(pRadixList->Lists[r]);
00466 }
00467 pRadixList->Min = pRadixList->NumLists;
00468 pRadixList->Max = - 1;
00469 return pRadixList;
00470 }
00471
00472 void RadixList_Destroy(RadixList * pRadixList)
00473 {
00474 int r;
00475 assert(pRadixList);
00476 for(r=0;r<(pRadixList->NumLists);r++)
00477 {
00478 List_Destroy(pRadixList->Lists[r]);
00479 }
00480 MemFree(pRadixList->Lists);
00481 MemFree(pRadixList);
00482 }
00483
00484 List * RadixList_Add(RadixList *pRadixList,void * Data,int Key)
00485 {
00486 List * l;
00487 assert(pRadixList);
00488 assert( Key < pRadixList->NumLists && Key >= 0 );
00489 l = List_AddTail(pRadixList->Lists[Key],Data);
00490 if ( Key < pRadixList->Min ) pRadixList->Min = Key;
00491 if ( Key > pRadixList->Max ) pRadixList->Max = Key;
00492 return l;
00493 }
00494
00495 void * RadixList_CutMax(RadixList *pRadixList,int *pKey)
00496 {
00497 assert(pRadixList);
00498
00499 while ( pRadixList->Max >= 0 )
00500 {
00501 void * Data;
00502
00503 if ( Data = List_CutHead(pRadixList->Lists[pRadixList->Max]) )
00504 {
00505 if ( pKey ) *pKey = pRadixList->Max;
00506 return Data;
00507 }
00508 pRadixList->Max --;
00509
00510 }
00511
00512 return NULL;
00513 }
00514
00515 void * RadixList_CutMin(RadixList *pRadixList,int *pKey)
00516 {
00517 assert(pRadixList);
00518
00519 while ( pRadixList->Min < pRadixList->NumLists )
00520 {
00521 void * Data;
00522
00523 if ( Data = List_CutHead(pRadixList->Lists[pRadixList->Min]) )
00524 {
00525 if ( pKey ) *pKey = pRadixList->Min;
00526 return Data;
00527 }
00528 pRadixList->Min ++;
00529
00530 }
00531
00532 return NULL;
00533 }
00534
00535 void * RadixList_CutKey(RadixList *pRadixList,int Key)
00536 {
00537 assert(pRadixList);
00538 return List_CutHead(pRadixList->Lists[Key]);
00539 }
00540
00541
00542
00543 struct RadixLN
00544 {
00545 int NumLNs;
00546 int Min,Max;
00547 LinkNode * LNs;
00548 };
00549
00550 RadixLN * RadixLN_Create(int RadixLNMax)
00551 {
00552 RadixLN * pRadixLN;
00553 LinkNode * LNs;
00554 int r;
00555 pRadixLN = new(RadixLN);
00556 assert(pRadixLN);
00557 pRadixLN->NumLNs = RadixLNMax+1;
00558 pRadixLN->LNs = MemAlloc(sizeof(LinkNode)*(pRadixLN->NumLNs));
00559 assert(pRadixLN->LNs);
00560
00561 TIMER_P(List_RadixInit);
00562
00563 LNs = pRadixLN->LNs;
00564 for(r=(pRadixLN->NumLNs);r--;LNs++)
00565 {
00566
00567 LNs->Next = LNs->Prev = LNs;
00568 }
00569 pRadixLN->Min = RadixLNMax;
00570 pRadixLN->Max = 0;
00571
00572 TIMER_Q(List_RadixInit);
00573
00574 return pRadixLN;
00575 }
00576
00577 void RadixLN_Destroy(RadixLN * pRadixLN)
00578 {
00579 assert(pRadixLN);
00580 MemFree(pRadixLN->LNs);
00581 MemFree(pRadixLN);
00582 }
00583
00584 void RadixLN_AddHead(RadixLN *pRadixLN,LinkNode *LN,int Key)
00585 {
00586 assert(pRadixLN);
00587 assert( Key < pRadixLN->NumLNs && Key >= 0 );
00588 LN_AddHead(&(pRadixLN->LNs[Key]),LN);
00589 if ( Key < pRadixLN->Min ) pRadixLN->Min = Key;
00590 if ( Key > pRadixLN->Max ) pRadixLN->Max = Key;
00591 }
00592
00593 void RadixLN_AddTail(RadixLN *pRadixLN,LinkNode *LN,int Key)
00594 {
00595 assert(pRadixLN);
00596 assert( Key < pRadixLN->NumLNs && Key >= 0 );
00597 LN_AddTail(&(pRadixLN->LNs[Key]),LN);
00598 if ( Key < pRadixLN->Min ) pRadixLN->Min = Key;
00599 if ( Key > pRadixLN->Max ) pRadixLN->Max = Key;
00600 }
00601
00602 LinkNode * RadixLN_CutMax(RadixLN *pRadixLN,int *pKey)
00603 {
00604 assert(pRadixLN);
00605
00606 TIMER_P(List_RadixWalk);
00607 while ( pRadixLN->Max >= 0 )
00608 {
00609 LinkNode * LN;
00610
00611 if ( LN = LN_CutHead(&(pRadixLN->LNs[pRadixLN->Max])) )
00612 {
00613 if ( pKey ) *pKey = pRadixLN->Max;
00614 TIMER_Q(List_RadixWalk);
00615 return LN;
00616 }
00617 pRadixLN->Max --;
00618 }
00619 TIMER_Q(List_RadixWalk);
00620
00621 return NULL;
00622 }
00623
00624 LinkNode * RadixLN_CutMin(RadixLN *pRadixLN,int *pKey)
00625 {
00626 assert(pRadixLN);
00627
00628 TIMER_P(List_RadixWalk);
00629 while ( pRadixLN->Min < pRadixLN->NumLNs )
00630 {
00631 LinkNode * LN;
00632
00633 if ( LN = LN_CutHead(&(pRadixLN->LNs[pRadixLN->Min])) )
00634 {
00635 if ( pKey ) *pKey = pRadixLN->Max;
00636 TIMER_Q(List_RadixWalk);
00637 return LN;
00638 }
00639 pRadixLN->Min ++;
00640 }
00641 TIMER_Q(List_RadixWalk);
00642
00643 return NULL;
00644 }
00645
00646 LinkNode * RadixLN_CutKey(RadixLN *pRadixLN,int Key)
00647 {
00648 assert(pRadixLN);
00649 return LN_CutHead(&(pRadixLN->LNs[Key]));
00650 }
00651
00652
00653 LinkNode * RadixLN_PeekMax(RadixLN *pRadixLN,int *pKey)
00654 {
00655 LinkNode * LNs;
00656 assert(pRadixLN);
00657
00658 TIMER_P(List_RadixWalk);
00659 LNs = & pRadixLN->LNs[pRadixLN->Max];
00660 while ( pRadixLN->Max >= 0 )
00661 {
00662 LinkNode * LN;
00663
00664 LN = LNs->Next;
00665 if ( LN != LNs )
00666 {
00667 if ( pKey ) *pKey = pRadixLN->Max;
00668 TIMER_Q(List_RadixWalk);
00669 return LN;
00670 }
00671 pRadixLN->Max --;
00672 LNs --;
00673 }
00674 TIMER_Q(List_RadixWalk);
00675
00676 return NULL;
00677 }
00678
00679 LinkNode * RadixLN_PeekMin(RadixLN *pRadixLN,int *pKey)
00680 {
00681 LinkNode * LNlist;
00682 assert(pRadixLN);
00683
00684 TIMER_P(List_RadixWalk);
00685 LNlist = & pRadixLN->LNs[pRadixLN->Min];
00686 while ( pRadixLN->Min < pRadixLN->NumLNs )
00687 {
00688 LinkNode * LN;
00689
00690 LN = LNlist->Next;
00691 if ( LN != LNlist )
00692 {
00693 if ( pKey ) *pKey = pRadixLN->Min;
00694 TIMER_Q(List_RadixWalk);
00695 return LN;
00696 }
00697 pRadixLN->Min ++;
00698 LNlist ++;
00699 }
00700 TIMER_Q(List_RadixWalk);
00701
00702 return NULL;
00703 }
00704
00705
00706
00707 struct RadixLink
00708 {
00709 int NumLinks;
00710 int Min,Max;
00711 Link * Links;
00712 };
00713
00714 RadixLink * RadixLink_Create(int RadixLinkMax)
00715 {
00716 RadixLink * pRadixLink;
00717 pRadixLink = new(RadixLink);
00718 assert(pRadixLink);
00719 pRadixLink->NumLinks = RadixLinkMax+1;
00720 pRadixLink->Links = MemAlloc(sizeof(Link)*(pRadixLink->NumLinks));
00721 assert(pRadixLink->Links);
00722
00723 pRadixLink->Min = pRadixLink->NumLinks;
00724 pRadixLink->Max = - 1;
00725 return pRadixLink;
00726 }
00727
00728 void RadixLink_Grow(RadixLink *pRadixLink,int NewMax)
00729 {
00730 Link * OldLinks;
00731 int OldNumLinks;
00732
00733 OldNumLinks = pRadixLink->NumLinks;
00734 OldLinks = pRadixLink->Links;
00735
00736 pRadixLink->NumLinks = NewMax + 1;
00737 pRadixLink->Links = MemAlloc(sizeof(Link)*(pRadixLink->NumLinks));
00738
00739 assert(pRadixLink->Links);
00740
00741 memcpy(pRadixLink->Links, OldLinks, (sizeof(Link)*OldNumLinks));
00742
00743
00744 MemFree(OldLinks);
00745 }
00746
00747 void RadixLink_Destroy(RadixLink * pRadixLink)
00748 {
00749 int r;
00750 assert(pRadixLink);
00751 for(r=0;r<(pRadixLink->NumLinks);r++)
00752 {
00753 if ( pRadixLink->Links[r].Next )
00754 Link_Destroy(pRadixLink->Links[r].Next);
00755 }
00756 MemFree(pRadixLink->Links);
00757 MemFree(pRadixLink);
00758 }
00759
00760 void RadixLink_Add(RadixLink *pRadixLink,void * Data,int Key)
00761 {
00762 assert(pRadixLink);
00763 assert( Key >= 0 );
00764
00765 if ( Key >= pRadixLink->NumLinks )
00766 RadixLink_Grow(pRadixLink, Key + (Key>>2) );
00767
00768 Link_Push(&(pRadixLink->Links[Key]),Data);
00769
00770 if ( Key < pRadixLink->Min ) pRadixLink->Min = Key;
00771 if ( Key > pRadixLink->Max ) pRadixLink->Max = Key;
00772 }
00773
00774 void * RadixLink_CutMax(RadixLink *pRadixLink,int *pKey)
00775 {
00776 Link * pLink;
00777 pLink = (pRadixLink->Links) + (pRadixLink->Max);
00778 while ( pRadixLink->Max >= 0 )
00779 {
00780 if ( pLink->Next )
00781 {
00782 if ( pKey ) *pKey = pRadixLink->Max;
00783 return Link_Pop(pLink);
00784 }
00785 pRadixLink->Max --;
00786 pLink --;
00787 }
00788 return NULL;
00789 }
00790
00791 void * RadixLink_CutMin(RadixLink *pRadixLink,int *pKey)
00792 {
00793 Link * pLink;
00794 pLink = (pRadixLink->Links) + (pRadixLink->Min);
00795 while ( pRadixLink->Min < pRadixLink->NumLinks )
00796 {
00797 if ( pLink->Next )
00798 {
00799 if ( pKey ) *pKey = pRadixLink->Min;
00800 return Link_Pop(pLink);
00801 }
00802 pRadixLink->Min ++;
00803 pLink ++;
00804 }
00805 return NULL;
00806 }
00807
00808 void * RadixLink_CutKey(RadixLink *pRadixLink,int Key)
00809 {
00810 assert(pRadixLink);
00811 return Link_Pop(&(pRadixLink->Links[Key]));
00812 }
00813
00814
00815
00816
00817 void List_TimerReport(void)
00818 {
00819 #ifdef DO_TIMER
00820 TIMER_REPORT(List_Ram);
00821 TIMER_REPORT(List_RadixWalk);
00822 TIMER_REPORT(List_RadixInit);
00823 #endif
00824 }
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
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
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
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
00914
00915
00916
00917
00918
00919
00920
00921 #ifdef SAFE_HASH_DEBUG //{
00922
00923 #pragma message("using safe debug hash implementation")
00924
00925 struct Hash
00926 {
00927 HashNode ** NodeArray;
00928 int NodeArrayLen;
00929 int NodeCount;
00930 };
00931
00932
00933 struct HashNode
00934 {
00935 uint32 Key;
00936 uint32 Data;
00937 };
00938
00939 Hash * Hash_Create(void)
00940 {
00941 Hash * H;
00942 H = new(Hash);
00943 assert(H);
00944
00945 return H;
00946 }
00947
00948 void Hash_Destroy(Hash *H)
00949 {
00950 assert(H);
00951 if ( H->NodeArray )
00952 {
00953 int n;
00954 for(n=0;n<H->NodeCount;n++)
00955 {
00956 MemPool_FreeHunk(HashNodePool_g,H->NodeArray[n]);
00957 }
00958 destroy(H->NodeArray);
00959 }
00960
00961 destroy(H);
00962 }
00963
00964 HashNode * LISTCALL Hash_Add(Hash *H,uint32 Key,uint32 Data)
00965 {
00966 HashNode * hn;
00967 hn = MemPool_GetHunk(HashNodePool_g);
00968 assert(hn);
00969 hn->Key = Key;
00970 hn->Data = Data;
00971
00972 if ( H->NodeCount == H->NodeArrayLen )
00973 {
00974 H->NodeArrayLen = H->NodeCount + 100;
00975 if ( H->NodeArray )
00976 {
00977 H->NodeArray = geRam_Realloc(H->NodeArray,H->NodeArrayLen*sizeof(HashNode *));
00978 }
00979 else
00980 {
00981 H->NodeArray = geRam_Allocate(H->NodeArrayLen*sizeof(HashNode *));
00982 }
00983 assert(H->NodeArray);
00984 }
00985
00986 H->NodeArray[H->NodeCount] = hn;
00987 H->NodeCount ++;
00988
00989 return hn;
00990 }
00991
00992 void LISTCALL Hash_DeleteNode(Hash *pHash,HashNode *pNode)
00993 {
00994 int n;
00995
00996 n = 0;
00997 while( pHash->NodeArray[n] != pNode )
00998 {
00999 n++;
01000 assert( n < pHash->NodeCount );
01001 }
01002
01003 pHash->NodeArray[n] = pHash->NodeArray[ pHash->NodeCount - 1];
01004 assert(pHash->NodeArray[n]);
01005 pHash->NodeArray[ pHash->NodeCount - 1] = NULL;
01006 pHash->NodeCount --;
01007
01008 MemPool_FreeHunk(HashNodePool_g,pNode);
01009 }
01010
01011 HashNode * LISTCALL Hash_Get(Hash *pHash,uint32 Key,uint32 *pData)
01012 {
01013 int n;
01014 for(n=0;n<pHash->NodeCount;n++)
01015 {
01016 if ( pHash->NodeArray[n]->Key == Key )
01017 {
01018 if ( pData )
01019 *pData = pHash->NodeArray[n]->Data;
01020 return pHash->NodeArray[n];
01021 }
01022 }
01023 return NULL;
01024 }
01025
01026 HashNode * LISTCALL Hash_WalkNext(Hash *pHash,HashNode *pCur)
01027 {
01028 int n;
01029
01030 if ( pCur )
01031 {
01032 n = 0;
01033 while( pHash->NodeArray[n] != pCur )
01034 {
01035 n++;
01036 assert( n < pHash->NodeCount );
01037 }
01038 n ++;
01039 }
01040 else
01041 {
01042 n = 0;
01043 }
01044 if ( n == pHash->NodeCount )
01045 return NULL;
01046 else
01047 return pHash->NodeArray[n];
01048 }
01049
01050 uint32 LISTCALL Hash_NumMembers(Hash *pHash)
01051 {
01052 return pHash->NodeCount;
01053 }
01054
01055
01056 #else //}{ the real thing
01057
01058 #define HASH_MOD (1009) // or 1013 , a nice prime
01059 #define HASH_SIZE (HASH_MOD + 1)
01060 #define HASH(Key) ((( ((Key)>>15) ^ (Key) )%HASH_MOD)+1)
01061
01062 struct Hash
01063 {
01064
01065 Debug(Hash * MySelf1)
01066
01067 HashNode * HashTable[HASH_SIZE];
01068 HashNode * NodeList;
01069
01070 Debug(int Members)
01071 Debug(Hash * MySelf2)
01072 };
01073
01074 struct HashNode
01075 {
01076 LinkNode LN;
01077 uint32 Key;
01078 uint32 Data;
01079 uint32 Hash;
01080 };
01081
01082 Hash * Hash_Create(void)
01083 {
01084 Hash * pHash;
01085 HashNode *pHead,*pTail;
01086
01087 pHash = new(Hash);
01088 if ( ! pHash )
01089 return NULL;
01090
01091
01092
01093 Debug( pHash->MySelf1 = pHash )
01094 Debug( pHash->MySelf2 = pHash )
01095
01096 pTail = MemPool_GetHunk(HashNodePool_g);
01097 assert(pTail);
01098 LN_Null(pTail);
01099 pTail->Key = pTail->Data = 0;
01100 pTail->Hash = HASH_SIZE;
01101
01102 pHead = MemPool_GetHunk(HashNodePool_g);
01103 assert(pHead);
01104 LN_Null(pHead);
01105 pHead->Key = pHead->Data = 0;
01106 pHead->Hash = 0;
01107
01108 LN_AddBefore(pHead,pTail);
01109
01110 pHash->NodeList = pHead;
01111
01112 Debug(pHash->Members = 0)
01113
01114 return pHash;
01115 }
01116
01117 void Hash_Destroy(Hash *pHash)
01118 {
01119 if ( pHash )
01120 {
01121 HashNode *pList,*pNode,*pNext;
01122
01123 assert( pHash->MySelf1 == pHash && pHash->MySelf2 == pHash );
01124
01125 Debug(pHash->Members += 2)
01126
01127 pList = pHash->NodeList;
01128 LN_Walk_Editting(pNode,pList,pNext) {
01129 MemPool_FreeHunk(HashNodePool_g,pNode);
01130 assert(pHash->Members > 1);
01131 Debug(pHash->Members --)
01132 }
01133 assert(pHash->Members == 1);
01134 MemPool_FreeHunk(HashNodePool_g,pList);
01135 destroy(pHash);
01136 }
01137 }
01138
01139 #ifdef _DEBUG
01140 int Hash_ListLen(Hash *pHash,uint32 H)
01141 {
01142 HashNode *hn;
01143 int Len = 0;
01144 hn = pHash->HashTable[H];
01145 if ( ! hn )
01146 return 0;
01147 while( hn->Hash == H )
01148 {
01149 Len ++;
01150 assert(pHash->Members >= Len);
01151 hn = LN_Next(hn);
01152 }
01153 return Len;
01154 }
01155 #endif
01156
01157 HashNode * LISTCALL Hash_Add(Hash *pHash,uint32 Key,uint32 Data)
01158 {
01159 uint32 H;
01160 HashNode *hn,**pTable,*Node,*Prev;
01161 Debug( int ListLen1; int ListLen2; int HashLen1; int HashLen2; int WalkLen)
01162
01163 assert(pHash);
01164 assert( pHash->MySelf1 == pHash && pHash->MySelf2 == pHash );
01165
01166 hn = MemPool_GetHunk(HashNodePool_g);
01167 assert(hn);
01168 Debug( LN_Null(hn) )
01169
01170 hn->Key = Key;
01171 hn->Data = Data;
01172 hn->Hash = H = HASH(Key);
01173
01174 pTable = &(pHash->HashTable[H]);
01175 Node = *pTable;
01176
01177 assert( H > 0 );
01178 assert( pHash->NodeList->Hash == 0 );
01179 assert( ((HashNode *)LN_Prev(pHash->NodeList))->Hash == HASH_SIZE );
01180
01181 Debug(HashLen1 = Hash_NumMembers(pHash))
01182 Debug(ListLen1 = Hash_ListLen(pHash,H))
01183
01184 if ( ! Node )
01185 {
01186 Prev = pHash->NodeList;
01187 Node = LN_Next(Prev);
01188
01189 Debug(WalkLen = 0)
01190
01191 assert(Prev->Hash < H);
01192 while( Node->Hash < H )
01193 {
01194 Prev = Node;
01195 Node = LN_Next(Prev);
01196
01197 assert(WalkLen < pHash->Members );
01198 Debug( WalkLen ++)
01199
01200 assert(Prev->Hash <= Node->Hash);
01201 assert(Prev->Hash < HASH_SIZE );
01202 }
01203
01204 assert(Prev->Hash < H);
01205 assert(Node->Hash >= H);
01206 }
01207
01208 LN_AddBefore(hn,Node);
01209 *pTable = hn;
01210
01211 Debug(pHash->Members ++)
01212
01213 Debug(ListLen2 = Hash_ListLen(pHash,H))
01214 assert( ListLen2 == (ListLen1 + 1) );
01215 Debug(HashLen2 = Hash_NumMembers(pHash))
01216 assert( HashLen2 == (HashLen1 + 1) );
01217
01218 return hn;
01219 }
01220
01221 void LISTCALL Hash_DeleteNode(Hash *pHash,HashNode *pNode)
01222 {
01223 HashNode ** pHead;
01224 uint32 H;
01225 Debug( int ListLen1; int ListLen2;int HashLen1; int HashLen2)
01226
01227 assert(pNode );
01228 assert( pHash );
01229 assert( pHash->MySelf1 == pHash && pHash->MySelf2 == pHash );
01230
01231 assert( pNode->Hash > 0 && pNode->Hash < HASH_SIZE );
01232
01233 H = pNode->Hash;
01234 pHead = & ( pHash->HashTable[H] );
01235
01236 Debug( HashLen1 = Hash_NumMembers(pHash) )
01237 Debug( ListLen1 = Hash_ListLen(pHash,H) )
01238 assert(pHash->Members > 0);
01239 Debug(pHash->Members --)
01240
01241 if ( *pHead == pNode )
01242 {
01243 *pHead = LN_Next(pNode);
01244 if ( (*pHead)->Hash != H )
01245 {
01246
01247 assert( ((HashNode *)LN_Prev(pNode))->Hash < H );
01248 *pHead = NULL;
01249 }
01250 }
01251 assert( *pHead == NULL || (*pHead)->Hash == H );
01252
01253 LN_Cut(pNode);
01254
01255 MemPool_FreeHunk(HashNodePool_g,pNode);
01256
01257 Debug( HashLen2 = Hash_NumMembers(pHash) )
01258 Debug( ListLen2 = Hash_ListLen(pHash,H) )
01259 assert( HashLen2 == (HashLen1 - 1) );
01260
01261 }
01262
01263 HashNode * LISTCALL Hash_Get(Hash *pHash,uint32 Key,uint32 *pData)
01264 {
01265 uint32 H;
01266 HashNode *pNode;
01267
01268 assert(pHash );
01269 assert( pHash->MySelf1 == pHash && pHash->MySelf2 == pHash );
01270
01271 H = HASH(Key);
01272 assert( H > 0 && H < HASH_SIZE );
01273
01274 pNode = pHash->HashTable[H];
01275 if ( ! pNode )
01276 return NULL;
01277
01278 assert( pNode->Hash == H );
01279
01280 while( pNode->Hash == H )
01281 {
01282 if ( pNode->Key == Key )
01283 {
01284 if ( pData )
01285 *pData = pNode->Data;
01286 return pNode;
01287 }
01288 pNode = LN_Next(pNode);
01289 }
01290
01291 return NULL;
01292 }
01293
01294 HashNode * LISTCALL Hash_WalkNext(Hash *pHash,HashNode *pNode)
01295 {
01296 HashNode *pNext;
01297
01298 assert(pHash);
01299 assert( pHash->MySelf1 == pHash && pHash->MySelf2 == pHash );
01300
01301 if ( ! pNode )
01302 {
01303 pNode = pHash->NodeList;
01304 assert( pNode->Hash == 0 );
01305 }
01306
01307 pNext = LN_Next(pNode);
01308 assert( pNext->Hash > 0 );
01309 assert( pNext->Hash >= pNode->Hash );
01310
01311 assert( pNext != pNode );
01312 assert( LN_Prev(pNext) == pNode );
01313
01314 if ( pNext->Hash == HASH_SIZE )
01315 {
01316 assert( ((HashNode *)LN_Next(pNext)) == pHash->NodeList );
01317 return NULL;
01318 }
01319
01320 assert(pNext->Hash < HASH_SIZE);
01321
01322 return pNext;
01323 }
01324
01325 uint32 LISTCALL Hash_NumMembers(Hash *pHash)
01326 {
01327 uint32 N;
01328 HashNode *pNode;
01329
01330 assert(pHash);
01331 assert( pHash->MySelf1 == pHash && pHash->MySelf2 == pHash );
01332
01333 pNode = pHash->NodeList;
01334 assert( pNode->Hash == 0 );
01335 pNode = LN_Next(pNode);
01336 assert( pNode->Hash > 0 );
01337
01338 N = 0;
01339 while( pNode->Hash < HASH_SIZE )
01340 {
01341 assert( N < (uint32)pHash->Members );
01342 pNode = LN_Next(pNode);
01343 N ++;
01344 }
01345
01346 assert( N == (uint32)pHash->Members );
01347
01348 return N;
01349 }
01350
01351 #endif //}{ hashes
01352
01353 uint32 Hash_StringToKey(const char * String)
01354 {
01355 return CRC32_Array(String,strlen(String));
01356 }
01357
01358 void HashNode_SetData(HashNode *pNode,uint32 Data)
01359 {
01360 assert(pNode);
01361 pNode->Data = Data;
01362 }
01363
01364 void HashNode_GetData(HashNode *pNode,uint32 *pKey,uint32 *pData)
01365 {
01366 assert(pNode);
01367 *pKey = pNode->Key;
01368 *pData = pNode->Data;
01369 }
01370
01371 uint32 HashNode_Data(HashNode *pNode)
01372 {
01373 assert(pNode);
01374 return pNode->Data;
01375 }
01376
01377 uint32 HashNode_Key(HashNode *pNode)
01378 {
01379 assert(pNode);
01380 return pNode->Key;
01381 }
01382
01383
01384
01385 geBoolean List_Start(void)
01386 {
01387 assert(UsageCount >= 0 );
01388 if ( UsageCount == 0 )
01389 {
01390 assert(ListPool_g == NULL && LinkPool_g == NULL);
01391 if ( ! (ListPool_g = MemPool_Create(sizeof(List),1024,1024) ) )
01392 return GE_FALSE;
01393 if ( ! (LinkPool_g = MemPool_Create(sizeof(Link),128,128) ) )
01394 return GE_FALSE;
01395 if ( ! (HashNodePool_g = MemPool_Create(sizeof(HashNode),128,128) ) )
01396 return GE_FALSE;
01397
01398 }
01399 UsageCount ++;
01400 return GE_TRUE;
01401 }
01402
01403 geBoolean List_Stop(void)
01404 {
01405 assert(UsageCount > 0 );
01406 UsageCount --;
01407 if ( UsageCount == 0 )
01408 {
01409 assert(ListPool_g && LinkPool_g );
01410 MemPool_Destroy(&ListPool_g); ListPool_g = NULL;
01411 MemPool_Destroy(&LinkPool_g); LinkPool_g = NULL;
01412 MemPool_Destroy(&HashNodePool_g); HashNodePool_g = NULL;
01413 }
01414 return GE_TRUE;
01415 }