diff --git a/src/backend/utils/hash/dynahash.c b/src/backend/utils/hash/dynahash.c index 9555e25d3021572c9e082fc22531908071e0f1df..5124fe1efdba1aa298cdb51a5287ddc009add9e0 100644 --- a/src/backend/utils/hash/dynahash.c +++ b/src/backend/utils/hash/dynahash.c @@ -9,7 +9,7 @@ * * * 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; HASHSEGMENT *segp; + long lnbuckets; int nbuckets; int nsegs; @@ -319,9 +320,9 @@ init_htab(HTAB *hashp, long nelem) * number of buckets. Allocate space for the next greater power of * 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->high_mask = (nbuckets << 1) - 1; @@ -363,6 +364,10 @@ init_htab(HTAB *hashp, long nelem) 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 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, @@ -394,7 +399,8 @@ hash_estimate_size(long num_entries, Size entrysize) nSegments, nDirEntries, nElementAllocs, - elementSize; + elementSize, + elementAllocCnt; /* estimate number of buckets wanted */ 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)); /* segments */ 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); - nElementAllocs = (num_entries - 1) / HASHELEMENT_ALLOC_INCR + 1; - size += nElementAllocs * HASHELEMENT_ALLOC_INCR * elementSize; + elementAllocCnt = Min(num_entries, HASHELEMENT_ALLOC_MAX); + elementAllocCnt = Max(elementAllocCnt, 1); + nElementAllocs = (num_entries - 1) / elementAllocCnt + 1; + size += nElementAllocs * elementAllocCnt * elementSize; return size; } @@ -633,7 +641,7 @@ hash_search(HTAB *hashp, if (currBucket == NULL) { /* 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 */ if (action == HASH_ENTER_NULL) diff --git a/src/include/utils/hsearch.h b/src/include/utils/hsearch.h index 5bd693063acf9cef083eab7286a0e4d11d670a39..b4bede7666e64a68a2f87663f3e3e085607aca61 100644 --- a/src/include/utils/hsearch.h +++ b/src/include/utils/hsearch.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * 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 */ long max_dsize; /* 'dsize' limit if directory is fixed * size */ + int nelem_alloc; /* number of entries to allocate at once */ HASHELEMENT *freeList; /* linked list of free elements */ #ifdef HASH_STATISTICS long accesses; @@ -158,8 +159,8 @@ typedef struct HASHCTL /* max_dsize value to indicate expansible directory */ #define NO_MAX_DSIZE (-1) -/* number of hash elements allocated at once */ -#define HASHELEMENT_ALLOC_INCR (32) +/* max number of hash elements allocated at once */ +#define HASHELEMENT_ALLOC_MAX (32) /* hash_search operations */ typedef enum diff --git a/src/timezone/pgtz.c b/src/timezone/pgtz.c index 20f4b898c01148541c44ea973aacec374048993e..305bea2e5ebda486f0b4a8bdf68c6ae7a583412b 100644 --- a/src/timezone/pgtz.c +++ b/src/timezone/pgtz.c @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * * 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); timezone_cache = hash_create("Timezones", - 31, + 4, &hash_ctl, HASH_ELEM); if (!timezone_cache)