Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 06ae88a

Browse files
committed
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 ...
1 parent 943b396 commit 06ae88a

File tree

3 files changed

+22
-13
lines changed

3 files changed

+22
-13
lines changed

src/backend/utils/hash/dynahash.c

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $PostgreSQL: pgsql/src/backend/utils/hash/dynahash.c,v 1.62 2005/06/18 20:51:30 tgl Exp $
12+
* $PostgreSQL: pgsql/src/backend/utils/hash/dynahash.c,v 1.63 2005/06/26 23:32:33 tgl Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -311,6 +311,7 @@ init_htab(HTAB *hashp, long nelem)
311311
{
312312
HASHHDR *hctl = hashp->hctl;
313313
HASHSEGMENT *segp;
314+
long lnbuckets;
314315
int nbuckets;
315316
int nsegs;
316317

@@ -319,9 +320,9 @@ init_htab(HTAB *hashp, long nelem)
319320
* number of buckets. Allocate space for the next greater power of
320321
* two number of buckets
321322
*/
322-
nelem = (nelem - 1) / hctl->ffactor + 1;
323+
lnbuckets = (nelem - 1) / hctl->ffactor + 1;
323324

324-
nbuckets = 1 << my_log2(nelem);
325+
nbuckets = 1 << my_log2(lnbuckets);
325326

326327
hctl->max_bucket = hctl->low_mask = nbuckets - 1;
327328
hctl->high_mask = (nbuckets << 1) - 1;
@@ -363,6 +364,10 @@ init_htab(HTAB *hashp, long nelem)
363364
return false;
364365
}
365366

367+
/* Choose number of entries to allocate at a time */
368+
hctl->nelem_alloc = (int) Min(nelem, HASHELEMENT_ALLOC_MAX);
369+
hctl->nelem_alloc = Max(hctl->nelem_alloc, 1);
370+
366371
#if HASH_DEBUG
367372
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",
368373
"TABLE POINTER ", hashp,
@@ -394,7 +399,8 @@ hash_estimate_size(long num_entries, Size entrysize)
394399
nSegments,
395400
nDirEntries,
396401
nElementAllocs,
397-
elementSize;
402+
elementSize,
403+
elementAllocCnt;
398404

399405
/* estimate number of buckets wanted */
400406
nBuckets = 1L << my_log2((num_entries - 1) / DEF_FFACTOR + 1);
@@ -411,10 +417,12 @@ hash_estimate_size(long num_entries, Size entrysize)
411417
size += MAXALIGN(nDirEntries * sizeof(HASHSEGMENT));
412418
/* segments */
413419
size += nSegments * MAXALIGN(DEF_SEGSIZE * sizeof(HASHBUCKET));
414-
/* elements --- allocated in groups of HASHELEMENT_ALLOC_INCR */
420+
/* elements --- allocated in groups of up to HASHELEMENT_ALLOC_MAX */
415421
elementSize = MAXALIGN(sizeof(HASHELEMENT)) + MAXALIGN(entrysize);
416-
nElementAllocs = (num_entries - 1) / HASHELEMENT_ALLOC_INCR + 1;
417-
size += nElementAllocs * HASHELEMENT_ALLOC_INCR * elementSize;
422+
elementAllocCnt = Min(num_entries, HASHELEMENT_ALLOC_MAX);
423+
elementAllocCnt = Max(elementAllocCnt, 1);
424+
nElementAllocs = (num_entries - 1) / elementAllocCnt + 1;
425+
size += nElementAllocs * elementAllocCnt * elementSize;
418426

419427
return size;
420428
}
@@ -633,7 +641,7 @@ hash_search(HTAB *hashp,
633641
if (currBucket == NULL)
634642
{
635643
/* no free elements. allocate another chunk of buckets */
636-
if (!element_alloc(hashp, HASHELEMENT_ALLOC_INCR))
644+
if (!element_alloc(hashp, hctl->nelem_alloc))
637645
{
638646
/* out of memory */
639647
if (action == HASH_ENTER_NULL)

src/include/utils/hsearch.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/utils/hsearch.h,v 1.38 2005/06/18 20:51:30 tgl Exp $
10+
* $PostgreSQL: pgsql/src/include/utils/hsearch.h,v 1.39 2005/06/26 23:32:34 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -97,6 +97,7 @@ typedef struct HASHHDR
9797
Size entrysize; /* total user element size in bytes */
9898
long max_dsize; /* 'dsize' limit if directory is fixed
9999
* size */
100+
int nelem_alloc; /* number of entries to allocate at once */
100101
HASHELEMENT *freeList; /* linked list of free elements */
101102
#ifdef HASH_STATISTICS
102103
long accesses;
@@ -158,8 +159,8 @@ typedef struct HASHCTL
158159

159160
/* max_dsize value to indicate expansible directory */
160161
#define NO_MAX_DSIZE (-1)
161-
/* number of hash elements allocated at once */
162-
#define HASHELEMENT_ALLOC_INCR (32)
162+
/* max number of hash elements allocated at once */
163+
#define HASHELEMENT_ALLOC_MAX (32)
163164

164165
/* hash_search operations */
165166
typedef enum

src/timezone/pgtz.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
77
*
88
* IDENTIFICATION
9-
* $PostgreSQL: pgsql/src/timezone/pgtz.c,v 1.35 2005/06/20 08:00:51 neilc Exp $
9+
* $PostgreSQL: pgsql/src/timezone/pgtz.c,v 1.36 2005/06/26 23:32:34 tgl Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -978,7 +978,7 @@ init_timezone_hashtable(void)
978978
hash_ctl.entrysize = sizeof(pg_tz);
979979

980980
timezone_cache = hash_create("Timezones",
981-
31,
981+
4,
982982
&hash_ctl,
983983
HASH_ELEM);
984984
if (!timezone_cache)

0 commit comments

Comments
 (0)