home *** CD-ROM | disk | FTP | other *** search
-
-
- #include "dict.h"
-
- static int ceilPrime(int aValue)
- {
- int retVal;
-
- retVal = aValue;
-
- if(aValue <= 5) retVal = 5;
- else if(aValue <= 10) retVal = 11;
- else if(aValue <= 15) retVal = 17;
- else if(aValue <= 50) retVal = 51;
- else if(aValue <= 95) retVal = 97;
- else if(aValue <= 240) retVal = 241;
- else if(aValue <= 395) retVal = 397;
- else if(aValue <= 495) retVal = 499;
- else if(aValue <= 740) retVal = 743;
- else if(aValue <= 995) retVal = 997;
- else if(aValue <= 1490) retVal = 1499;
- else if(aValue <= 1990) retVal = 1999;
- else if(aValue <= 3975) retVal = 3989;
- else if((aValue % 2) == 0) retVal+=1;
-
- return retVal;
- }
-
- static int stringHash(const char *theString)
- {
- unsigned long theHash = 0, g;
- char *tmpString = (char *)theString;
-
- if(tmpString)
- {
- while((*tmpString) != '\0')
- {
-
- /* Old version theHash = *tmpString++ + (31 * theHash); */
- theHash = (theHash << 4 ) + *tmpString++;
-
- if( g = theHash & 0xF0000000 ) theHash ^= g >> 24;
-
- theHash &= ~g;
-
- }
-
- }
- return theHash;
- }
-
- Dictionary dict_alloc()
- {
- Dictionary retVal;
- int newS;
-
- retVal = (Dictionary) malloc(sizeof(struct _dict));
-
- newS = ceilPrime(DEF_CAPACITY);
-
- retVal->hashtable = (struct listnode **)
- calloc(newS,sizeof(struct listnode *));
- retVal->size = newS;
- retVal->used = 0;
-
- return retVal;
- }
-
- void dict_free(Dictionary aDict)
- {
- if(aDict)
- {
- struct listnode *newNode = 0;
- struct listnode *nextNode = 0;
- int i;
-
- for(i = 0; i < aDict->size; i++)
- {
- newNode = aDict->hashtable[i];
-
- while(newNode)
- {
- nextNode = newNode->next;
- free(newNode->key);
- free(newNode);
- newNode = nextNode;
- }
-
- aDict->hashtable[i] = 0;
- }
-
- if(aDict->hashtable) free(aDict->hashtable);
-
- free(aDict);
-
- aDict = 0;
- }
- }
-
- void dict_freeWithData(Dictionary aDict,void(*freer)())
- {
- if(aDict)
- {
- struct listnode *newNode = 0;
- struct listnode *nextNode = 0;
- int i;
-
- for(i = 0; i < aDict->size; i++)
- {
- newNode = aDict->hashtable[i];
-
- while(newNode)
- {
- nextNode = newNode->next;
- free(newNode->key);
- freer(newNode->value);
- free(newNode);
- newNode = nextNode;
- }
-
- aDict->hashtable[i] = 0;
- }
-
- if(aDict->hashtable) free(aDict->hashtable);
-
- free(aDict);
-
- aDict = 0;
- }
- }
-
- int dict_isKey(Dictionary aDict, const char *aStr)
- {
- return (dict_valueForKey(aDict, aStr)) ? 1 : 0;
- }
-
- void * dict_setValueForKey(Dictionary aDict, const char *aKey, void *theValue)
- {
- void * valueToReturn = 0;
-
- if(aKey)
- {
- unsigned long index;
- struct listnode *node = 0;
-
- index = (stringHash(aKey) % (aDict->size));
-
- node = aDict->hashtable[index];
-
- if(node){
-
- do
- {
- if( node->key && (0 == strcmp(aKey,node->key)) )
- {
- valueToReturn = node->value;/*cache the old one and*/
-
- node->value = theValue;/*replace it*/
- }
- else
- {
- node = node->next;
- }
-
- }while((!valueToReturn)&& node);
-
- }
-
- if(!valueToReturn)
- {
- node = (struct listnode *) calloc(1,sizeof(struct listnode));
-
- node->key = (char *)malloc(sizeof(char) * (strlen(aKey) + 1));
- strcpy(node->key,aKey);
-
- node->value = theValue;
- node->next = aDict->hashtable[index];
-
- aDict->hashtable[index]= node;
-
- aDict->used++;
-
- /*check if we need to grow*/
- if(aDict->used >= (GROW_PERCENTAGE * aDict->size)){
-
- struct listnode **newTable;
- int newS = GROWTH_RATE * aDict->size, newUsed = 0;
- DictState iterator;
- struct listnode *newNode = 0;
- struct listnode *nextNode = 0;
- unsigned long curIndex, i;
-
-
- iterator = dict_initState(aDict);
-
- newS = ceilPrime(newS);
-
- newTable = (struct listnode **) calloc(newS,sizeof(struct listnode *));
-
- while(dict_nextState(&iterator))
- {
-
- curIndex = (stringHash(iterator.curNode->key) % (newS));
-
- newNode =
- (struct listnode *) calloc(1,sizeof(struct listnode));
-
- newNode->key = iterator.curNode->key;
- newNode->value = iterator.curNode->value;
- newNode->next = newTable[curIndex];
- newTable[curIndex]= newNode;
-
- newUsed++;
- }
-
- for(i = 0; i < aDict-> size; i++)
- {
- newNode = aDict->hashtable[i];
-
- while(newNode)
- {
-
- nextNode = newNode->next;
- free(newNode);
- newNode = nextNode;
-
- }
-
- aDict->hashtable[i] = 0;
-
- }
-
- free(aDict->hashtable);
-
- aDict->hashtable = newTable;
- aDict->size = newS;
- aDict->used = newUsed;
- }
- }
- }
-
- return valueToReturn;
- }
-
-
- void * dict_valueForKey(Dictionary aDict, const char *theKey)
- {
- void * returnValue = 0;
-
- if( theKey &&( aDict->used > 0))
- {
- unsigned long index;
- struct listnode *node = 0;
-
- index = (stringHash(theKey) % (aDict->size));
- node = aDict->hashtable[index];
-
- if(node)
- {
- do
- {
- if( node->key && (0 == strcmp(theKey,node->key)) )
- {
- returnValue = node->value;
- }
- else
- {
- node = node->next;
- }
-
- }while( !returnValue && node);
- }
- }
-
- return returnValue;
- }
-
- void * dict_orphanValueForKey(Dictionary aDict, const char *theKey)
- {
- void * returnValue = 0;
-
- if( theKey &&( aDict->used > 0))
- {
- unsigned long index;
- struct listnode *node = 0;
- struct listnode *prevNode = 0;
-
- index = (stringHash(theKey) % (aDict->size));
- node = aDict->hashtable[index];
-
- if(node)
- {
- if(node->key && (0 == strcmp(theKey,node->key)))
- {
- aDict->hashtable[index] = node->next;
- returnValue = node->value;
-
- free(node->key);
- node->key = 0;
-
- free(node);
-
- aDict->used--;
- }
- else
- {
- while( returnValue && node)
- {
-
- if(node->key && (0 == strcmp(theKey,node->key)))
- {
- prevNode->next = node->next;
- returnValue = node->value;
-
- free(node->key);
- node->key = 0;
-
- free(node);
-
- aDict->used--;
- }
- else
- {
- prevNode = node;
- node = node->next;
- }
- }
- }
- }
- }
-
- return returnValue;
- }
-
- DictState dict_initState(Dictionary aDict)
- {
- DictState retVal;
-
- retVal.curIndex = -1;
- retVal.curNode = (struct listnode *) 0;
- retVal.bumpedCurNode = 0;
- retVal.dict = aDict;
-
- return retVal;
- }
-
-
- int dict_nextState(DictState *aState)
- {
- int foundAnotherNode = 0;
- struct listnode *nextNode;
-
- if(aState->curNode){
-
- if(aState->bumpedCurNode)
- {
- foundAnotherNode = 1;
- }
- else/* we have a node, try to find the next one at that slot */
- {
- nextNode = aState->curNode->next;
-
- if(nextNode)/* found one in this slot */
- {
- aState->curNode = nextNode;
- foundAnotherNode = 1;
- }
- else/* move to the next slot */
- {
- aState->curIndex++;
- }
- }
- }
-
- if(!foundAnotherNode)
- {
-
- if(aState->curIndex == -1) aState->curIndex = 0;
-
- while(aState->curIndex < aState->dict->size)
- {
- nextNode = aState->dict->hashtable[aState->curIndex];
-
- if(nextNode)
- {
- aState->curNode = nextNode;
- foundAnotherNode = 1;
- break;
- }
- else
- {
- aState->curIndex++;
- }
-
- }
-
- }
-
- aState->bumpedCurNode = 0;
-
- return foundAnotherNode;
- }
-
- void dict_printToStdout(Dictionary theDict)
- {
- DictState state;
-
- /* Create a dictionary state */
- state = dict_initState(theDict);
-
- while(dict_nextState(&state))
- {
- printf("%s = %s\n",state.curNode->key,(char *)state.curNode->value);
- }
- }
-