/* hash.c */

/* Copyright 1997 by Eberhard Mattes <mattes@azu.informatik.uni-stuttgart.de>
   Donated to the public domain.  No warranty.

   1997-07-22 Initial version
   1997-09-06 Moved from squid-gw to libem */

#include <stdlib.h>
#include <string.h>
#include <limits.h>

/* Select how to compute the hash code.  If this macro is defined, it
   should evaluate to an integer by which the previous hash value is
   multipled.  If this macro is not defined, the hash value will be
   rotated. */

#define FACTOR	3	/* Multiplying by 3 should be efficient. */

/* This macro assumes that there are no unused bits in `unsigned'. */

#define BITS(u)		 (CHAR_BIT * sizeof (u))
#define ROTATE_LEFT(u,n) (((u) << (n)) | ((u) >> (BITS (h) - (n))))

#ifdef FACTOR
#define HASH_STEP(h,c) ((h) * FACTOR + (c))
#else
#define HASH_STEP(h,c) (ROTATE_LEFT ((h), 7) ^ (c))
#endif

unsigned hash (const char *s, size_t n, unsigned hash_size)
{
  unsigned h = 0;
  if (n != 0)
    {
      /* Speed hack. */
      h = (unsigned char)*s++; --n;
    }
  while (n != 0)
    {
      h = HASH_STEP (h, (unsigned char)*s);
      ++s; --n;
    }
  return h % hash_size;
}
