1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-12 05:01:15 +03:00

Code review for improved-hashing patch. Fix some portability issues

(char != unsigned char, Datum != uint32); make use of new hash code in
dynahash hash tables and hash joins.
This commit is contained in:
Tom Lane
2002-03-09 17:35:37 +00:00
parent 1eb31d197d
commit c422b5ca6b
11 changed files with 111 additions and 187 deletions

View File

@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/hash/dynahash.c,v 1.41 2002/03/02 21:39:33 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/hash/dynahash.c,v 1.42 2002/03/09 17:35:36 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -329,8 +329,7 @@ init_htab(HTAB *hashp, long nelem)
}
#if HASH_DEBUG
fprintf(stderr, "%s\n%s%p\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%x\n%s%x\n%s%d\n%s%d\n",
"init_htab:",
fprintf(stderr, "init_htab:\n%s%p\n%s%ld\n%s%ld\n%s%d\n%s%ld\n%s%u\n%s%x\n%s%x\n%s%ld\n%s%ld\n",
"TABLE POINTER ", hashp,
"DIRECTORY SIZE ", hctl->dsize,
"SEGMENT SIZE ", hctl->ssize,
@@ -453,7 +452,7 @@ hash_stats(const char *where, HTAB *hashp)
fprintf(stderr, "%s: this HTAB -- accesses %ld collisions %ld\n",
where, hashp->hctl->accesses, hashp->hctl->collisions);
fprintf(stderr, "hash_stats: entries %ld keysize %ld maxp %d segmentcount %d\n",
fprintf(stderr, "hash_stats: entries %ld keysize %ld maxp %u segmentcount %ld\n",
hashp->hctl->nentries, hashp->hctl->keysize,
hashp->hctl->max_bucket, hashp->hctl->nsegs);
fprintf(stderr, "%s: total accesses %ld total collisions %ld\n",
@@ -470,7 +469,7 @@ static uint32
call_hash(HTAB *hashp, void *k)
{
HASHHDR *hctl = hashp->hctl;
long hash_val,
uint32 hash_val,
bucket;
hash_val = hashp->hash(k, (int) hctl->keysize);
@@ -479,7 +478,7 @@ call_hash(HTAB *hashp, void *k)
if (bucket > hctl->max_bucket)
bucket = bucket & hctl->low_mask;
return (uint32) bucket;
return bucket;
}
/*----------
@@ -647,7 +646,7 @@ hash_search(HTAB *hashp,
/* caller is expected to fill the data field on return */
/* Check if it is time to split the segment */
if (++hctl->nentries / (hctl->max_bucket + 1) > hctl->ffactor)
if (++hctl->nentries / (long) (hctl->max_bucket + 1) > hctl->ffactor)
{
/*
* NOTE: failure to expand table is not a fatal error, it
@@ -795,10 +794,10 @@ expand_table(HTAB *hashp)
/*
* If we crossed a power of 2, readjust masks.
*/
if (new_bucket > hctl->high_mask)
if ((uint32) new_bucket > hctl->high_mask)
{
hctl->low_mask = hctl->high_mask;
hctl->high_mask = new_bucket | hctl->low_mask;
hctl->high_mask = (uint32) new_bucket | hctl->low_mask;
}
/*

View File

@@ -9,14 +9,16 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/hash/hashfn.c,v 1.15 2001/10/25 05:49:51 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/hash/hashfn.c,v 1.16 2002/03/09 17:35:36 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "access/hash.h"
#include "utils/hsearch.h"
/*
* string_hash: hash function for keys that are null-terminated strings.
*
@@ -27,91 +29,17 @@
*
* NOTE: this is the default hash function if none is specified.
*/
long
uint32
string_hash(void *key, int keysize)
{
unsigned char *k = (unsigned char *) key;
long h = 0;
while (*k)
h = (h * PRIME1) ^ (*k++);
h %= PRIME2;
return h;
return DatumGetUInt32(hash_any((unsigned char *) key, strlen((char *) key)));
}
/*
* 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).
*/
long
uint32
tag_hash(void *key, int keysize)
{
int *k = (int *) key;
long h = 0;
/*
* 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
* cases for up to 32. Bigger than this will resort to a for loop
* (see the default case).
*/
switch (keysize)
{
case 8 * sizeof(int):
h = (h * PRIME1) ^(*k++);
/* fall through */
case 7 * sizeof(int):
h = (h * PRIME1) ^(*k++);
/* fall through */
case 6 * sizeof(int):
h = (h * PRIME1) ^(*k++);
/* fall through */
case 5 * sizeof(int):
h = (h * PRIME1) ^(*k++);
/* fall through */
case 4 * sizeof(int):
h = (h * PRIME1) ^(*k++);
/* fall through */
case 3 * sizeof(int):
h = (h * PRIME1) ^(*k++);
/* fall through */
case 2 * sizeof(int):
h = (h * PRIME1) ^(*k++);
/* fall through */
case sizeof(int):
h = (h * PRIME1) ^(*k++);
break;
default:
/* 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)
{
unsigned char *keybyte = (unsigned char *) k;
do
h = (h * PRIME1) ^ (*keybyte++);
while (--keysize > 0);
}
break;
}
h %= PRIME2;
return h;
return DatumGetUInt32(hash_any((unsigned char *) key, keysize));
}