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:
@@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user