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

Improve dynahash.c's API so that caller can specify the comparison function

as well as the hash function (formerly the comparison function was hardwired
as memcmp()).  This makes it possible to eliminate the special-purpose
hashtable management code in execGrouping.c in favor of using dynahash to
manage tuple hashtables; which is a win because dynahash knows how to expand
a hashtable when the original size estimate was too small, whereas the
special-purpose code was too stupid to do that.  (See recent gripe from
Stephan Szabo about poor performance when hash table size estimate is way
off.)  Free side benefit: when using string_hash, the default comparison
function is now strncmp() instead of memcmp().  This should eliminate some
part of the overhead associated with larger NAMEDATALEN values.
This commit is contained in:
Tom Lane
2003-08-19 01:13:41 +00:00
parent 23e10843db
commit 80860c32d9
9 changed files with 263 additions and 194 deletions

View File

@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: hsearch.h,v 1.28 2003/08/04 02:40:15 momjian Exp $
* $Id: hsearch.h,v 1.29 2003/08/19 01:13:41 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -15,6 +15,23 @@
#define HSEARCH_H
/*
* Hash and comparison functions must have these signatures. Comparison
* functions return zero for match, nonzero for no match. (The comparison
* function definition is designed to allow memcmp() and strncmp() to be
* used directly as key comparison functions.)
*/
typedef uint32 (*HashValueFunc) (const void *key, Size keysize);
typedef int (*HashCompareFunc) (const void *key1, const void *key2,
Size keysize);
/*
* Space allocation function for a hashtable --- designed to match malloc().
* Note: there is no free function API; can't destroy a hashtable unless you
* use the default allocator.
*/
typedef void *(*HashAllocFunc) (Size request);
/*
* Constants
*
@@ -44,6 +61,7 @@
typedef struct HASHELEMENT
{
struct HASHELEMENT *link; /* link to next entry in same bucket */
uint32 hashvalue; /* hash function result for this entry */
} HASHELEMENT;
/* A hash bucket is a linked list of HASHELEMENTs */
@@ -64,8 +82,8 @@ typedef struct HASHHDR
long ffactor; /* Fill factor */
long nentries; /* Number of entries in hash table */
long nsegs; /* Number of allocated segments */
long keysize; /* hash key length in bytes */
long entrysize; /* total user element size in bytes */
Size keysize; /* hash key length in bytes */
Size entrysize; /* total user element size in bytes */
long max_dsize; /* 'dsize' limit if directory is fixed
* size */
HASHELEMENT *freeList; /* linked list of free elements */
@@ -83,8 +101,9 @@ typedef struct HTAB
{
HASHHDR *hctl; /* shared control information */
HASHSEGMENT *dir; /* directory of segment starts */
uint32 (*hash) (void *key, int keysize); /* Hash Function */
void *(*alloc) (Size); /* memory allocator */
HashValueFunc hash; /* hash function */
HashCompareFunc match; /* key comparison function */
HashAllocFunc alloc; /* memory allocator */
MemoryContext hcxt; /* memory context if default allocator
* used */
char *tabname; /* table name (for error messages) */
@@ -97,28 +116,30 @@ typedef struct HASHCTL
{
long ssize; /* Segment Size */
long dsize; /* (initial) Directory Size */
long ffactor; /* Fill factor */
uint32 (*hash) (void *key, int keysize); /* Hash Function */
long keysize; /* hash key length in bytes */
long entrysize; /* total user element size in bytes */
long max_dsize; /* limit to dsize if directory size is
* limited */
void *(*alloc) (Size); /* memory allocation function */
long ffactor; /* Fill factor */
Size keysize; /* hash key length in bytes */
Size entrysize; /* total user element size in bytes */
HashValueFunc hash; /* hash function */
HashCompareFunc match; /* key comparison function */
HashAllocFunc alloc; /* memory allocator */
HASHSEGMENT *dir; /* directory of segment starts */
HASHHDR *hctl; /* location of header in shared mem */
MemoryContext hcxt; /* memory context to use for allocations */
} HASHCTL;
/* Flags to indicate which parameters are supplied */
#define HASH_SEGMENT 0x002 /* Setting segment size */
#define HASH_DIRSIZE 0x004 /* Setting directory size */
#define HASH_FFACTOR 0x008 /* Setting fill factor */
#define HASH_SEGMENT 0x002 /* Set segment size */
#define HASH_DIRSIZE 0x004 /* Set directory size */
#define HASH_FFACTOR 0x008 /* Set fill factor */
#define HASH_FUNCTION 0x010 /* Set user defined hash function */
#define HASH_ELEM 0x020 /* Setting key/entry size */
#define HASH_SHARED_MEM 0x040 /* Setting shared mem const */
#define HASH_ELEM 0x020 /* Set key/entry size */
#define HASH_SHARED_MEM 0x040 /* Set shared mem const */
#define HASH_ATTACH 0x080 /* Do not initialize hctl */
#define HASH_ALLOC 0x100 /* Setting memory allocator */
#define HASH_CONTEXT 0x200 /* Setting explicit memory context */
#define HASH_ALLOC 0x100 /* Set memory allocator */
#define HASH_CONTEXT 0x200 /* Set explicit memory context */
#define HASH_COMPARE 0x400 /* Set user defined comparison function */
/* max_dsize value to indicate expansible directory */
@@ -151,17 +172,17 @@ extern HTAB *hash_create(const char *tabname, long nelem,
HASHCTL *info, int flags);
extern void hash_destroy(HTAB *hashp);
extern void hash_stats(const char *where, HTAB *hashp);
extern void *hash_search(HTAB *hashp, void *keyPtr, HASHACTION action,
extern void *hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action,
bool *foundPtr);
extern void hash_seq_init(HASH_SEQ_STATUS *status, HTAB *hashp);
extern void *hash_seq_search(HASH_SEQ_STATUS *status);
extern long hash_estimate_size(long num_entries, long entrysize);
extern long hash_estimate_size(long num_entries, Size entrysize);
extern long hash_select_dirsize(long num_entries);
/*
* prototypes for functions in hashfn.c
*/
extern uint32 string_hash(void *key, int keysize);
extern uint32 tag_hash(void *key, int keysize);
extern uint32 string_hash(const void *key, Size keysize);
extern uint32 tag_hash(const void *key, Size keysize);
#endif /* HSEARCH_H */