/*
 * Copyright (c) 2005 Sendmail, Inc. and its suppliers.
 *	All rights reserved.
 *
 * By using this file, you agree to the terms and conditions set
 * forth in the LICENSE file which can be found at the top level of
 * the sendmail distribution.
 */

#include "sm/generic.h"
SM_RCSID("@(#)$Id: ptrhash.c,v 1.1 2005/02/11 23:46:43 ca Exp $")

#include "heapdbg.h"

/*
**  This is a randomly generated table
**  which contains exactly one occurrence
**  of each of the numbers between 0 and 255.
**  It is used by ptrhash.
*/

static uchar
hashtab[SM_HEAP_TABLE_SIZE] =
{
	161, 71, 77,187, 15,229,  9,176,221,119,239, 21, 85,138,203, 86,
	102, 65, 80,199,235, 32,140, 96,224, 78,126,127,144,  0, 11,179,
	 64, 30,120, 23,225,226, 33, 50,205,167,130,240,174, 99,206, 73,
	231,210,189,162, 48, 93,246, 54,213,141,135, 39, 41,192,236,193,
	157, 88, 95,104,188, 63,133,177,234,110,158,214,238,131,233, 91,
	125, 82, 94, 79, 66, 92,151, 45,252, 98, 26,183,  7,191,171,106,
	145,154,251,100,113,  5, 74, 62, 76,124, 14,217,200, 75,115,190,
	103, 28,198,196,169,219, 37,118,150, 18,152,175, 49,136,  6,142,
	 89, 19,243,254, 47,137, 24,166,180, 10, 40,186,202, 46,184, 67,
	148,108,181, 81, 25,241, 13,139, 58, 38, 84,253,201, 12,116, 17,
	195, 22,112, 69,255, 43,147,222,111, 56,194,216,149,244, 42,173,
	232,220,249,105,207, 51,197,242, 72,211,208, 59,122,230,237,170,
	165, 44, 68,123,129,245,143,101,  8,209,215,247,185, 57,218, 53,
	114,121,  3,128,  4,204,212,146,  2,155, 83,250, 87, 29, 31,159,
	 60, 27,107,156,227,182,  1, 61, 36,160,109, 97, 90, 20,168,132,
	223,248, 70,164, 55,172, 34, 52,163,117, 35,153,134, 16,178,228
};

/*
**  PTRHASH -- hash a pointer value
**
**	Parameters:
**		p -- pointer.
**
**	Returns:
**		hash value.
**
**  ptrhash hashes a pointer value to a uniformly distributed random
**  number between 0 and 255.
**
**  This hash algorithm is based on Peter K. Pearson,
**  "Fast Hashing of Variable-Length Text Strings",
**  in Communications of the ACM, June 1990, vol 33 no 6.
*/

int
ptrhash(void *p)
{
	int h;

# if SIZEOF_VOID_P == 4 && SIZEOF_LONG == 4
	ulong n = (ulong) p;

	h = hashtab[n & 0xFF];
	h = hashtab[h ^ ((n >> 8) & 0xFF)];
	h = hashtab[h ^ ((n >> 16) & 0xFF)];
	h = hashtab[h ^ ((n >> 24) & 0xFF)];
# else /* SIZEOF_VOID_P == 4 && SIZEOF_LONG == 4 */
#  if SIZEOF_VOID_P == 8 && SIZEOF_LONG == 8
	ulong n = (ulong) p;

	h = hashtab[n & 0xFF];
	h = hashtab[h ^ ((n >> 8) & 0xFF)];
	h = hashtab[h ^ ((n >> 16) & 0xFF)];
	h = hashtab[h ^ ((n >> 24) & 0xFF)];
	h = hashtab[h ^ ((n >> 32) & 0xFF)];
	h = hashtab[h ^ ((n >> 40) & 0xFF)];
	h = hashtab[h ^ ((n >> 48) & 0xFF)];
	h = hashtab[h ^ ((n >> 56) & 0xFF)];
#  else /* SIZEOF_VOID_P == 8 && SIZEOF_LONG == 8 */
	uchar *cp = (uchar *) &p;
	int i;

	h = 0;
	for (i = 0; i < sizeof(void*); ++i)
		h = hashtab[h ^ cp[i]];
#  endif /* SIZEOF_VOID_P == 8 && SIZEOF_LONG == 8 */
# endif /* SIZEOF_VOID_P == 4 && SIZEOF_LONG == 4 */
	return h;
}


syntax highlighted by Code2HTML, v. 0.9.1