Fix the size of predicate lock manager's shared memory hash tables at creation.
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Mon, 11 Apr 2011 10:43:31 +0000 (13:43 +0300)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Mon, 11 Apr 2011 10:43:31 +0000 (13:43 +0300)
This way they don't compete with the regular lock manager for the slack shared
memory, making the behavior more predictable.

src/backend/storage/lmgr/predicate.c
src/backend/utils/hash/dynahash.c
src/include/utils/hsearch.h

index 72385c2f3eba67cd0cb9e8d749c4bb8f735ac4b6..eceb384e581fb7370bae11f074a9a495070881b0 100644 (file)
@@ -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,
index f718785ee47cadcd4861aeaf6e499146d1930569..d9027291ee355057c813d3184e779193008f7c1f 100644 (file)
@@ -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);
 
index bca34d23e2ed33649ec0024f428c84e3131a7f69..ce54c0a21b17c4e5bd5b966a5456e8932b14aa67 100644 (file)
@@ -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 */