mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-21 08:29:39 +08:00
Tweak dynahash.c to not allocate so many entries at once when dealing
with a table that has a small predicted size. Avoids wasting several hundred K on the timezone hash table, which is likely to have only one or a few entries, but the entries use up 10Kb apiece ...
This commit is contained in:
parent
943b396245
commit
06ae88a82e
@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/hash/dynahash.c,v 1.62 2005/06/18 20:51:30 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/hash/dynahash.c,v 1.63 2005/06/26 23:32:33 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -311,6 +311,7 @@ init_htab(HTAB *hashp, long nelem)
|
|||||||
{
|
{
|
||||||
HASHHDR *hctl = hashp->hctl;
|
HASHHDR *hctl = hashp->hctl;
|
||||||
HASHSEGMENT *segp;
|
HASHSEGMENT *segp;
|
||||||
|
long lnbuckets;
|
||||||
int nbuckets;
|
int nbuckets;
|
||||||
int nsegs;
|
int nsegs;
|
||||||
|
|
||||||
@ -319,9 +320,9 @@ init_htab(HTAB *hashp, long nelem)
|
|||||||
* number of buckets. Allocate space for the next greater power of
|
* number of buckets. Allocate space for the next greater power of
|
||||||
* two number of buckets
|
* two number of buckets
|
||||||
*/
|
*/
|
||||||
nelem = (nelem - 1) / hctl->ffactor + 1;
|
lnbuckets = (nelem - 1) / hctl->ffactor + 1;
|
||||||
|
|
||||||
nbuckets = 1 << my_log2(nelem);
|
nbuckets = 1 << my_log2(lnbuckets);
|
||||||
|
|
||||||
hctl->max_bucket = hctl->low_mask = nbuckets - 1;
|
hctl->max_bucket = hctl->low_mask = nbuckets - 1;
|
||||||
hctl->high_mask = (nbuckets << 1) - 1;
|
hctl->high_mask = (nbuckets << 1) - 1;
|
||||||
@ -363,6 +364,10 @@ init_htab(HTAB *hashp, long nelem)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Choose number of entries to allocate at a time */
|
||||||
|
hctl->nelem_alloc = (int) Min(nelem, HASHELEMENT_ALLOC_MAX);
|
||||||
|
hctl->nelem_alloc = Max(hctl->nelem_alloc, 1);
|
||||||
|
|
||||||
#if HASH_DEBUG
|
#if HASH_DEBUG
|
||||||
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",
|
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,
|
"TABLE POINTER ", hashp,
|
||||||
@ -394,7 +399,8 @@ hash_estimate_size(long num_entries, Size entrysize)
|
|||||||
nSegments,
|
nSegments,
|
||||||
nDirEntries,
|
nDirEntries,
|
||||||
nElementAllocs,
|
nElementAllocs,
|
||||||
elementSize;
|
elementSize,
|
||||||
|
elementAllocCnt;
|
||||||
|
|
||||||
/* estimate number of buckets wanted */
|
/* estimate number of buckets wanted */
|
||||||
nBuckets = 1L << my_log2((num_entries - 1) / DEF_FFACTOR + 1);
|
nBuckets = 1L << my_log2((num_entries - 1) / DEF_FFACTOR + 1);
|
||||||
@ -411,10 +417,12 @@ hash_estimate_size(long num_entries, Size entrysize)
|
|||||||
size += MAXALIGN(nDirEntries * sizeof(HASHSEGMENT));
|
size += MAXALIGN(nDirEntries * sizeof(HASHSEGMENT));
|
||||||
/* segments */
|
/* segments */
|
||||||
size += nSegments * MAXALIGN(DEF_SEGSIZE * sizeof(HASHBUCKET));
|
size += nSegments * MAXALIGN(DEF_SEGSIZE * sizeof(HASHBUCKET));
|
||||||
/* elements --- allocated in groups of HASHELEMENT_ALLOC_INCR */
|
/* elements --- allocated in groups of up to HASHELEMENT_ALLOC_MAX */
|
||||||
elementSize = MAXALIGN(sizeof(HASHELEMENT)) + MAXALIGN(entrysize);
|
elementSize = MAXALIGN(sizeof(HASHELEMENT)) + MAXALIGN(entrysize);
|
||||||
nElementAllocs = (num_entries - 1) / HASHELEMENT_ALLOC_INCR + 1;
|
elementAllocCnt = Min(num_entries, HASHELEMENT_ALLOC_MAX);
|
||||||
size += nElementAllocs * HASHELEMENT_ALLOC_INCR * elementSize;
|
elementAllocCnt = Max(elementAllocCnt, 1);
|
||||||
|
nElementAllocs = (num_entries - 1) / elementAllocCnt + 1;
|
||||||
|
size += nElementAllocs * elementAllocCnt * elementSize;
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
@ -633,7 +641,7 @@ hash_search(HTAB *hashp,
|
|||||||
if (currBucket == NULL)
|
if (currBucket == NULL)
|
||||||
{
|
{
|
||||||
/* no free elements. allocate another chunk of buckets */
|
/* no free elements. allocate another chunk of buckets */
|
||||||
if (!element_alloc(hashp, HASHELEMENT_ALLOC_INCR))
|
if (!element_alloc(hashp, hctl->nelem_alloc))
|
||||||
{
|
{
|
||||||
/* out of memory */
|
/* out of memory */
|
||||||
if (action == HASH_ENTER_NULL)
|
if (action == HASH_ENTER_NULL)
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/utils/hsearch.h,v 1.38 2005/06/18 20:51:30 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/utils/hsearch.h,v 1.39 2005/06/26 23:32:34 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -97,6 +97,7 @@ typedef struct HASHHDR
|
|||||||
Size entrysize; /* total user element size in bytes */
|
Size entrysize; /* total user element size in bytes */
|
||||||
long max_dsize; /* 'dsize' limit if directory is fixed
|
long max_dsize; /* 'dsize' limit if directory is fixed
|
||||||
* size */
|
* size */
|
||||||
|
int nelem_alloc; /* number of entries to allocate at once */
|
||||||
HASHELEMENT *freeList; /* linked list of free elements */
|
HASHELEMENT *freeList; /* linked list of free elements */
|
||||||
#ifdef HASH_STATISTICS
|
#ifdef HASH_STATISTICS
|
||||||
long accesses;
|
long accesses;
|
||||||
@ -158,8 +159,8 @@ typedef struct HASHCTL
|
|||||||
|
|
||||||
/* max_dsize value to indicate expansible directory */
|
/* max_dsize value to indicate expansible directory */
|
||||||
#define NO_MAX_DSIZE (-1)
|
#define NO_MAX_DSIZE (-1)
|
||||||
/* number of hash elements allocated at once */
|
/* max number of hash elements allocated at once */
|
||||||
#define HASHELEMENT_ALLOC_INCR (32)
|
#define HASHELEMENT_ALLOC_MAX (32)
|
||||||
|
|
||||||
/* hash_search operations */
|
/* hash_search operations */
|
||||||
typedef enum
|
typedef enum
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/timezone/pgtz.c,v 1.35 2005/06/20 08:00:51 neilc Exp $
|
* $PostgreSQL: pgsql/src/timezone/pgtz.c,v 1.36 2005/06/26 23:32:34 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -978,7 +978,7 @@ init_timezone_hashtable(void)
|
|||||||
hash_ctl.entrysize = sizeof(pg_tz);
|
hash_ctl.entrysize = sizeof(pg_tz);
|
||||||
|
|
||||||
timezone_cache = hash_create("Timezones",
|
timezone_cache = hash_create("Timezones",
|
||||||
31,
|
4,
|
||||||
&hash_ctl,
|
&hash_ctl,
|
||||||
HASH_ELEM);
|
HASH_ELEM);
|
||||||
if (!timezone_cache)
|
if (!timezone_cache)
|
||||||
|
Loading…
Reference in New Issue
Block a user