libstash_oh(3s)

NAME
oh - Dynamic open hashing.

SYNOPSIS

  Single-threaded
#define _LIBSTASH_USE_OH
#include <libstash/libstash.h> cw_oh_t *
oh_new (cw_oh_t * a_oh)

  Multi-threaded
#define _LIBSTASH_USE_OH
#include <libstash/libstash_r.h> cw_oh_t *
oh_new (cw_oh_t * a_oh) cw_oh_t *
oh_new_r (cw_oh_t * a_oh)

  General
void
oh_delete (void) cw_uint64_t
oh_get_size (cw_oh_t * a_oh) cw_uint64_t
oh_get_num_items (cw_oh_t * a_oh) cw_uint64_t
oh_get_base_size (cw_oh_t * a_oh) cw_uint32_t
oh_get_base_h2 (cw_oh_t * a_oh) cw_uint32_t
oh_get_base_shrink_point (cw_oh_t * a_oh) cw_uint32_t
oh_get_base_grow_point (cw_oh_t * a_oh) oh_h1_t *
oh_oh_set_h1 (cw_oh_t * a_oh, oh_h1_t * a_new_h1) oh_key_comp_t *
oh_set_key_compare (cw_oh_t * a_oh, oh_key_comp_t * a_new_key_compare) cw_bool_t
oh_set_base_h2 (cw_oh_t * a_oh, cw_uint32_t a_h2) cw_bool_t
oh_set_base_shrink_point (cw_oh_t * a_oh, cw_uint32_t a_shrink_point) cw_bool_t
oh_set_base_grow_point (cw_oh_t * a_oh, cw_uint32_t a_grow_point) cw_sint32_t
oh_item_insert (cw_oh_t * a_oh, const void * a_key, const void * a_data ) cw_bool_t
oh_item_delete (cw_oh_t * a_oh, const void * a_search_key, void ** r_key , void ** r_data) cw_bool_t
oh_item_search (cw_oh_t * a_oh, const void * a_key, void ** r_data) cw_bool_t
oh_item_get_iterate (cw_oh_t * a_oh, void ** r_key, void ** r_data) cw_bool_t
oh_item_delete_iterate (cw_oh_t * a_oh, void ** r_key, void ** r_data) void
oh_dump (cw_oh_t * a_oh, cw_bool_t a_all) cw_uint64_t
oh_get_num_collisions (cw_oh_t * a_oh) cw_uint64_t
oh_get_num_inserts (cw_oh_t * a_oh) cw_uint64_t
oh_get_num_deletes (cw_oh_t * a_oh) cw_uint64_t
oh_get_num_grows (cw_oh_t * a_oh) cw_uint64_t
oh_get_num_shrinks (cw_oh_t * a_oh) cw_uint64_t
oh_h1_string (const void * a_key) cw_uint64_t
oh_h1_direct (const void * a_key) cw_bool_t
oh_key_compare_string (const void * a_k1, const void * a_k2) cw_bool_t
oh_key_compare_direct (const void * a_k1, const void * a_k2)

  Debugging (dbg) symbols
None.

DESCRIPTION
Dynamic open hashing class. This is a somewhat sophisticated implementation of hashing. All internal consistency, growth, shrinkage, etc. issues are taken care of internally. The hash functions to use, as well as just about any other useful parameter, can be modified on the fly with no worries of inconsistency. This class is thread safe, thanks to read/write locks. That is, multiple readers can be in the code simultaneously, but only one locker (with no readers) can be in the code at any given time. This implementation uses a secondary hash function instead of bucket chaining. As a result, the table needs to be kept a little emptier than some implementations in order to avoid excessive secondary hashing. This code never rehashes during normal operation, because it is careful to shuffle slot contents (items) whenever items are deleted. This code also keeps an internal list of all items to allow fast table rebuilding when growing, shrinking, and rehashing (done only when hashing functions are changed). This also makes it possible to use realloc() instead of malloc(), since the table can be bzero()ed, then rebuilt from the list. Decisions on when to grow and shrink are based on the base table size. The growth and shrinkage thresholds are in always in direct proportion to the thresholds set for the base table size. A useful side effect of the internal list is that calling oh_item_delete_iterate() and oh_item_get_iterate() are guaranteed to operate on the oldest item in the hash table, which means that the hash code has an integrated FIFO queue. A list of spare item containers is kept around to avoid excessive calls to malloc() during insertion/deletion. All internal lists and buffers are kept tidy and at reasonable sizes.

USAGE
cw_oh_t *
oh_new (cw_oh_t * a_oh)
cw_oh_t *
oh_new_r (cw_oh_t * a_oh)
    Input(s):
        a_oh:
            Pointer to space for an oh, or NULL.
    Output(s):
        retval:
            non-NULL: Pointer to an oh.
            NULL: Memory allocation error.
    Description:
        Non-thread-safe and thread-safe constructors.
void
oh_delete (cw_oh_t * a_oh)
    Input(s):
        a_oh:
            Pointer to an oh.
    Output(s):
        None.
    Description:
        Destructor.
cw_uint64_t
oh_get_size (cw_oh_t * a_oh)
    Input(s):
        a_oh:
            Pointer to an oh.
    Output(s):
        retval:
            Internal table size.
    Description:
        Return the internal table size.
cw_uint64_t
oh_get_num_items (cw_oh_t * a_oh)
    Input(s):
        a_oh:
            Pointer to an oh.
    Output(s):
        retval:
            Number of items in a_oh.
    Description:
        Return the number of items in a_oh.
cw_uint64_t
oh_get_base_size (cw_oh_t * a_oh)
    Input(s):
        a_oh:
            Pointer to an oh.
    Output(s):
        retval:
            Base table size.
    Description:
        Return the base table size on which the expansion and contraction parameters depend.
cw_uint32_t
oh_get_base_h2 (cw_oh_t * a_oh)
    Input(s):
        a_oh:
            Pointer to an oh.
    Output(s):
        retval:
            Base table size.
    Description:
        Return the value of the base secondary hashing function.
cw_uint32_t
oh_get_base_shrink_point (cw_oh_t * a_oh)
    Input(s):
        a_oh:
            Pointer to an oh.
    Output(s):
        retval:
            Base shrink point.
    Description:
        Return the value of the base shrink point, which is used to determine when to shrink the internal table.
cw_uint32_t
oh_get_base_grow_point (cw_oh_t * a_oh)
    Input(s):
        a_oh:
            Pointer to an oh.
    Output(s):
        retval:
            Base grow point.
    Description:
        Return the value of the base grow point, which is used to determine when to grow the internal table.
oh_h1_t *
oh_oh_set_h1 (cw_oh_t * a_oh, oh_h1_t * a_new_h1)
    Input(s):
        a_oh:
            Pointer to an oh.
        a_new_h1:
            Pointer to a primary hashing function.
    Output(s):
        retval:
            Pointer to the old primary hashing function.
    Description:
        Set the primary hashing function. Calling this function causes an internal rehash.
oh_key_comp_t *
oh_set_key_compare (cw_oh_t * a_oh, oh_key_comp_t * a_new_key_compare)
    Input(s):
        a_oh:
            Pointer to an oh.
        a_new_key_compare:
            Pointer to a key comparison function.
    Output(s):
        retval:
            Pointer to the old key comparison function.
    Description:
        Set the key comparison function. Note: There is no good reason to specify a new key comparison function after a_ah has been populated. This function should probably be folded into oh_new().
cw_bool_t
oh_set_base_h2 (cw_oh_t * a_oh, cw_uint32_t a_h2)
    Input(s):
        a_oh:
            Pointer to an oh.
        a_h2:
            Secondary hash.
    Output(s):
        retval:
            FALSE: Success.
            TRUE: a_h2 is not an odd number less than a_oh's base table size.
    Description:
        Set the base secondary hash.
cw_bool_t
oh_set_base_shrink_point (cw_oh_t * a_oh, cw_uint32_t a_shrink_point)
    Input(s):
        a_oh:
            Pointer to an oh.
        a_shrink_point:
            Base shrink point.
    Output(s):
        retval:
            FALSE: Success.
            TRUE: a_shrink_point is > the base grow point or table size.
    Description:
        Set the base shrink point.
cw_bool_t
oh_set_base_grow_point (cw_oh_t * a_oh, cw_uint32_t a_grow_point)
    Input(s):
        a_oh:
            Pointer to an oh.
        a_grow_point:
            Base grow point.
    Output(s):
        retval:
            FALSE: Success.
            TRUE: a_grow_point is <= the base shrink point or >= the base table size.
    Description:
        Set the base grow point.
cw_sint32_t
oh_item_insert (cw_oh_t * a_oh, const void * a_key, const void * a_data )
    Input(s):
        a_oh:
            Pointer to an oh.
        a_key:
            Pointer to a key.
        a_data:
            Pointer to data associated with a_key.
    Output(s):
        retval:
            -1: Memory allocation error.
            0: Success.
            1: a_key already exists in a_oh.
    Description:
        Insert an item, unless an item with the same key already exists in a_oh.
cw_bool_t
oh_item_delete (cw_oh_t * a_oh, const void * a_search_key, void ** r_key , void ** r_data)
    Input(s):
        a_oh:
            Pointer to an oh.
        a_search_key:
            Pointer to a key.
        r_key:
            Pointer to a key pointer, or NULL.
        r_data:
            Pointer to a data pointer, or NULL.
    Output(s):
        retval:
            FALSE: Success.
            TRUE: Item with key a_search_key not found.
        *r_key:
            If (NULL != r_key) and (FALSE == retval): Pointer to a key.
            Otherwise: Undefined.
        *r_data:
            If (NULL != r_data) and (FALSE == retval): Pointer to data.
            Otherwise: Undefined.
    Description:
        Delete an item with key a_search_key. If successful, set *r_key and *r_data to point to the key and data, respectively.
cw_bool_t
oh_item_search (cw_oh_t * a_oh, const void * a_key, void ** r_data)
    Input(s):
        a_oh:
            Pointer to an oh.
        a_key:
            Pointer to a key.
        r_data:
            Pointer to a data pointer, or NULL.
    Output(s):
        retval:
            FALSE: Success.
            TRUE: Item with key a_key not found in a_oh.
        *r_data:
            If (NULL != r_data) and (FALSE == retval): Pointer to data.
            Otherwise: Undefined.
    Description:
        Search for an item with key a_key. If found, set *r_data to point to the associated data.
cw_bool_t
oh_item_get_iterate (cw_oh_t * a_oh, void ** r_key, void ** r_data)
    Input(s):
        a_oh:
            Pointer to an oh.
        r_key:
            Pointer to a key pointer, or NULL.
        r_data:
            Pointer to a data pointer, or NULL.
    Output(s):
        retval:
            FALSE: Success.
            TRUE: a_oh is empty.
        *r_key:
            If (NULL != r_key) and (FALSE == retval): Pointer to a key.
            Otherwise: Undefined.
        *r_data:
            If (NULL != r_data) and (FALSE == retval): Pointer to data.
            Otherwise: Undefined.
    Description:
        Set *r_key and *r_data to point to the oldest item in a_oh.
cw_bool_t
oh_item_delete_iterate (cw_oh_t * a_oh, void ** r_key, void ** r_data)
    Input(s):
        a_oh:
            Pointer to an oh.
        r_key:
            Pointer to a key pointer, or NULL.
        r_data:
            Pointer to a data pointer, or NULL.
    Output(s):
        retval:
            FALSE: Success.
            TRUE: a_oh is empty.
        *r_key:
            If (NULL != r_key) and (FALSE == retval): Pointer to a key.
            Otherwise: Undefined.
        *r_data:
            If (NULL != r_data) and (FALSE == retval): Pointer to data.
            Otherwise: Undefined.
    Description:
        Set *r_key and *r_data to point to the oldest item in a_oh, and delete the item from a_oh.
void
oh_dump (cw_oh_t * a_oh, cw_bool_t a_all)
    Input(s):
        a_oh:
            Pointer to an oh.
        a_all:
            TRUE: Dump the contents of the hash table.
            FALSE: Only dump the metadata.
    Output(s):
        Internal state of a_oh printed to cw_g_out.
    Description:
        Print the internal state of a_oh.
cw_uint64_t
oh_get_num_collisions (cw_oh_t * a_oh)
    Input(s):
        a_oh:
            Pointer to an oh.
    Output(s):
        retval:
            Number of collisions.
    Description:
        Return the number of collisions that have occurred.
cw_uint64_t
oh_get_num_inserts (cw_oh_t * a_oh)
    Input(s):
        a_oh:
            Pointer to an oh.
    Output(s):
        retval:
            Number of insertions.
    Description:
        Return the number of insertions.
cw_uint64_t
oh_get_num_deletes (cw_oh_t * a_oh)
    Input(s):
        a_oh:
            Pointer to an oh.
    Output(s):
        retval:
            Number of deletions.
    Description:
        Return the number of deletions.
cw_uint64_t
oh_get_num_grows (cw_oh_t * a_oh)
    Input(s):
        a_oh:
            Pointer to an oh.
    Output(s):
        retval:
            Number of table grows.
    Description:
        Return the number of table grows.
cw_uint64_t
oh_get_num_shrinks (cw_oh_t * a_oh)
    Input(s):
        a_oh:
            Pointer to an oh.
    Output(s):
        retval:
            Number of table shrinks.
    Description:
        Return the number of table shrinks.
cw_uint64_t
oh_h1_string (const void * a_key)
    Input(s):
        a_key:
            Pointer to a key.
    Output(s):
        retval:
            Hash result.
    Description:
        Default primary hash function. This is a string hash, so if the keys being used for an oh instance aren't strings, don't use this.
cw_uint64_t
oh_h1_direct (const void * a_key)
    Input(s):
        a_key:
            Pointer to a key.
    Output(s):
        retval:
            Hash result.
    Description:
        Alternate primary hash function. This is a direct pointer hash.
cw_bool_t
oh_key_compare_string (const void * a_k1, const void * a_k2)
    Input(s):
        a_k1:
            Pointer to a key.
        a_k2:
            Pointer to a key.
    Output(s):
        retval:
            FALSE: Not equal.
            TRUE: Equal.
    Description:
        Compare two keys (NULL-terminated strings) for equality.
cw_bool_t
oh_key_compare_direct (const void * a_k1, const void * a_k2)
    Input(s):
        a_k1:
            Pointer to a key.
        a_k2:
            Pointer to a key.
    Output(s):
        retval:
            FALSE: Not equal.
            TRUE: Equal.
    Description:
        Compare two keys (pointers) for equality.

SEE ALSO
libstash(3s).

HISTORY
Written by Jason Evans <jasone@canonware.com>.