
/*
 * HASH.C
 * (c) 1992-3 J.Harper
 *
 * open hashing module
 */

#include "hash.h"
#include <string.h>

/*
 * _very_ simple hash function
 */
static int
hash(char *name, int tabSize)
{
    int total = 0;
    char c;
    while(c = *name++)
	total += c;
    return(total % tabSize);
}

/****** inserthash **********************************************************
*
*   NAME
*	inserthash -- link a hash node
*
*   SYNOPSIS
*	inserthash(hashTab, hashNode, tabSize)
*
*	void inserthash(HASHNODE **, HASHNODE *, int);
*
*   FUNCTION
*	Links an initialized HASHNODE into a hash table, this node will
*	be inserted before any other nodes with the same name. (ie, calls
*	to inserthash() and removehash() nest).
*
*   INPUTS
*	hashTab	    -- pointer to an array containing tabSize number of
*		       pointers to HASHNODE's.
*	hashNode    -- initialized HASHNODE which is to be linked into the
*		       hashTab
*	tabSize	    -- number of pointers in hashTab
*
*   RESULT
*	none.
*
*   SEE ALSO
*	hash.h, removehash(), findhash()
*
*****************************************************************************
*
*/
void
inserthash(HASHNODE **hashTab, HASHNODE *node, int tabSize)
{
    HASHNODE *lastchain;
    int index = hash(node->h_Name, tabSize);
    lastchain = hashTab[index];
    hashTab[index] = node;
    node->h_Next = lastchain;
    node->h_Prev = NULL;
    if(lastchain)
	lastchain->h_Prev = node;
}

/****** removehash **********************************************************
*
*   NAME
*	removehash -- unlink a hash node
*
*   SYNOPSIS
*	removehash(hashTab, hashNode, tabSize)
*
*	void removehash(HASHNODE **, HASHNODE *, int);
*
*   FUNCTION
*	Unlinks hashNode from hashTable.
*
*   INPUTS
*	hashTab	    -- pointer to the hash table
*	hashNode    -- pointer to the hash node
*	tabSize	    -- number of pointers in hashTab
*
*   RESULT
*	none.
*
*   SEE ALSO
*	hash.h, inserthash(), findhash()
*
*****************************************************************************
*
*/
void
removehash(HASHNODE **hashTab, HASHNODE *node, int tabSize)
{
    HASHNODE *next = node->h_Next;
    HASHNODE *prev = node->h_Prev;
    if(!prev)
	hashTab[hash(node->h_Name, tabSize)] = next;
    else
	prev->h_Next = next;
    if(next)
	next->h_Prev = prev;
}

/****** findhash ************************************************************
*
*   NAME
*	findhash -- find a hash entry
*
*   SYNOPSIS
*	hashNode = findhash(hashTab, name)
*
*	HASHNODE *findhash(HASHNODE **, char *);
*
*   FUNCTION
*	Scans the specified hash table for the specified entry.
*
*   INPUTS
*	hashTab	    -- pointer to the hash table
*	name	    -- name of node to find
*	tabSize	    -- number of pointers in hashTab
*
*   RESULT
*	hashNode    -- pointer to found node or NULL if no matching node
*		       could be found
*
*   SEE ALSO
*	hash.h, inserthash(), removehash()
*
*****************************************************************************
*
*/
HASHNODE *
findhash(HASHNODE **hashTab, char *name, int tabSize)
{
    HASHNODE *node;
    for(node = hashTab[hash(name, tabSize)]; node; node = node->h_Next)
    {
	if(!(stricmp(name, node->h_Name)))
	    break;
    }
    return(node);
}
