/*
 * cache - handle hashed list of article ids to retrieve
 *
 * Copyright (C) 1994 Stephen Hebditch <steveh@tqmcomms.co.uk>.
 * All rights reserved. TQM Communications, BCM Box 225, London, WC1N 3XX.
 *
 * See README for more information and disclaimers
 *
 * Routines to add items to hashed list and read the list sequentially.
 *
 * $Id: cache.c,v 1.9 1995/01/10 12:44:34 root Exp $
 *
 * $Log: cache.c,v $
 * Revision 1.9  1995/01/10  12:44:34  root
 * Initial coding.
 *
 */

#include "conf.h"

/* POSIX headers */

#define _POSIX_SOURCE 1
#include <sys/types.h>
#include <limits.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* Local headers */

#include "slurp.h"
#include "syslog.h"

/* File-scope variables */

static IDNODE *hash_table [HASHTBLSIZE];	/* Hash table into list */

static int idx;								/* Current hash table entry */
static IDNODE *ptr;							/* Next id node */


/*
 * gethash - calculate hash value for a message id. Stolen from
 * the msgidd patch written by jerry@strobe.ATC.Olivetti.Com.
 */

	static int
gethash (const char *msgid)
	{
	register char *p = (char *) msgid;
	register int h = 0;

	while (*p)
		h += *p++;

	h %= HASHTBLSIZE;

	if (h < 0)
		h = 0;

	return (h);
	}


/*
 * add_id - Add a message id to the cache if not already present.
 * Returns TRUE if the item is new, FALSE if it already exists.
 */

	int
add_id (const char *msgid)
	{
	IDNODE **current;
	IDNODE *new;
	int hash;
	int test;

	hash = gethash (msgid);

	current = &(hash_table [hash]);

	while (*current != NULL)
		{
		test = strcmp (msgid, (*current) -> msgid);
		if (test == 0)
			return (FALSE);
		else if (test > 0)
			break;
		else
			current = &((*current) -> next);
		}

	if ((new = (IDNODE *) malloc (sizeof (IDNODE))) == NULL)
		log_sys ("add_id: malloc %d bytes", sizeof (IDNODE));
	if ((new -> msgid = (char *) malloc (strlen (msgid) + sizeof (char))) == NULL)
		log_sys ("add_id: malloc %d bytes", strlen (msgid) + sizeof (char));
	(void) strcpy (new -> msgid, msgid);
	new -> next = *current;
	new -> used = FALSE;
	*current = new;

	return (TRUE);
	}


/*
 * first_id - Read the first id node from the list.
 */

	IDNODE *
first_id (void)
	{
	idx = 0;
	ptr = hash_table [idx];

	return (next_id ());
	}


/*
 * next_id - Read the next id node from the list.
 */

	IDNODE *
next_id (void)
	{
	static IDNODE *rnode;

	while (idx < HASHTBLSIZE)
		{
		if (ptr != NULL)
			{
			rnode = ptr;
			ptr = ptr -> next;
			return (rnode);
			}
		idx++;
		ptr = hash_table [idx];
		}

	return (NULL);
	}

/* END-OF-FILE */


syntax highlighted by Code2HTML, v. 0.9.1