#ifndef STRINGHASHTABLE_H #define STRINGHASHTABLE_H #include <stdio.h> #include <stdlib.h> #include <inttypes.h> #include <stdbool.h> /*** DO NOT MODIFY THIS FILE IN ANY WAY!! ***/ // The following two lines provide a forward declaration of StringNode, // allowing the use of StringNode as a type name in the declaration of // the StringHashTable type that follows, but without revealing anything // about the internals of a StringNode object. The full definition of // the StringNode type is contained in StringHashTable.c. struct _StringNode; typedef struct _StringNode StringNode; /** StringHashTable provides a user-configurable hash table implementation. * * The user can specify the size of the hash table, but the size is then * fixed, so the user must be careful to make sure the table is large * enough. * * As the name implies, the key field must be a zero-terminated C-string. * * The user must also provide the hash function to be applied to the * record keys. */ struct _StringHashTable { StringNode** table; // physical array for table uint32_t tableSz; // number of slots in the table uint32_t numEntries; // number of entries in the table (not // necessarily the number of nonempty slots) uint32_t (*hash)(const char* str); // pointer to the hash function }; typedef struct _StringHashTable StringHashTable; /** Creates a new StringHashTable object such that: * - the array has dimension Size * - the slots in the array are set to NULL * - the hash pointer is set to Hasher (so the hash table will use * that user-supplied hash function) * * Pre: Size equals the desired number of slots in the table * Hasher is the name of the hash function the table is to use, * and that function conforms to the specified interface * * Returns: pointer to a newly-allocated StringHashTable object; * blows up an assert() if creation fails */ StringHashTable* StringHashTable_create(uint32_t Size, uint32_t (*Hasher)(const char* str)); /** Adds an entry to the hash table corresponding to the given key/location. * * Pre: pTable points to a proper StringHashTable object * key points to a proper C-string * location is set to a corresponding location * * Post: if the key/location pair is already in the table, fails; otherwise * if the table does not contain an entry for key, a new index entry * has been created and location has been installed in it; * otherwise, location has been installed into the existing index entry * for key; * the user's C-string is duplicated, not linked to the table * * Returns: true iff the key/location have been properly added to the table */ bool StringHashTable_addEntry(StringHashTable* const pTable, char* key, uint32_t location); /** Finds the locations, if any, that correspond to the given key. * * Pre: pTable points to a proper StringHashTable object * key points to a proper C-string * * Returns: NULL if there is no entry for key in the table; otherwise * a pointer to an array storing the locations corresponding * to the key, and terminated by a zero location (which would * never be logically valid) */ uint32_t* StringHashTable_getLocationsOf(const StringHashTable* const pTable, const char* key); /** Deallocates memory associated with a StringHashTable. * * Pre: pTable points to a proper StringHashTable object * * Post: the following have been deallocated * - the key belonging to every index entry in the table * - the array of locations belonging to every index entry in the table * - every index entry in the table * - the array for the table * * Note: the function does not attempt to deallocate the StringHashTable object * itself, because that object may or may not have been allocated dynamically; * cleanup that up is the responsibility of the user. */ void StringHashTable_clear(StringHashTable* const pTable); /** Writes a clearly-formatted display of the contents of a given * StringHashTable. * * Pre: fp points to an open file, or is stdout * pTable points to a proper StringHashTable object */ void StringHashTable_display(FILE* fp, const StringHashTable* const pTable); #endif