diff --git a/src/backend/storage/lmgr/predicate.c b/src/backend/storage/lmgr/predicate.c index 72385c2f3eba67cd0cb9e8d749c4bb8f735ac4b6..eceb384e581fb7370bae11f074a9a495070881b0 100644 --- a/src/backend/storage/lmgr/predicate.c +++ b/src/backend/storage/lmgr/predicate.c @@ -970,17 +970,15 @@ InitPredicateLocks(void) { HASHCTL info; int hash_flags; - long init_table_size, - max_table_size; + long max_table_size; Size requestSize; bool found; /* - * Compute init/max size to request for predicate lock target hashtable. + * Compute size of predicate lock target hashtable. * Note these calculations must agree with PredicateLockShmemSize! */ max_table_size = NPREDICATELOCKTARGETENTS(); - init_table_size = max_table_size / 2; /* * Allocate hash table for PREDICATELOCKTARGET structs. This stores @@ -991,17 +989,16 @@ InitPredicateLocks(void) info.entrysize = sizeof(PREDICATELOCKTARGET); info.hash = tag_hash; info.num_partitions = NUM_PREDICATELOCK_PARTITIONS; - hash_flags = (HASH_ELEM | HASH_FUNCTION | HASH_PARTITION); + hash_flags = (HASH_ELEM | HASH_FUNCTION | HASH_PARTITION | HASH_FIXED_SIZE); PredicateLockTargetHash = ShmemInitHash("PREDICATELOCKTARGET hash", - init_table_size, + max_table_size, max_table_size, &info, hash_flags); /* Assume an average of 2 xacts per target */ max_table_size *= 2; - init_table_size *= 2; /* * Reserve an entry in the hash table; we use it to make sure there's @@ -1022,18 +1019,17 @@ InitPredicateLocks(void) info.entrysize = sizeof(PREDICATELOCK); info.hash = predicatelock_hash; info.num_partitions = NUM_PREDICATELOCK_PARTITIONS; - hash_flags = (HASH_ELEM | HASH_FUNCTION | HASH_PARTITION); + hash_flags = (HASH_ELEM | HASH_FUNCTION | HASH_PARTITION | HASH_FIXED_SIZE); PredicateLockHash = ShmemInitHash("PREDICATELOCK hash", - init_table_size, + max_table_size, max_table_size, &info, hash_flags); /* - * Compute init/max size to request for serializable transaction - * hashtable. Note these calculations must agree with - * PredicateLockShmemSize! + * Compute size for serializable transaction hashtable. + * Note these calculations must agree with PredicateLockShmemSize! */ max_table_size = (MaxBackends + max_prepared_xacts); @@ -1104,7 +1100,7 @@ InitPredicateLocks(void) info.keysize = sizeof(SERIALIZABLEXIDTAG); info.entrysize = sizeof(SERIALIZABLEXID); info.hash = tag_hash; - hash_flags = (HASH_ELEM | HASH_FUNCTION); + hash_flags = (HASH_ELEM | HASH_FUNCTION | HASH_FIXED_SIZE); SerializableXidHash = ShmemInitHash("SERIALIZABLEXID hash", max_table_size, diff --git a/src/backend/utils/hash/dynahash.c b/src/backend/utils/hash/dynahash.c index f718785ee47cadcd4861aeaf6e499146d1930569..d9027291ee355057c813d3184e779193008f7c1f 100644 --- a/src/backend/utils/hash/dynahash.c +++ b/src/backend/utils/hash/dynahash.c @@ -160,6 +160,7 @@ struct HTAB MemoryContext hcxt; /* memory context if default allocator used */ char *tabname; /* table name (for error messages) */ bool isshared; /* true if table is in shared memory */ + bool isfixed; /* if true, don't enlarge */ /* freezing a shared table isn't allowed, so we can keep state here */ bool frozen; /* true = no more inserts allowed */ @@ -435,6 +436,8 @@ hash_create(const char *tabname, long nelem, HASHCTL *info, int flags) errmsg("out of memory"))); } + if (flags & HASH_FIXED_SIZE) + hashp->isfixed = true; return hashp; } @@ -1334,6 +1337,9 @@ element_alloc(HTAB *hashp, int nelem) HASHELEMENT *prevElement; int i; + if (hashp->isfixed) + return false; + /* Each element has a HASHELEMENT header plus user data. */ elementSize = MAXALIGN(sizeof(HASHELEMENT)) + MAXALIGN(hctlv->entrysize); diff --git a/src/include/utils/hsearch.h b/src/include/utils/hsearch.h index bca34d23e2ed33649ec0024f428c84e3131a7f69..ce54c0a21b17c4e5bd5b966a5456e8932b14aa67 100644 --- a/src/include/utils/hsearch.h +++ b/src/include/utils/hsearch.h @@ -92,6 +92,7 @@ typedef struct HASHCTL #define HASH_CONTEXT 0x200 /* Set memory allocation context */ #define HASH_COMPARE 0x400 /* Set user defined comparison function */ #define HASH_KEYCOPY 0x800 /* Set user defined key-copying function */ +#define HASH_FIXED_SIZE 0x1000 /* Initial size is a hard limit */ /* max_dsize value to indicate expansible directory */