\chapter{How A Hash Works\label{chap:advhash}}

\section{Program Listing of Example Implementation}

This appendix is a general, language-independent overview of how a hash table (or simply a hash) 
works. I will present the complete source code of a Perl class module \mono{Hash}, 
which is a hash implemented in Perl. All basic hash operations have been built into the
module. After you have learnt how a hash table works, you can then implement one likewise 
in another programming language, in case one is not available. This implementation is
written in an object-oriented style so that it can be reused and extended very easily.
Understanding of the source program shown below requires familiarity of object-oriented
programming in Perl. Therefore, you should be able to understand the whole of the source 
code if you have read through this tutorial and, as a result, I will not attempt to describe
the programming constructs in detail in the text below. \\

Please note that the given \mono{Hash} class is intended for illustration purpose only,
and is not optimized in any way for performance or utilization. Therefore, you are not
advised to use it in production environments. \\

\head{EXAMPLE}{Hash Table Implementation}
\lstinputlisting[backgroundcolor=\color{CodeBackground}]{src/apphash/Hash.pm}

In Chapter~\ref{chap:basicds} I tried to compare the efficiency of searching for an 
item in an array by various methods, namely linear search and binary search. I 
mentioned that although you may search for an item in an array, you should not try
to do so because neither method is efficient when the population (number of items) 
becomes large. I purported that searching in a hash is more efficient compared with
an array. However, I could not give you any evidence for it because you cannot look
at the internals of Perl builtin hashes to examine the process of searching. Now this
self-written implementation lets you examine the process in more detail. By putting
the module in ``debug'' mode, some extra information reflecting the internal state 
will be sent to the standard error. In this implementation, when the \mono{search()}
internal method is invoked, the number of comparisons will be output to let you see
how many comparisons is needed to arrive at the conclusion of whether a hit or a miss
occurs. \\

This example program uses the self-implemented hash. A hash is created and populated
with 100 (may be less, if collision occurs, i.e. generation of the same value multiple
times) integers and the user inputs a number to check if it appears in the generated
list of integers: \\

\lstinputlisting[backgroundcolor=\color{CodeBackground}]{src/apphash/testhash.pl}

\section{Overview}

A hash table is actually composed of arrays which possess additional instruments to
ensure efficient indexing of data. A hash table has three fundamental operations ---
insertion, searching and deletion. They can all be performed very efficiently regardless
of the population. \\

Conceptually, a hash table consists of a number of \term{slots}. 
Each hash table is associated with a \term{hash function}, which
transforms the key into a slot index. \\ 

To insert a key-value pair into the hash, a slot index is computed from the key, using the hash function. In this
way, the key will be assigned to one of the slots. The key-value pair will be appended to the slot. \\

It is possible that multiple keys will be mapped to the same slot index. We describe this situation
as a \term{collision}. This must occur if the population is larger than the number of slots. However,
because of the characteristics of the hash function, it is possible that collision occurs even if the 
number of slots is larger than the population. 
Several \term{collision resolution} mechanisms exist that may be used 
to address this problem. The method that is described in this section is known as \term{chaining}.
That is, items that are mapped to the same slot are linked together, like a chain. \\

To locate an item with a particular key in the hash, we essentially repeat the procedure by computing
the slot index. Then, we perform a linear search on the chain attached to the slot. If an item with
this key exists in the hash, it must exist in this chain. If we traverse the chain and cannot find
a matching key, then we conclude the key is not in the hash. Therefore, with the help of a slot index
we reduce the traversal from all items to just items whose key maps to a single slot index. That truly
explains why searching is very efficient for hashes. \\

Other hash operations have to depend on searching. For example, to delete a hash element simply compute
the slot index and search for the key in the chain corresponding to the slot index. If one is found, 
remove the item and fix the linkages in the broken chain. \\

\section{Principles}

Let the number of slots in a hash be $m$ and the population be $n$. Therefore, in the ideal case when 
the population is evenly distributed over all available slots, the average number of items on each 
chain (\term{load factor}) is thus $n/m$, assuming $n \geq m$. If $n < m$, then in the ideal case 
all $m$ items are distributed over $n$ of $m$ slots, so some slots are empty while the others have
the maximum chain length of 1. \\ %For the purpose of this chapter, I define utilization as the ratio of
%the number of occupied slots to the total number of slots or the population, whichever is smaller.
%Therefore, it may be specified as \\

%\begin{displaymath}
%Utilization = \frac{\textstyle \#\ of\ occupied\ slots}{min(m, n)} \\
%\end{displaymath}

Efficiency of hash access is determined by how well (uniformly) the items are distributed over the
available slots. Therefore, the hash function used exerts a direct impact. Construction of good
hash functions is a topic under constant research. However, how well a hash function
performs is not only determined by the hash function itself, but also by the nature
of the keys, which depends on the domain in which the hash is to be used. It is probable
that a hash function that performs well in one scenario does not perform well in another scenario.
Therefore, a perfect hash function can hardly be achieved in practice if the application domain
is not known in advance. \\

An optimal choice of the number of slots is also important. For hash item access, once the
slot index is computed, a linear search for the key on the chain attached to the slot has
to be performed. Therefore, the shorter is the chain, the more efficient is the hash access. 
Again, the optimal number of slots also depends on the application domain. \\

\section{Notes on Implementation}

In the sample implementation,
the default number of slots is 17, but you may override it by specifying the \mono{NUMSLOTS}
key in the class constructor. The Perl builtin hash is 
different from this implementation in that the implementation provided by Perl
is a \term{dynamic hash table}. That means, the number of slots is not fixed throughout
its lifetime. A dynamic hash table is able to increase the number of slots as items 
are constantly added to the hash. This keeps the chains short on average so that 
access is still efficient when the population grows large. However, because the principles
of dynamic hash tables is complicated, you should seek external documentation for more
information. \\

The chains in my implementation are constructed in the form of \term{linked lists}. This
is usually the preferred way of implementing a chain in programming languages supporting
some sort of references. However, you may also use an array to represent it in case
references are not supported in certain programming languages. \\

\section*{Web Links}

\begin{list}{\thechapter.\arabic{count}}{\usecounter{count}}
\item {
	\link{http://www.perl.com/pub/a/2002/10/01/hashes.html}{perl.com: How Hashes Really Work} \\
	\textit{http://www.perl.com/pub/a/2002/10/01/hashes.html}
}	
\end{list}

