/*
 HASH.DOX

 License CC0 PUBLIC DOMAIN

 To the extent possible under law, Mark J. Olesen has waived all copyright
 and related or neighboring rights to FDOSTUI Library. This work is published
 from: United States.
*/

/*! \file hash.h
\brief A hash table, which maps keys to values. 
*/

/*!
\struct bucket
\brief internal data structure that holds a single key and value

\var bucket::m_key
	A unique key 

\var bucket::m_value
	Reference to a value. Value must survive life of bucket.

\var bucket::m_next
	Pointer to the next bucket in list

*/

/*!
\typedef void (*hash_remove_cb)(
    void *                         io_value)
\brief function prototype that is called to delete a value
\param[in] io_value value to delete
\returns none
*/

/*!
\struct hash
\brief hash data structure that holds keys and values

\var hash::m_bucket
	Array of pointers to hold buckets

\var hash::m_slots
	Number of buckets

\var hash::m_remove
	function to delete a value
*/

/*!
\fn int hash_assign(
    struct hash*const                   o_hash,
    size_t const                        i_buckets,
    hash_remove_cb                      i_remove)
\brief initialize hash object
\param[out] o_hash object to initialize
\param[in] i_buckets number of buckets the hash will hold
\param[in] i_remove function to remove values
\returns 0 success
\returns ENOMEM memory allocation failed

This routine will allocate the buckets and can return a
failure if there was not enough memory. Upon failure,
it is not advisable to use the other routines. However,
they should all exit gracefully with a valid error code.

If \a i_buckets is 0, the hash should not allow any 
operations to be performed.

*/

/*!
\fn void hash_discharge(
    struct hash*const                   io_hash)
\brief release resources held by the object
\param[in,out] io_hash object to release
\returns none
*/

/*!
\fn int hash_insert(
    struct hash*const                   io_hash,
    char const *                        i_key,
    void *                              i_value)
\brief insert a key and value
\param[in,out] io_hash hash object
\param[in] i_key key to insert
\param[in,out] i_value value associated with key
\returns 0 success
\returns EINVAL key is NULL
\returns ENOMEM unable to allocate memory
*/

/*!
\fn void * hash_lookup(
    int *const                          o_found,
    struct hash*const                   io_hash,
    char const *                        i_key)
\brief lookup a value
\param[out] o_found indicator if key exists
\param[in,out] io_hash hash object
\param[in] i_key key to find
\returns value of key

Zero is a valid return value. Check \a o_found to see if the key exists.

*/

/*!
\fn int hash_remove(
    struct hash*const                       io_hash,
    char const *                   	    i_key)
\brief remove a key fromt the hash table
\param[in] i_key key to remove
\returns 0 success
\returns ENOENT key does not exist

If available, the routine will call ::hash_remove_cb to dispose of the
key's value.

*/
