From 731603a92b115db97c1202df243954195070c500 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Sat, 6 Mar 1999 21:17:56 +0000
Subject: [PATCH] A few further tweaks to shared memory space estimation. This
 change brings the default size of the main shmem block back under 1MB, which
 is a fairly popular value for the kernel's SHMMAX parameter.

---
 src/backend/storage/ipc/ipci.c    |  4 +---
 src/backend/storage/lmgr/lock.c   | 23 ++++++++++++++---------
 src/backend/storage/smgr/mm.c     |  6 +++---
 src/backend/utils/hash/dynahash.c | 26 +++++++++++++++++---------
 src/include/storage/lock.h        | 10 +++++++---
 5 files changed, 42 insertions(+), 27 deletions(-)

diff --git a/src/backend/storage/ipc/ipci.c b/src/backend/storage/ipc/ipci.c
index 2f5d1d3a193..e7d6e702bf2 100644
--- a/src/backend/storage/ipc/ipci.c
+++ b/src/backend/storage/ipc/ipci.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/storage/ipc/ipci.c,v 1.22 1999/02/22 06:16:49 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/storage/ipc/ipci.c,v 1.23 1999/03/06 21:17:41 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -77,14 +77,12 @@ CreateSharedMemoryAndSemaphores(IPCKey key, int maxBackends)
 	 * Size of the primary shared-memory block is estimated via
 	 * moderately-accurate estimates for the big hogs, plus 100K for
 	 * the stuff that's too small to bother with estimating.
-	 * Then we add 10% for a safety margin.
 	 */
 	size = BufferShmemSize() + LockShmemSize(maxBackends);
 #ifdef STABLE_MEMORY_STORAGE
 	size += MMShmemSize();
 #endif
 	size += 100000;
-	size += size / 10;
 
 	if (DebugLvl > 1)
 	{
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index ed9a5b31313..2f822add66d 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lock.c,v 1.45 1999/02/22 06:16:52 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lock.c,v 1.46 1999/03/06 21:17:44 tgl Exp $
  *
  * NOTES
  *	  Outside modules can create a lock table and acquire/release
@@ -339,8 +339,8 @@ LockMethodTableInit(char *tabName,
 	 * to find the different locks.
 	 * ----------------------
 	 */
-	info.keysize = sizeof(LOCKTAG);
-	info.datasize = sizeof(LOCK);
+	info.keysize = SHMEM_LOCKTAB_KEYSIZE;
+	info.datasize = SHMEM_LOCKTAB_DATASIZE;
 	info.hash = tag_hash;
 	hash_flags = (HASH_ELEM | HASH_FUNCTION);
 
@@ -361,8 +361,8 @@ LockMethodTableInit(char *tabName,
 	 * the same lock, additional information must be saved (locks per tx).
 	 * -------------------------
 	 */
-	info.keysize = XID_TAGSIZE;
-	info.datasize = sizeof(XIDLookupEnt);
+	info.keysize = SHMEM_XIDTAB_KEYSIZE;
+	info.datasize = SHMEM_XIDTAB_DATASIZE;
 	info.hash = tag_hash;
 	hash_flags = (HASH_ELEM | HASH_FUNCTION);
 
@@ -1488,13 +1488,18 @@ LockShmemSize(int maxBackends)
 
 	/* lockHash table */
 	size += hash_estimate_size(NLOCKENTS(maxBackends),
-							   sizeof(LOCKTAG),
-							   sizeof(LOCK));
+							   SHMEM_LOCKTAB_KEYSIZE,
+							   SHMEM_LOCKTAB_DATASIZE);
 
 	/* xidHash table */
 	size += hash_estimate_size(maxBackends,
-							   XID_TAGSIZE,
-							   sizeof(XIDLookupEnt));
+							   SHMEM_XIDTAB_KEYSIZE,
+							   SHMEM_XIDTAB_DATASIZE);
+
+	/* Since the lockHash entry count above is only an estimate,
+	 * add 10% safety margin.
+	 */
+	size += size / 10;
 
 	return size;
 }
diff --git a/src/backend/storage/smgr/mm.c b/src/backend/storage/smgr/mm.c
index 603ee590638..2d5c1cdc4d8 100644
--- a/src/backend/storage/smgr/mm.c
+++ b/src/backend/storage/smgr/mm.c
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/storage/smgr/Attic/mm.c,v 1.14 1999/02/22 06:16:57 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/storage/smgr/Attic/mm.c,v 1.15 1999/03/06 21:17:50 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -110,7 +110,7 @@ mminit()
 	}
 
 	info.keysize = sizeof(MMCacheTag);
-	info.datasize = sizeof(int);
+	info.datasize = sizeof(MMHashEntry) - sizeof(MMCacheTag);
 	info.hash = tag_hash;
 
 	MMCacheHT = (HTAB *) ShmemInitHash("Main memory store HT",
@@ -124,7 +124,7 @@ mminit()
 	}
 
 	info.keysize = sizeof(MMRelTag);
-	info.datasize = sizeof(int);
+	info.datasize = sizeof(MMRelHashEntry) - sizeof(MMRelTag);
 	info.hash = tag_hash;
 
 	MMRelCacheHT = (HTAB *) ShmemInitHash("Main memory rel HT",
diff --git a/src/backend/utils/hash/dynahash.c b/src/backend/utils/hash/dynahash.c
index dcf4e4cce55..f9d87120535 100644
--- a/src/backend/utils/hash/dynahash.c
+++ b/src/backend/utils/hash/dynahash.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/hash/dynahash.c,v 1.19 1999/02/22 06:16:47 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/hash/dynahash.c,v 1.20 1999/03/06 21:17:56 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -373,18 +373,23 @@ hash_estimate_size(long num_entries, long keysize, long datasize)
 	long	size = 0;
 	long	nBuckets,
 			nSegments,
+			nDirEntries,
 			nRecordAllocs,
 			recordSize;
 
 	/* estimate number of buckets wanted */
 	nBuckets = 1L << my_log2((num_entries - 1) / DEF_FFACTOR + 1);
 	/* # of segments needed for nBuckets */
-	nSegments = (nBuckets - 1) / DEF_SEGSIZE + 1;
+	nSegments = 1L << my_log2((nBuckets - 1) / DEF_SEGSIZE + 1);
+	/* directory entries */
+	nDirEntries = DEF_DIRSIZE;
+	while (nDirEntries < nSegments)
+		nDirEntries <<= 1;		/* dir_alloc doubles dsize at each call */
 
 	/* fixed control info */
 	size += MAXALIGN(sizeof(HHDR));	/* but not HTAB, per above */
-	/* directory, assumed to be of size DEF_DIRSIZE */
-	size += MAXALIGN(DEF_DIRSIZE * sizeof(SEG_OFFSET));
+	/* directory */
+	size += MAXALIGN(nDirEntries * sizeof(SEG_OFFSET));
 	/* segments */
 	size += nSegments * MAXALIGN(DEF_SEGSIZE * sizeof(BUCKET_INDEX));
 	/* records --- allocated in groups of BUCKET_ALLOC_INCR */
@@ -408,9 +413,6 @@ hash_estimate_size(long num_entries, long keysize, long datasize)
 void
 hash_destroy(HTAB *hashp)
 {
-	/* cannot destroy a shared memory hash table */
-	Assert(!hashp->segbase);
-
 	if (hashp != NULL)
 	{
 		SEG_OFFSET	segNum;
@@ -422,6 +424,13 @@ hash_destroy(HTAB *hashp)
 					q;
 		ELEMENT    *curr;
 
+		/* cannot destroy a shared memory hash table */
+		Assert(!hashp->segbase);
+		/* allocation method must be one we know how to free, too */
+		Assert(hashp->alloc == (dhalloc_ptr) MEM_ALLOC);
+
+		hash_stats("destroy", hashp);
+
 		for (segNum = 0; nsegs > 0; nsegs--, segNum++)
 		{
 
@@ -435,11 +444,10 @@ hash_destroy(HTAB *hashp)
 					MEM_FREE((char *) curr);
 				}
 			}
-			free((char *) segp);
+			MEM_FREE((char *) segp);
 		}
 		MEM_FREE((char *) hashp->dir);
 		MEM_FREE((char *) hashp->hctl);
-		hash_stats("destroy", hashp);
 		MEM_FREE((char *) hashp);
 	}
 }
diff --git a/src/include/storage/lock.h b/src/include/storage/lock.h
index ce1f30133f3..da77f1d523c 100644
--- a/src/include/storage/lock.h
+++ b/src/include/storage/lock.h
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: lock.h,v 1.23 1999/02/21 01:41:47 tgl Exp $
+ * $Id: lock.h,v 1.24 1999/03/06 21:17:43 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -57,8 +57,6 @@ typedef int LOCKMETHOD;
 #define USER_LOCKMETHOD		2
 #define MIN_LOCKMETHOD		DEFAULT_LOCKMETHOD
 
-/*typedef struct LOCK LOCK; */
-
 
 typedef struct LTAG
 {
@@ -174,6 +172,9 @@ typedef struct XIDLookupEnt
 	SHM_QUEUE	queue;
 } XIDLookupEnt;
 
+#define SHMEM_XIDTAB_KEYSIZE  sizeof(XIDTAG)
+#define SHMEM_XIDTAB_DATASIZE (sizeof(XIDLookupEnt) - SHMEM_XIDTAB_KEYSIZE)
+
 #define XID_TAGSIZE (sizeof(XIDTAG))
 #define XIDENT_LOCKMETHOD(xident) (XIDTAG_LOCKMETHOD((xident).tag))
 
@@ -210,6 +211,9 @@ typedef struct LOCK
 	int			nActive;
 } LOCK;
 
+#define SHMEM_LOCKTAB_KEYSIZE  sizeof(LOCKTAG)
+#define SHMEM_LOCKTAB_DATASIZE (sizeof(LOCK) - SHMEM_LOCKTAB_KEYSIZE)
+
 #define LOCK_LOCKMETHOD(lock) (LOCKTAG_LOCKMETHOD((lock).tag))
 
 #define LockGetLock_nHolders(l) l->nHolders
-- 
GitLab