X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=libcitadel%2Flib%2Fhash.c;h=0eedcab41c3850fd35746079009842e8a97050d3;hb=101a56a24149e797b4f8ae555f9aa004cb5f446d;hp=d4c2f5080f408b516c47ab98d800f5618beff19c;hpb=4f5a1c888ea70dcfa0d79afb4894d68dae1e483a;p=citadel.git diff --git a/libcitadel/lib/hash.c b/libcitadel/lib/hash.c index d4c2f5080..0eedcab41 100644 --- a/libcitadel/lib/hash.c +++ b/libcitadel/lib/hash.c @@ -173,10 +173,12 @@ int PrintHash(HashList *Hash, TransitionFunc Trans, PrintHashDataFunc PrintEntry */ int dbg_PrintHash(HashList *Hash, PrintHashContent First, PrintHashContent Second) { +#ifdef DEBUG const char *foo; const char *bar; const char *bla = ""; long key; +#endif long i; if (Hash == NULL) @@ -193,22 +195,39 @@ int dbg_PrintHash(HashList *Hash, PrintHashContent First, PrintHashContent Secon if (Hash->LookupTable[i] == NULL) { +#ifdef DEBUG foo = ""; bar = ""; key = 0; +#endif } else { +#ifdef DEBUG key = Hash->LookupTable[i]->Key; foo = Hash->LookupTable[i]->HashKey; +#endif if (First != NULL) - bar = First(Hash->Members[Hash->LookupTable[i]->Position]->Data); +#ifdef DEBUG + bar = +#endif + First(Hash->Members[Hash->LookupTable[i]->Position]->Data); +#ifdef DEBUG else bar = ""; +#endif + if (Second != NULL) - bla = Second(Hash->Members[Hash->LookupTable[i]->Position]->Data); +#ifdef DEBUG + bla = +#endif + Second(Hash->Members[Hash->LookupTable[i]->Position]->Data); +#ifdef DEBUG + else bla = ""; +#endif + } #ifdef DEBUG printf (" ---- Hashkey[%ld][%ld]: '%s' Value: '%s' ; %s\n", i, key, foo, bar, bla); @@ -254,12 +273,25 @@ HashList *NewHash(int Uniq, HashFunc F) { HashList *NewList; NewList = malloc (sizeof(HashList)); + if (NewList == NULL) + return NULL; memset(NewList, 0, sizeof(HashList)); NewList->Members = malloc(sizeof(Payload*) * 100); + if (NewList->Members == NULL) + { + free(NewList); + return NULL; + } memset(NewList->Members, 0, sizeof(Payload*) * 100); NewList->LookupTable = malloc(sizeof(HashKey*) * 100); + if (NewList->LookupTable == NULL) + { + free(NewList->Members); + free(NewList); + return NULL; + } memset(NewList->LookupTable, 0, sizeof(HashKey*) * 100); NewList->MemberSize = 100; @@ -371,14 +403,14 @@ void DeleteHash(HashList **Hash) * @brief Private function to increase the hash size. * @param Hash the Hasharray to increase */ -static void IncreaseHashSize(HashList *Hash) +static int IncreaseHashSize(HashList *Hash) { /* Ok, Our space is used up. Double the available space. */ Payload **NewPayloadArea; HashKey **NewTable; if (Hash == NULL) - return ; + return 0; /** If we grew to much, this might be the place to rehash and shrink again. if ((Hash->NMembersUsed > Hash->nLookupTableItems) && @@ -390,21 +422,30 @@ static void IncreaseHashSize(HashList *Hash) } */ - /** double our payload area */ NewPayloadArea = (Payload**) malloc(sizeof(Payload*) * Hash->MemberSize * 2); + if (NewPayloadArea == NULL) + return 0; + NewTable = malloc(sizeof(HashKey*) * Hash->MemberSize * 2); + if (NewTable == NULL) + { + free(NewPayloadArea); + return 0; + } + + /** double our payload area */ memset(&NewPayloadArea[Hash->MemberSize], 0, sizeof(Payload*) * Hash->MemberSize); memcpy(NewPayloadArea, Hash->Members, sizeof(Payload*) * Hash->MemberSize); free(Hash->Members); Hash->Members = NewPayloadArea; /** double our hashtable area */ - NewTable = malloc(sizeof(HashKey*) * Hash->MemberSize * 2); memset(&NewTable[Hash->MemberSize], 0, sizeof(HashKey*) * Hash->MemberSize); memcpy(NewTable, Hash->LookupTable, sizeof(HashKey*) * Hash->MemberSize); free(Hash->LookupTable); Hash->LookupTable = NewTable; Hash->MemberSize *= 2; + return 1; } @@ -419,31 +460,49 @@ static void IncreaseHashSize(HashList *Hash) * @param Data your Payload to add * @param Destructor Functionpointer to free Data. if NULL, default free() is used. */ -static void InsertHashItem(HashList *Hash, - long HashPos, - long HashBinKey, - const char *HashKeyStr, - long HKLen, - void *Data, - DeleteHashDataFunc Destructor) +static int InsertHashItem(HashList *Hash, + long HashPos, + long HashBinKey, + const char *HashKeyStr, + long HKLen, + void *Data, + DeleteHashDataFunc Destructor) { Payload *NewPayloadItem; HashKey *NewHashKey; + char *HashKeyOrgVal; if (Hash == NULL) - return; + return 0; - if (Hash->nMembersUsed >= Hash->MemberSize) - IncreaseHashSize (Hash); + if ((Hash->nMembersUsed >= Hash->MemberSize) && + (!IncreaseHashSize (Hash))) + return 0; - /** Arrange the payload */ NewPayloadItem = (Payload*) malloc (sizeof(Payload)); + if (NewPayloadItem == NULL) + return 0; + NewHashKey = (HashKey*) malloc (sizeof(HashKey)); + if (NewHashKey == NULL) + { + free(NewPayloadItem); + return 0; + } + HashKeyOrgVal = (char *) malloc (HKLen + 1); + if (HashKeyOrgVal == NULL) + { + free(NewHashKey); + free(NewPayloadItem); + return 0; + } + + + /** Arrange the payload */ NewPayloadItem->Data = Data; NewPayloadItem->Destructor = Destructor; /** Arrange the hashkey */ - NewHashKey = (HashKey*) malloc (sizeof(HashKey)); - NewHashKey->HashKey = (char *) malloc (HKLen + 1); NewHashKey->HKLen = HKLen; + NewHashKey->HashKey = HashKeyOrgVal; memcpy (NewHashKey->HashKey, HashKeyStr, HKLen + 1); NewHashKey->Key = HashBinKey; NewHashKey->PL = NewPayloadItem; @@ -468,6 +527,7 @@ static void InsertHashItem(HashList *Hash, Hash->LookupTable[HashPos] = NewHashKey; Hash->nMembersUsed++; Hash->nLookupTableItems++; + return 1; } /** @@ -616,8 +676,9 @@ void Put(HashList *Hash, const char *HKey, long HKLen, void *Data, DeleteHashDat HashBinKey = CalcHashKey(Hash, HKey, HKLen); HashAt = FindInHash(Hash, HashBinKey); - if (HashAt >= Hash->MemberSize) - IncreaseHashSize (Hash); + if ((HashAt >= Hash->MemberSize) && + (!IncreaseHashSize (Hash))) + return; /** oh, we're brand new... */ if (Hash->LookupTable[HashAt] == NULL) { @@ -691,7 +752,7 @@ int GetKey(HashList *Hash, char *HKey, long HKLen, void **Payload) /** * @ingroup HashListAccess - * @brief get the Keys present in this hash, simila to array_keys() in PHP + * @brief get the Keys present in this hash, similar to array_keys() in PHP * Attention: List remains to Hash! don't modify or free it! * @param Hash Your Hashlist to extract the keys from * @param List returns the list of hashkeys stored in Hash @@ -699,14 +760,19 @@ int GetKey(HashList *Hash, char *HKey, long HKLen, void **Payload) int GetHashKeys(HashList *Hash, char ***List) { long i; + + *List = NULL; if (Hash == NULL) return 0; if (Hash->MyKeys != NULL) free (Hash->MyKeys); Hash->MyKeys = (char**) malloc(sizeof(char*) * Hash->nLookupTableItems); - for (i=0; i < Hash->nLookupTableItems; i++) { - + if (Hash->MyKeys == NULL) + return 0; + + for (i=0; i < Hash->nLookupTableItems; i++) + { Hash->MyKeys[i] = Hash->LookupTable[i]->HashKey; } *List = (char**)Hash->MyKeys; @@ -722,11 +788,14 @@ int GetHashKeys(HashList *Hash, char ***List) * step-raster is provided. * @return the hash iterator */ -HashPos *GetNewHashPos(HashList *Hash, int StepWidth) +HashPos *GetNewHashPos(const HashList *Hash, int StepWidth) { HashPos *Ret; Ret = (HashPos*)malloc(sizeof(HashPos)); + if (Ret == NULL) + return NULL; + if (StepWidth != 0) Ret->StepWidth = StepWidth; else @@ -740,6 +809,30 @@ HashPos *GetNewHashPos(HashList *Hash, int StepWidth) return Ret; } +/** + * @ingroup HashListAccess + * @brief resets a hash-linear iterator object + * @param Hash the list we reference + * @param StepWidth in which step width should we iterate? + * @param it the iterator object to manipulate + * If negative, the last position matching the + * step-raster is provided. + * @return the hash iterator + */ +void RewindHashPos(const HashList *Hash, HashPos *it, int StepWidth) +{ + if (StepWidth != 0) + it->StepWidth = StepWidth; + else + it->StepWidth = 1; + if (it->StepWidth < 0) { + it->Position = Hash->nLookupTableItems - 1; + } + else { + it->Position = 0; + } +} + /** * @ingroup HashListAccess * @brief Set iterator object to point to key. If not found, don't change iterator @@ -871,7 +964,7 @@ void DeleteHashPos(HashPos **DelMe) * @param Data returns the Data found at HashPos * @return whether the item was found or not. */ -int GetNextHashPos(HashList *Hash, HashPos *At, long *HKLen, const char **HashKey, void **Data) +int GetNextHashPos(const HashList *Hash, HashPos *At, long *HKLen, const char **HashKey, void **Data) { long PayloadPos; @@ -1155,8 +1248,15 @@ int ParseMSet(MSet **MSetList, StrBuf *MSetStr) return 0; OneSet = NewStrBufPlain(NULL, StrLength(MSetStr)); + if (OneSet == NULL) + return 0; ThisMSet = NewHash(0, lFlathash); + if (ThisMSet == NULL) + { + FreeStrBuf(&OneSet); + return 0; + } *MSetList = (MSet*) ThisMSet; @@ -1179,6 +1279,12 @@ int ParseMSet(MSet **MSetList, StrBuf *MSetStr) } pEndSet = (long*) malloc (sizeof(long)); + if (pEndSet == NULL) + { + FreeStrBuf(&OneSet); + DeleteHash(&ThisMSet); + return 0; + } *pEndSet = EndSet; Put(ThisMSet, LKEY(StartSet), pEndSet, NULL);