%-*-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
%
% dch portion of Onyx Manual.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\subsection{dch}
\label{dch}
\index{dch@\classname{dch}{}}

The \classname{dch} class implements dynamic chained hashing.  The
\classname{dch} class is a wrapper around the \classname{ch} class that enforces
fullness/emptiness constraints and rebuilds the hash table when necessary.
Other than this added functionality, the \classname{dch} class behaves almost
exactly like the \classname{ch} class.  See the \htmlref{\classname{ch}}{ch}
class documentation for additional information.

\subsubsection{API}
\begin{capi}

\label{dch_new}
\index{dch_new@\cfunc{dch\_new}{}}
\citem{\cfunc[]{dch\_new}{cw\_dch\_t *a\_dch, cw\_mema\_t *a\_mema,
uint32\_t a\_base\_table, uint32\_t a\_base\_grow, uint32\_t
a\_base\_shrink, cw\_ch\_hash\_t *a\_hash, cw\_ch\_key\_comp\_t *a\_key\_comp}}
	\begin{capilist}
	\item[Input(s): ]
		\begin{description}\item[]
		\item[a\_dch: ]
			Pointer to space for a \classname{dch}, or NULL.
		\item[a\_mema: ]
			Pointer to a memory allocator.
		\item[a\_base\_table: ]
			Number of slots in the initial hash table.
		\item[a\_base\_grow: ]
			Maximum number of items to allow in \cvar{a\_dch} before
			doubling the hash table size.  The same proportions (in
			relation to \cvar{a\_base\_table}) are used to decide
			when to double the table additional times.
		\item[a\_base\_shrink: ]
			Minimum proportional (with respect to
			\cvar{a\_base\_table}) emptiness to allow in the hash
			table before cutting the hash table size in half.
		\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{dch}.
		\end{description}
	\item[Exception(s): ]
		\begin{description}\item[]
		\item[\htmlref{CW\_ONYXX\_OOM}{CW_ONYXX_OOM}.]
		\end{description}
	\item[Description: ]
		Constructor.
	\end{capilist}
\label{dch_delete}
\index{dch_delete@\cfunc{dch\_delete}{}}
\citem{\cfunc[void]{dch\_delete}{cw\_dch\_t *a\_dch}}
	\begin{capilist}
	\item[Input(s): ]
		\begin{description}\item[]
		\item[a\_dch: ]
			Pointer to a \classname{dch}.
		\end{description}
	\item[Output(s): ] None.
	\item[Exception(s): ] None.
	\item[Description: ]
		Destructor.
	\end{capilist}
\label{dch_count}
\index{dch_count@\cfunc{dch\_count}{}}
\citem{\cfunc[uint32\_t]{dch\_count}{cw\_dch\_t *a\_dch}}
	\begin{capilist}
	\item[Input(s): ]
		\begin{description}\item[]
		\item[a\_dch: ]
			Pointer to a \classname{dch}.
		\end{description}
	\item[Output(s): ]
		\begin{description}\item[]
		\item[retval: ]
			Number of items in \cvar{a\_dch}.
		\end{description}
	\item[Exception(s): ] None.
	\item[Description: ]
		Return the number of items in \cvar{a\_dch}.
	\end{capilist}
\label{dch_shrinkable_get}
\index{dch_shrinkable_get@\cfunc{dch\_shrinkable\_get}{}}
\citem{\cfunc[bool]{dch\_shrinkable\_get}{cw\_dch\_t *a\_dch}}
	\begin{capilist}
	\item[Input(s): ]
		\begin{description}\item[]
		\item[a\_dch: ]
			Pointer to a \classname{dch}.
		\end{description}
	\item[Output(s): ]
		\begin{description}\item[]
		\item[retval: ]
			\begin{description}\item[]
			\item[true: ] \cvar{a\_dch} is currently shrinkable
				(initial default).
			\item[false: ] \cvar{a\_dch} is not currently
				shrinkable, so no attempt will be made to shrink
				the hash table in \cfunc{dch\_remove}{} or
				\cfunc{dch\_remove\_iterate}{}.
			\end{description}
		\end{description}
	\item[Exception(s): ] None.
	\item[Description: ]
		Return whether \cvar{a\_dch} is currently shrinkable.
	\end{capilist}
\label{dch_shrinkable_set}
\index{dch_shrinkable_set@\cfunc{dch\_shrinkable\_set}{}}
\citem{\cfunc[void]{dch\_shrinkable\_set}{cw\_dch\_t *a\_dch, bool
a\_shrinkable}}
	\begin{capilist}
	\item[Input(s): ]
		\begin{description}\item[]
		\item[a\_dch: ]
			Pointer to a \classname{dch}.
		\item[a\_shrinkable: ]
			\begin{description}\item[]
			\item[true: ] Set \cvar{a\_dch} to be shrinkable.
			\item[false: ] Set \cvar{a\_dch} to not be shrinkable.
				No attempt will be made to shrink the hash table
				in \cfunc{dch\_remove}{} or
				\cfunc{dch\_remove\_iterate}{} while in this
				state.
			\end{description}
		\end{description}
	\item[Output(s): ] None.
	\item[Exception(s): ] None.
	\item[Description: ]
		Set whether \cvar{a\_dch} should try to shrink the hash table in
		\cfunc{dch\_remove}{} and \cfunc{dch\_remove\_iterate}{}.
	\end{capilist}
\label{dch_insert}
\index{dch_insert@\cfunc{dch\_insert}{}}
\citem{\cfunc[void]{dch\_insert}{cw\_dch\_t *a\_dch, const void *a\_key, const
void *a\_data, cw\_chi\_t *a\_chi}}
	\begin{capilist}
	\item[Input(s): ]
		\begin{description}\item[]
		\item[a\_dch: ]
			Pointer to a \classname{dch}.
		\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\_dch}, using key
		\cvar{a\_key}.  Use \cvar{a\_chi} for the internal
		\classname{chi} container if non-NULL.
	\end{capilist}
\label{dch_remove}
\index{dch_remove@\cfunc{dch\_remove}{}}
\citem{\cfunc[bool]{dch\_remove}{cw\_dch\_t *a\_dch, 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\_dch: ]
			Pointer to a \classname{dch}.
		\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\_dch} 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{dch_chi_remove}
\index{dch_chi_remove@\cfunc{dch\_chi\_remove}{}}
\citem{\cfunc[bool]{dch\_chi\_remove}{cw\_dch\_t *a\_dch, cw\_chi\_t
*a\_chi}}
	\begin{capilist}
	\item[Input(s): ]
		\begin{description}\item[]
		\item[a\_dch: ]
			Pointer to a \classname{dch}.
		\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\_dch} that was inserted using
		\cvar{a\_chi}.
	\end{capilist}
\label{dch_search}
\index{dch_search@\cfunc{dch\_search}{}}
\citem{\cfunc[bool]{dch\_search}{cw\_dch\_t *a\_dch, const void *a\_key,
void **r\_data}}
	\begin{capilist}
	\item[Input(s): ]
		\begin{description}\item[]
		\item[a\_dch: ]
			Pointer to a \classname{dch}.
		\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\_dch}.
			\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}
\end{capi}
