99 *
1010 *
1111 * IDENTIFICATION
12- * $PostgreSQL: pgsql/src/backend/utils/hash/dynahash.c,v 1.53 2004/08/29 05:06:50 momjian Exp $
12+ * $PostgreSQL: pgsql/src/backend/utils/hash/dynahash.c,v 1.54 2004/09/28 20:46:34 tgl Exp $
1313 *
1414 *-------------------------------------------------------------------------
1515 */
6363 */
6464static void * DynaHashAlloc (Size size );
6565static HASHSEGMENT seg_alloc (HTAB * hashp );
66- static bool element_alloc (HTAB * hashp );
66+ static bool element_alloc (HTAB * hashp , int nelem );
6767static bool dir_realloc (HTAB * hashp );
6868static bool expand_table (HTAB * hashp );
6969static bool hdefault (HTAB * hashp );
@@ -228,11 +228,26 @@ hash_create(const char *tabname, long nelem, HASHCTL *info, int flags)
228228CurrentDynaHashCxt = hashp -> hcxt ;
229229}
230230
231+ /* Build the hash directory structure */
231232if (!init_htab (hashp ,nelem ))
232233{
233234hash_destroy (hashp );
234235return NULL ;
235236}
237+
238+ /*
239+ * For a shared hash table, preallocate the requested number of elements.
240+ * This reduces problems with run-time out-of-shared-memory conditions.
241+ */
242+ if (flags & HASH_SHARED_MEM )
243+ {
244+ if (!element_alloc (hashp , (int )nelem ))
245+ {
246+ hash_destroy (hashp );
247+ return NULL ;
248+ }
249+ }
250+
236251return hashp ;
237252}
238253
@@ -631,7 +646,7 @@ hash_search(HTAB *hashp,
631646if (currBucket == NULL )
632647{
633648/* no free elements. allocate another chunk of buckets */
634- if (!element_alloc (hashp ))
649+ if (!element_alloc (hashp , HASHELEMENT_ALLOC_INCR ))
635650return NULL ;/* out of memory */
636651currBucket = hctl -> freeList ;
637652Assert (currBucket != NULL );
@@ -898,7 +913,7 @@ seg_alloc(HTAB *hashp)
898913 * allocate some new elements and link them into the free list
899914 */
900915static bool
901- element_alloc (HTAB * hashp )
916+ element_alloc (HTAB * hashp , int nelem )
902917{
903918HASHHDR * hctl = hashp -> hctl ;
904919Size elementSize ;
@@ -910,13 +925,13 @@ element_alloc(HTAB *hashp)
910925
911926CurrentDynaHashCxt = hashp -> hcxt ;
912927tmpElement = (HASHELEMENT * )
913- hashp -> alloc (HASHELEMENT_ALLOC_INCR * elementSize );
928+ hashp -> alloc (nelem * elementSize );
914929
915930if (!tmpElement )
916931return false;
917932
918933/* link all the new entries into the freelist */
919- for (i = 0 ;i < HASHELEMENT_ALLOC_INCR ;i ++ )
934+ for (i = 0 ;i < nelem ;i ++ )
920935{
921936tmpElement -> link = hctl -> freeList ;
922937hctl -> freeList = tmpElement ;