1996-07-09 08:22:35 +02:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
*
|
1999-02-14 00:22:53 +01:00
|
|
|
* hashfn.c
|
2001-10-01 07:36:17 +02:00
|
|
|
* Hash functions for use in dynahash.c hashtables
|
1997-09-07 07:04:48 +02:00
|
|
|
*
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
2001-01-24 20:43:33 +01:00
|
|
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
2000-01-26 06:58:53 +01:00
|
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
*
|
|
|
|
* IDENTIFICATION
|
2001-10-25 07:50:21 +02:00
|
|
|
* $Header: /cvsroot/pgsql/src/backend/utils/hash/hashfn.c,v 1.15 2001/10/25 05:49:51 momjian Exp $
|
1996-07-09 08:22:35 +02:00
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
1996-11-03 07:54:38 +01:00
|
|
|
#include "postgres.h"
|
|
|
|
|
1996-07-09 08:22:35 +02:00
|
|
|
#include "utils/hsearch.h"
|
|
|
|
|
|
|
|
/*
|
2001-10-01 07:36:17 +02:00
|
|
|
* string_hash: hash function for keys that are null-terminated strings.
|
|
|
|
*
|
|
|
|
* NOTE: since dynahash.c backs this up with a fixed-length memcmp(),
|
|
|
|
* the key must actually be zero-padded to the specified maximum length
|
|
|
|
* to work correctly. However, if it is known that nothing after the
|
|
|
|
* first zero byte is interesting, this is the right hash function to use.
|
|
|
|
*
|
|
|
|
* NOTE: this is the default hash function if none is specified.
|
1996-07-09 08:22:35 +02:00
|
|
|
*/
|
|
|
|
long
|
2001-10-01 07:36:17 +02:00
|
|
|
string_hash(void *key, int keysize)
|
1996-07-09 08:22:35 +02:00
|
|
|
{
|
1998-02-11 20:14:04 +01:00
|
|
|
unsigned char *k = (unsigned char *) key;
|
2001-10-01 07:36:17 +02:00
|
|
|
long h = 0;
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
while (*k)
|
2001-10-01 07:36:17 +02:00
|
|
|
h = (h * PRIME1) ^ (*k++);
|
|
|
|
|
1997-09-07 07:04:48 +02:00
|
|
|
h %= PRIME2;
|
|
|
|
|
1998-09-01 05:29:17 +02:00
|
|
|
return h;
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
|
|
|
|
2001-10-01 07:36:17 +02:00
|
|
|
/*
|
|
|
|
* tag_hash: hash function for fixed-size tag values
|
|
|
|
*
|
|
|
|
* NB: we assume that the supplied key is aligned at least on an 'int'
|
|
|
|
* boundary, if its size is >= sizeof(int).
|
|
|
|
*/
|
1996-07-09 08:22:35 +02:00
|
|
|
long
|
2001-10-01 07:36:17 +02:00
|
|
|
tag_hash(void *key, int keysize)
|
1996-07-09 08:22:35 +02:00
|
|
|
{
|
2001-10-01 07:36:17 +02:00
|
|
|
int *k = (int *) key;
|
1998-02-26 05:46:47 +01:00
|
|
|
long h = 0;
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
/*
|
2001-10-01 07:36:17 +02:00
|
|
|
* Use four byte chunks in a "jump table" to go a little faster.
|
|
|
|
*
|
|
|
|
* Currently the maximum keysize is 16 (mar 17 1992). I have put in
|
2001-10-25 07:50:21 +02:00
|
|
|
* cases for up to 32. Bigger than this will resort to a for loop
|
2001-10-01 07:36:17 +02:00
|
|
|
* (see the default case).
|
1997-09-07 07:04:48 +02:00
|
|
|
*/
|
|
|
|
switch (keysize)
|
1996-07-09 08:22:35 +02:00
|
|
|
{
|
2001-10-01 07:36:17 +02:00
|
|
|
case 8 * sizeof(int):
|
2001-10-25 07:50:21 +02:00
|
|
|
h = (h * PRIME1) ^(*k++);
|
2001-10-01 07:36:17 +02:00
|
|
|
/* fall through */
|
|
|
|
|
|
|
|
case 7 * sizeof(int):
|
2001-10-25 07:50:21 +02:00
|
|
|
h = (h * PRIME1) ^(*k++);
|
2001-10-01 07:36:17 +02:00
|
|
|
/* fall through */
|
|
|
|
|
1997-09-08 04:41:22 +02:00
|
|
|
case 6 * sizeof(int):
|
2001-10-25 07:50:21 +02:00
|
|
|
h = (h * PRIME1) ^(*k++);
|
1997-09-08 04:41:22 +02:00
|
|
|
/* fall through */
|
1997-09-07 07:04:48 +02:00
|
|
|
|
1997-09-08 04:41:22 +02:00
|
|
|
case 5 * sizeof(int):
|
2001-10-25 07:50:21 +02:00
|
|
|
h = (h * PRIME1) ^(*k++);
|
1997-09-08 04:41:22 +02:00
|
|
|
/* fall through */
|
|
|
|
|
|
|
|
case 4 * sizeof(int):
|
2001-10-25 07:50:21 +02:00
|
|
|
h = (h * PRIME1) ^(*k++);
|
1997-09-08 04:41:22 +02:00
|
|
|
/* fall through */
|
|
|
|
|
|
|
|
case 3 * sizeof(int):
|
2001-10-25 07:50:21 +02:00
|
|
|
h = (h * PRIME1) ^(*k++);
|
1997-09-08 04:41:22 +02:00
|
|
|
/* fall through */
|
|
|
|
|
|
|
|
case 2 * sizeof(int):
|
2001-10-25 07:50:21 +02:00
|
|
|
h = (h * PRIME1) ^(*k++);
|
1997-09-08 04:41:22 +02:00
|
|
|
/* fall through */
|
1997-09-07 07:04:48 +02:00
|
|
|
|
1997-09-08 04:41:22 +02:00
|
|
|
case sizeof(int):
|
2001-10-25 07:50:21 +02:00
|
|
|
h = (h * PRIME1) ^(*k++);
|
1997-09-08 04:41:22 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2001-10-01 07:36:17 +02:00
|
|
|
/* Do an int at a time */
|
|
|
|
for (; keysize >= (int) sizeof(int); keysize -= sizeof(int))
|
|
|
|
h = (h * PRIME1) ^ (*k++);
|
|
|
|
|
|
|
|
/* Cope with any partial-int leftover bytes */
|
|
|
|
if (keysize > 0)
|
1996-07-09 08:22:35 +02:00
|
|
|
{
|
2001-10-25 07:50:21 +02:00
|
|
|
unsigned char *keybyte = (unsigned char *) k;
|
2001-10-01 07:36:17 +02:00
|
|
|
|
|
|
|
do
|
|
|
|
h = (h * PRIME1) ^ (*keybyte++);
|
|
|
|
while (--keysize > 0);
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
1997-09-08 04:41:22 +02:00
|
|
|
break;
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|
1997-09-07 07:04:48 +02:00
|
|
|
|
|
|
|
h %= PRIME2;
|
|
|
|
|
2001-10-01 07:36:17 +02:00
|
|
|
return h;
|
1996-07-09 08:22:35 +02:00
|
|
|
}
|