# HG changeset patch # User Me # Date 1274582968 25200 # Node ID ee3ad252427e2ef12ca7db7fa0676187868c47f1 Initial add diff -r 000000000000 -r ee3ad252427e PrivateHash.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PrivateHash.c Sat May 22 19:49:28 2010 -0700 @@ -0,0 +1,224 @@ +/* + * Copyright 2009 OpenSourceCodeStewardshipFoundation.org + * Licensed under GNU General Public License version 2 + * + * NOTE: this version of SRSW correct as of April 25, 2010 + * + * Author: seanhalle@yahoo.com + */ + + +#include +#include +#include +#include + +#include "PrivateHash.h" + + + HashTable * +makeHashTable( int numHashSlots, FreeEntryContentFnPtr freeFn ) + { HashTable * retTable; + retTable = malloc( sizeof( HashTable ) ); + + retTable->freeEntryContentFn = freeFn; + + retTable->entries = malloc( numHashSlots * sizeof(HashEntry *) ); + retTable->tableSz = numHashSlots; + + nullOutTablesArray( retTable ); + + return retTable; + } + + void +doubleTableSize( HashTable *table ) + { int i, oldTableSz, newTableSz; + HashEntry *entry, **oldEntries, **newEntries; + + oldTableSz = table->tableSz; + oldEntries = table->entries; + + newTableSz = 2 * oldTableSz + 1; + newEntries = malloc( newTableSz * sizeof(HashEntry *) ); + + table->tableSz = newTableSz; + table->entries = newEntries; + table->numEntries = 0; //about to add them all back! + + // move all the entries from old to new + for( i=0; i < oldTableSz; i++ ) + { if( oldEntries[i] != NULL ) + { entry = oldEntries[i]; + while( entry != NULL ) + { + addEntryToTable( entry, table ); //does not allocate anything + entry = entry->next; + } + } + } + } + + void +nullOutTablesArray( HashTable *table ) + { int i, tableSz; + tableSz = table->tableSz; + HashEntry ** entries = table->entries; + for( i = 0; i < tableSz; i++ ) + entries[ i ] = NULL; + } + + unsigned int +hashThisKey( char *s, int hashSz ) + { unsigned int h = 0; + + for( ; *s != 0; s++ ) + h = *s + h*31; + return h % hashSz; + } + +/*Need this to be separated out, for use in both getParam and putParam + */ + HashEntry * +getEntryFromTable( char *key, HashTable * table ) + { unsigned int + hashIndex = hashKey( key, table->tableSz ); + HashEntry* + hashEntry = table->entries[ hashIndex ]; + for( ; hashEntry != NULL; hashEntry = hashEntry->next ) + { if( strcmp( hashEntry->key, key ) == 0 ) return hashEntry; + } + return NULL; + } + + void * +getValueFromTable( char *key, HashTable * table ) + { HashEntry *entry; + entry = lookupKeyInHash( key, table ); + if( entry == NULL ) return NULL; + + return entry->content; + } + + int +addToTable( char* key, void *content, HashTable *table ) + { unsigned int hashIdx; + HashEntry* hashEntry; + + hashEntry = getEntryFromTable( key, table ); + if( hashEntry == NULL ) + { hashIdx = hashThisKey( key, table->tableSz ); + hashEntry = (HashEntry*) malloc( sizeof( HashEntry ) ); + if( hashEntry == NULL ) return 0; + hashEntry->key = strdup_m( key ); //TODO: figure out soln for incr Sz + if( hashEntry->key == NULL ) return 0; + hashEntry->next = (table->entries)[hashIdx]; + (table->entries)[hashIdx] = hashEntry; + table->numEntries += 1; + if( table->tableSz < table->numEntries ) doubleTableSize( table ); + } + else + { (*(table->freeEntryContentFn))( hashEntry->content ); + } + hashEntry->content = content; + return 1; + } + + int +addEntryToTable( HashEntry *entry, HashTable *table ) + { unsigned int hashIdx; + HashEntry* testEntry; + + testEntry = getEntryFromTable( entry->key, table ); + if( testEntry == NULL ) + { hashIdx = hashThisKey( entry->key, table->tableSz ); + entry->next = (table->entries)[hashIdx]; + (table->entries)[hashIdx] = entry; + table->numEntries += 1; + if( table->tableSz < table->numEntries ) doubleTableSize( table ); + } + else + { (*(table->freeEntryContentFn))( testEntry->content ); + testEntry->content = entry->content; + entry->content = NULL; + freeHashEntryUsing( entry, table ); + } + return 1; + } + + bool8 +deleteEntryFromTable( char *key, HashTable *table ) + { + table->numEntries -= 1; + + } + + + char* +strdup_m( char *o ) + { int len = strlen(o)+1; + char *ns = (char*) malloc( len * sizeof(char) ); + strcpy( ns, o ); + return ns; + } + +/* debugging function displays the hashtable in (key.value) pairs +*/ +/*void hashTableToString( HashTable * table ) + { int i; + HashEntry *t; + for( i = 0; i < table->tableSz; i++ ) + { t = entries[i]; + if( t == NULL ) + strcat_m( retStr, &"()" ); + else + { strcat_m( retStr, &"(" ); + for( ; t != NULL; t = t->next ) + { strcat_m( retStr, &" " ); + strcat_m( retStr, t->key ); + strcat_m( retStr, &"." ); + strcat_m( retStr, paramToString( t->param ) ); + strcat_m( retStr, &" " ); + } + strcat_m( retStr, &")" ); + } + } + } +*/ + +/* + void +setFnToFreeEntryContent( HashTable *table, FreeEntryContentFnPtr fnPtr ) + { + table->freeEntryContentFn = fnPtr; + } +*/ + + void +freeHashTable( HashTable *table ) + { int i; + HashEntry *hashEntry, *temp, **entries; + + entries = table->entries; + for( i=0; i < table->tableSz; i++ ) + { if( entries[i] != NULL ) + { hashEntry = entries[i]; + while( hashEntry != NULL ) + { + temp = hashEntry->next; + freeHashEntryUsing( hashEntry, table ); + hashEntry = temp; + } + } + } + } + + void +freeHashEntryUsing( HashEntry *entry, HashTable *table ) + { + if( entry->content != NULL ) + (*(table->freeEntryContentFn))( entry->content ); + free( entry->key ); //was malloc'd above, so free it + free( entry ); + } + diff -r 000000000000 -r ee3ad252427e PrivateHash.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PrivateHash.h Sat May 22 19:49:28 2010 -0700 @@ -0,0 +1,60 @@ +/* + * Copyright 2009 OpenSourceStewardshipFoundation.org + * Licensed under GNU General Public License version 2 + * + * Author: seanhalle@yahoo.com + */ + +#ifndef _PRIVATE_HASH_H +#define _PRIVATE_HASH_H + + +#define TRUE 1 +#define FALSE 0 + + +#define HASHSIZE 101 + +typedef struct _HashEntry HashEntry; + +struct _HashEntry + { + char *key; + void *content; + HashEntry *next; + }; + +typedef void (*FreeEntryContentFnPtr) ( void * ); + +typedef struct + { int tableSz; + int numEntries; + HashEntry* *entries; + FreeEntryContentFnPtr freeEntryContentFn; + } +HashTable; + +//=========================================================================== +// Internal functions +void freeHashEntryUsing( HashEntry *entry, HashTable *table ); +char* strdup_m(char *o); +unsigned int hashThisKey( char *s, int hashSz ); +void nullOutTablesArray( HashTable *table ); +void *getEntryFromTable( char *key, HashTable *table ); +void doubleTableSize( HashTable *table ); +void addEntryToTable( HashEntry *entry, HashTable *table ); + +//=========================================================================== +// Public functions +HashTable *makeHashTable( int numHashSlots, FreeEntryContentFnPtr freeFn ); + +void *getValueFromTable( char *key, HashTable *table ); +bool8 deleteEntryFromTable( char *key, HashTable *table ); +bool8 deleteEntrysValueInTable( char *key, HashTable *table ); + +int addToTable( char* key, void *content, HashTable *table ); +void freeTable( HashTable *table ); +//char *paramBagToString( ParamBag * bag ) + +#endif /* _PRIVATE_HASH_H */ +