/* * StringHashTable.h * * Created by Marvin Theimer, January 19, 1991. * * String hash table package. * * This package stores pointers to user data in a hash table. It uses * null-terminated ascii strings as keys. * * The package supplies four operations: * StringHashCreate: - Create a new hash table of a given size. * StringHashDestroy: - Deallocate a hash table and reclaim its resources. * StringHashFind - Find/insert an element into a hash table. * StringHashDelete - Delete an element from a hash table. * StringHashIterate - Apply a function to all elements in a hash table. * The package's StringHashFind function returns pointers to the elements stored * in the hash table, which consist of a field for the tuple and a field * where a user may put a pointer to the data they wish to store. * This allows a user to set the user data pointer * after a hash table element has already been found/created. This is * useful when we don't want to malloc a new user data record until * we're sure that one doesn't already exist. * * The hash table can accomodate an arbitrary number of elements. However, * the size of table into which keys are hashed is fixed at creation time; * implying that performance will deteriorate as more and more elements * are inserted. The hash table itself consists of a keytable into which * keys are hashed and a linked list of "free blocks" that contain hash * table elements. Whenever insertion uses up the elements in the free * blocks list, another block is allocated and added to the list. When the * hash table is destroyed, both the key table and the list of free blocks * is freed. * * The hash table iterator function operates in time proportional to the * size of the table. */ #ifndef NIL #define NIL 0 #endif /* * Opaque hash table handle. */ typedef char *StringHashTableHandle; /* * This package uses null-terminated ascii strings as keys */ typedef char *StringHashKey; /* * The hash table stores elements consisting of a key field and a field * containing a pointer to user data. */ typedef struct StringHashElementRep { StringHashKey key; char *userData; } *StringHashElement; /* * Actions that StringHashFind should take. * If action == insert then StringHashFind will insert a new element if none is * found. If action == find then StringHashFind will NOT insert a new element * when none is found and will return NIL. */ typedef enum {insert, find} StringHashAction; /* * Hash table statistics record. */ typedef struct StringHashStatisticsRecRep { int numElements; /* Number of records in the hash table. */ int numFinds; /* Returns number of HashFinds executed. */ float avFindLength; /* Returns av. number of records examined in a hash chain during HashFind. */ float avChainLength; /* Returns. av. chain length in hash table. */ int maxChainLength; /* Maximum length chain in the table. */ } *StringHashStatisticsRec; /* * Function definitions. */ /* * StringHashCreate * Create a new hash table to hold numElements elements. * If there is not enough memory to create the hash table then NIL is returned. * The mallocFcn parameter specifies which memory allocator to use for * creating the hash table and any subsequent memory resources it needs. * Passing in NIL for this argument will result in use of the system's * standard malloc() function. * The freeFcn parameter specifies a memory free function to use when * freeing memory resources. Passing in NIL for this argument will result * in use of the system's standard free() function */ StringHashTableHandle StringHashCreate(/* numElements, mallocFcn, freeFcn */); /* int numElements; int (*mallocFcn)(); void (*freeFcn)(); */ /* * StringHashDestroy * Deallocate a hash table. Reclaims the memory used by the hash table. */ void StringHashDestroy(/* hashTable */); /* StringHashTableHandle hashTable; */ /* * StringHashFind * Search for the specified key in a hash table and return a pointer to * the element found. * If no element is found and action specifies insert then a new element * is inserted into the hash table and a pointer to it is returned. * If no element is found and action specifies FIND then the function does * NOT insert a new element and returns NIL. * inserted returns a boolean indicating if a new element was inserted, * thereby allowing one to detect when an insert action actually inserted * a new element. If a value of NIL is passed in then nothing is passed * back. * * If inserting a new element causes the package to run out of memory then * the function returns NIL. */ StringHashElement StringHashFind(/* hashTable, key, action, inserted */); /* StringHashTableHandle hashTable; StringHashKey key; StringHashAction; int *inserted; */ /* * StringHashDelete * Delete an element from a hash table. */ void StringHashDelete(/* hashTable, key */); /* StringHashTableHandle hashTable; StringHashKey key; */ /* * StringHashIterate * Apply a function to each element of the hash table in turn. * The supplied function should take an StringHashElement and a pointer to * to user-supplied arguments as input and * should return a boolean value indicating whether or not to continue * iterating over the hash table elements (TRUE => continue): * int fcn(hashElement, userArgs) * StringHashElement hashElement; * char *userArgs; */ void StringHashIterate(/* hashTable, fcn, userArgs */); /* StringHashTableHandle hashTable; int (*fcn)(); char *userArgs; */ /* * StringHashStatistics * Return statistics on hash table usage. */ void StringHashStatistics(/*hashTable, stats*/); /*StringHashTable hashTable;*/ /*StringHashStatisticsRec stats;*/ /* * StringHashResetStatistics * Reset the statistics variables for a hash table. */ void StringHashResetStatistics(/*hashTable*/); /*StringHashTable hashTable;*/