/*
* class: hashClass - a dictionary implemented using an open hash table.
*
* public procedures:
* create( size ) create the hash table with the given size. Note
* that more elements than this can be stored in
* the table; it is a space/time tradeoff; smaller
* tables take somewhat less space, but run more
* slowly; larger tables take more space, but
* run more quickly.
* insert( name, val ) insert the given name into the dictionary
* with the given val. If name already exists in
* the dictionary, its previous value is discarded
* and the new val put in its place. No return
* value.
* lookup( name ) Looks up a name in the dictionary, and returns
* the value found there, or nil if the name is not
* present in the dictionary.
*/
using namespace oadl;
class hashClass {
var
hashSize, /* Number of elements in the hash table */
hashTab; /* The hash table itself - initialized by create() */
public proc
create( size )
{
var
i;
hashSize = size;
hashTab = new Array( size );
for( i = 0; i < size; i += 1 ) {
hashTab[i] = {};
}
}
/* This procedure computes a "hash" index based on the characters
* in the given string. Copied from the Dragon Book; look there
* for more info about hash functions.
*/
proc
hash( val )
{
var
i, n, t, result;
n = val.length();
result = 0;
for( i = 0; i < n; i += 1 ) {
result = (result << 4) + val[i];
t = result & 0xF0000000;
if( t ) {
result ^= (t >> 24); /* OADL >> is unsigned */
result ^= t;
}
}
n = result % hashSize;
if( n < 0 ) n = -n;
return n;
}
public proc
insert( name, val )
{
var
a, i, x, n;
x = hash( name ); /* Find the bucket in the hash table */
a = hashTab[x]; /* Get the entries in this bucket */
n = a.length(); /* Number of entries, times 2 */
/* Search the bucket for the given name. */
for( i = 0; i < n; i += 2 ) {
if( a[i] == name ) {
/* Overwrite old value with new value */
a[i+1] = val;
return;
}
}
/* Extend the bucket with the new name/value pair. */
hashTab[x] = a ## {name, val};
}
public proc
lookup( name )
{
var
a, i, x, n;
x = hash( name ); /* Find the bucket in the hash table */
a = hashTab[x]; /* Get the entries in this bucket */
n = a.length(); /* Number of entries, times 2 */
/* Search the bucket for the given name */
for( i = 0; i < n; i += 2 ) {
if( a[i] == name ) {
/* Found it! Return the value. */
return a[i+1];
}
}
/* If we get here, we couldn't find it. Return failure. */
return nil;
}
} /* class hashClass */
proc main()
{
var
i, hash;
hash = new hashClass(256);
hash.insert( "fred", 1 );
hash.insert( "foo", 2 );
hash.insert( "bar", 3 );
say( "fred = ", hash.lookup( "fred" ), "\n" );
say( "foo = ", hash.lookup( "foo" ), "\n" );
say( "bar = ", hash.lookup( "bar" ), "\n" );
say( "fr = ", hash.lookup( "fr" ), "\n" );
}