%-*-mode:latex-*-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Copyright (C) 1996-2004 Jason Evans <jasone@canonware.com>.
% All rights reserved.
% 
% Redistribution and use in source and binary forms, with or without
% modification, are permitted provided that the following conditions
% are met:
% 1. Redistributions of source code must retain the above copyright
%    notice(s), this list of conditions and the following disclaimer
%    unmodified other than the allowable addition of one or more
%    copyright notices.
% 2. Redistributions in binary form must reproduce the above copyright
%    notice(s), this list of conditions and the following disclaimer in
%    the documentation and/or other materials provided with the
%    distribution.
% 
% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY
% EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
% PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE
% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
% BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
% WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
% OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
% EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Version: Onyx 5.1.1
%
% ch portion of Onyx Manual.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\subsection{ch}
\label{ch}
\label{chi}
\index{ch@\classname{ch}{}}

The \classname{ch} class implements chained hashing.  It uses a simple bucket
chaining hash table implementation.  Table size is set at creation time, and
cannot be changed, so performance will suffer if a \classname{ch} object is
over-filled.  The main \ctype{cw\_ch\_t} data structure and the table are
contiguously allocated, which means that care must be taken when manually
pre-allocating space for the structure.  Each item that is inserted into the
\classname{ch} object is encapsulated by a \classname{chi} object, for which
space can optionally be passed in as a parameter to \cfunc{ch\_insert}{}.  If no
space for the \classname{chi} object is passed in, an opaque allocator function
is used internally for allocation.

Multiple entries with the same key are allowed and are stored in LIFO order.

The \classname{ch} class is meant to be small and simple without compromising
performance.  Note that it is not well suited for situations where the number of
items can vary wildly; the \htmlref{\classname{dch}}{dch} class is designed for
such situations.

\subsubsection{API}
\begin{capi}
\label{CW_CH_TABLE2SIZEOF}
\index{CW_CH_TABLE2SIZEOF@\cppmacro{CW\_CH\_TABLE2SIZEOF}{}}
\citem{\cppmacro[uint32\_t]{CW\_CH\_TABLE2SIZEOF}{uint32\_t
a\_table\_size}}
	\begin{capilist}
	\item[Input(s): ]
		\begin{description}\item[]
		\item[a\_table\_size: ]
			Number of slots in the hash table.
		\end{description}
	\item[Output(s): ]
		\begin{description}\item[]
		\item[retval: ]
			Size of a \classname{ch} object with
			\cvar{a\_table\_size} slots.
		\end{description}
	\item[Exception(s): ] None.
	\item[Description: ]
		Calculate the size of a \classname{ch} object with
		\cvar{a\_table\_size} slots.
	\end{capilist}
\label{ch_new}
\index{ch_new@\cfunc{ch\_new}{}}
\citem{\cfunc[]{ch\_new}{cw\_ch\_t *a\_ch, cw\_mema\_t *a\_mema, uint32\_t
a\_table\_size, cw\_ch\_hash\_t *a\_hash, cw\_ch\_key\_comp\_t *a\_key\_comp}}
	\begin{capilist}
	\item[Input(s): ]
		\begin{description}\item[]
		\item[a\_ch: ]
			Pointer to space for a \classname{ch} with
			\cvar{a\_table\_size} slots, or NULL.  Use the
			\cppmacro{CW\_CH\_TABLE2SIZEOF}{} macro to calculate
			the total space needed for a given table size.
		\item[a\_mema: ]
			Pointer to a memory allocator.
		\item[a\_table\_size: ]
			Number of slots in the hash table.
		\item[a\_hash: ]
			Pointer to a hashing function.
		\item[a\_key\_comp: ]
			Pointer to a key comparison function.
		\end{description}
	\item[Output(s): ]
		\begin{description}\item[]
		\item[retval: ]
			Pointer to a \classname{ch}.
		\end{description}
	\item[Exception(s): ]
		\begin{description}\item[]
		\item[\htmlref{CW\_ONYXX\_OOM}{CW_ONYXX_OOM}.]
		\end{description}
	\item[Description: ]
		Constructor.
	\end{capilist}
\label{ch_delete}
\index{ch_delete@\cfunc{ch\_delete}{}}
\citem{\cfunc[void]{ch\_delete}{cw\_ch\_t *a\_ch}}
	\begin{capilist}
	\item[Input(s): ]
		\begin{description}\item[]
		\item[a\_ch: ]
			Pointer to a \classname{ch}.
		\end{description}
	\item[Output(s): ] None.
	\item[Exception(s): ] None.
	\item[Description: ]
		Destructor.
	\end{capilist}
\label{ch_count}
\index{ch_count@\cfunc{ch\_count}{}}
\citem{\cfunc[uint32\_t]{ch\_count}{cw\_ch\_t *a\_ch}}
	\begin{capilist}
	\item[Input(s): ]
		\begin{description}\item[]
		\item[a\_ch: ]
			Pointer to a \classname{ch}.
		\end{description}
	\item[Output(s): ]
		\begin{description}\item[]
		\item[retval: ]
			Number of items in \cvar{a\_ch}.
		\end{description}
	\item[Exception(s): ] None.
	\item[Description: ]
		Return the number of items in \cvar{a\_ch}.
	\end{capilist}
\label{ch_insert}
\index{ch_insert@\cfunc{ch\_insert}{}}
\citem{\cfunc[void]{ch\_insert}{cw\_ch\_t *a\_ch, const void *a\_key, const void
*a\_data, cw\_chi\_t *a\_chi}}
	\begin{capilist}
	\item[Input(s): ]
		\begin{description}\item[]
		\item[a\_ch: ]
			Pointer to a \classname{ch}.
		\item[a\_key: ]
			Pointer to a key.
		\item[a\_data: ]
			Pointer to data associated with \cvar{a\_key}.
		\item[a\_chi: ]
			Pointer to space for a \classname{chi}, or NULL.
		\end{description}
	\item[Output(s): ] None.
	\item[Exception(s): ]
		\begin{description}\item[]
		\item[\htmlref{CW\_ONYXX\_OOM}{CW_ONYXX_OOM}.]
		\end{description}
	\item[Description: ]
		Insert \cvar{a\_data} into \cvar{a\_ch}, using key
		\cvar{a\_key}.  Use \cvar{a\_chi} for the internal
		\classname{chi} container if non-NULL.
	\end{capilist}
\label{ch_remove}
\index{ch_remove@\cfunc{ch\_remove}{}}
\citem{\cfunc[bool]{ch\_remove}{cw\_ch\_t *a\_ch, const void
*a\_search\_key, void **r\_key, void **r\_data, cw\_chi\_t **r\_chi}}
	\begin{capilist}
	\item[Input(s): ]
		\begin{description}\item[]
		\item[a\_ch: ]
			Pointer to a \classname{ch}.
		\item[a\_search\_key: ]
			Pointer to the key to search with.
		\item[r\_key: ]
			Pointer to a key pointer, or NULL.
		\item[r\_data: ]
			Pointer to a data pointer, or NULL.
		\item[r\_chi: ]
			Pointer to a \classname{chi} pointer, or NULL.
		\end{description}
	\item[Output(s): ]
		\begin{description}\item[]
		\item[retval: ]
			\begin{description}\item[]
			\item[false: ]
				Success.
			\item[true: ]
				Item with key \cvar{a\_search\_key} not	found.
			\end{description}
		\item[*r\_key: ]
			If (\cvar{r\_key} != NULL) and (retval == false),
			pointer to a key.  Otherwise, undefined.
		\item[*r\_data: ]
			If (\cvar{r\_data} != NULL) and (retval == false),
			pointer to data.  Otherwise, undefined.
		\item[*r\_chi: ]
			If (\cvar{r\_chi} != NULL) and (retval == false),
			pointer to space for a \classname{chi}, or NULL.
			Otherwise, undefined.
		\end{description}
	\item[Exception(s): ] None.
	\item[Description: ]
		Remove the item from \cvar{a\_ch} that was most recently
		inserted with key \cvar{a\_search\_key}.  If successful, set
		\cvar{*r\_key} and \cvar{*r\_data} to point to the key, data,
		and externally allocated \classname{chi}, respectively.
	\end{capilist}
\label{ch_chi_remove}
\index{ch_chi_remove@\cfunc{ch\_chi\_remove}{}}
\citem{\cfunc[void]{ch\_chi\_remove}{cw\_ch\_t *a\_ch, cw\_chi\_t *a\_chi}}
	\begin{capilist}
	\item[Input(s): ]
		\begin{description}\item[]
		\item[a\_ch: ]
			Pointer to a \classname{ch}.
		\item[a\_chi: ]
			Pointer to a \classname{chi}.
		\end{description}
	\item[Output(s): ] None.
	\item[Exception(s): ] None.
	\item[Description: ]
		Remove the item from \cvar{a\_ch} that was inserted using
		\cvar{a\_chi}.
	\end{capilist}
\label{ch_search}
\index{ch_search@\cfunc{ch\_search}{}}
\citem{\cfunc[bool]{ch\_search}{cw\_ch\_t *a\_ch, const void *a\_key,
void **r\_data}}
	\begin{capilist}
	\item[Input(s): ]
		\begin{description}\item[]
		\item[a\_ch: ]
			Pointer to a \classname{ch}.
		\item[a\_key: ]
			Pointer to a key.
		\item[r\_data: ]
			Pointer to a data pointer, or NULL.
		\end{description}
	\item[Output(s): ]
		\begin{description}\item[]
		\item[retval: ]
			\begin{description}\item[]
			\item[false: ]
				Success.
			\item[true: ]
				Item with key \cvar{a\_key} not found in
				\cvar{a\_ch}.
			\end{description}
		\item[*r\_data: ]
			If (\cvar{r\_data} != NULL) and (retval == false),
			pointer to data.
		\end{description}
	\item[Exception(s): ] None.
	\item[Description: ]
		Search for the most recently inserted item with key
		\cvar{a\_key}.  If found, \cvar{*r\_data} to point to the
		associated data.
	\end{capilist}
\label{ch_string_hash}
\index{ch_string_hash@\cfunc{ch\_string\_hash}{}}
\citem{\cfunc[uint32\_t]{ch\_string\_hash}{const void *a\_key}}
	\begin{capilist}
	\item[Input(s): ]
		\begin{description}\item[]
		\item[a\_key: ]
			Pointer to a key.
		\end{description}
	\item[Output(s): ]
		\begin{description}\item[]
		\item[retval: ]
			Hash result.
		\end{description}
	\item[Exception(s): ] None.
	\item[Description: ]
		NULL-terminated string hashing function.
	\end{capilist}
\label{ch_direct_hash}
\index{ch_direct_hash@\cfunc{ch\_direct\_hash}{}}
\citem{\cfunc[uint32\_t]{ch\_direct\_hash}{const void *a\_key}}
	\begin{capilist}
	\item[Input(s): ]
		\begin{description}\item[]
		\item[a\_key: ]
			Pointer to a key.
		\end{description}
	\item[Output(s): ]
		\begin{description}\item[]
		\item[retval: ]
			Hash result.
		\end{description}
	\item[Exception(s): ] None.
	\item[Description: ]
		Direct (pointer) hashing function.
	\end{capilist}
\label{ch_string_key_comp}
\index{ch_string_key_comp@\cfunc{ch\_string\_key\_comp}{}}
\citem{\cfunc[bool]{ch\_string\_key\_comp}{const void *a\_k1, const void
*a\_k2}}
	\begin{capilist}
	\item[Input(s): ]
		\begin{description}\item[]
		\item[a\_k1: ]
			Pointer to a key.
		\item[a\_k2: ]
			Pointer to a key.
		\end{description}
	\item[Output(s): ]
		\begin{description}\item[]
		\item[retval: ]
			\begin{description}\item[]
			\item[false: ]
				Not equal.
			\item[true: ]
				Equal.
			\end{description}
		\end{description}
	\item[Exception(s): ] None.
	\item[Description: ]
		Test two keys (NULL-terminated strings) for equality.
	\end{capilist}
\label{ch_direct_key_comp}
\index{ch_direct_key_comp@\cfunc{ch\_direct\_key\_comp}{}}
\citem{\cfunc[bool]{ch\_direct\_key\_comp}{const void *a\_k1, const void
*a\_k2}}
	\begin{capilist}
	\item[Input(s): ]
		\begin{description}\item[]
		\item[a\_k1: ]
			Pointer to a key.
		\item[a\_k2: ]
			Pointer to a key.
		\end{description}
	\item[Output(s): ]
		\begin{description}\item[]
		\item[retval: ]
			\begin{description}\item[]
			\item[false: ]
				Not equal.
			\item[true: ]
				Equal.
			\end{description}
		\end{description}
	\item[Exception(s): ] None.
	\item[Description: ]
		Test two keys (pointers) for equality.
	\end{capilist}
\end{capi}
