From bd77343110fabd259a1cc27d0c106b84d3a1cceb Mon Sep 17 00:00:00 2001
From: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
Date: Wed, 18 Sep 2024 16:41:36 +0530
Subject: [PATCH 5/6] Use simplehash instead of dynamic hash

---
 src/backend/optimizer/util/restrictinfo.c | 57 ++++++++++-------------
 src/include/nodes/pathnodes.h             |  2 +-
 2 files changed, 26 insertions(+), 33 deletions(-)

diff --git a/src/backend/optimizer/util/restrictinfo.c b/src/backend/optimizer/util/restrictinfo.c
index bed27ccf226..68ed44d7b48 100644
--- a/src/backend/optimizer/util/restrictinfo.c
+++ b/src/backend/optimizer/util/restrictinfo.c
@@ -715,7 +715,8 @@ typedef struct
 /* Hash table entry for RestrictInfo hash table. */
 typedef struct rinfo_tab_entry
 {
-	rinfo_tab_key key;			/* Key must be first. */
+	uint32		status;
+	rinfo_tab_key key;
 	RestrictInfo *rinfo;
 } rinfo_tab_entry;
 
@@ -724,13 +725,10 @@ typedef struct rinfo_tab_entry
  *		Computes hash of RestrictInfo hash table key.
  */
 static uint32
-rinfo_tab_key_hash(const void *key, Size size)
+rinfo_tab_key_hash(const rinfo_tab_key *rtabkey)
 {
-	rinfo_tab_key *rtabkey = (rinfo_tab_key *) key;
 	uint32		result;
 
-	Assert(sizeof(rinfo_tab_key) == size);
-
 	/* Combine hashes of all components of the key. */
 	result = hash_bytes_uint32(rtabkey->rinfo_serial);
 	result = hash_combine(result, bms_hash_value(rtabkey->required_relids));
@@ -743,14 +741,10 @@ rinfo_tab_key_hash(const void *key, Size size)
  *		Match function for RestrictInfo hash table.
  */
 static int
-rinfo_tab_key_match(const void *key1, const void *key2, Size size)
+rinfo_tab_key_match(const rinfo_tab_key *rtabkey1, const rinfo_tab_key *rtabkey2)
 {
-	rinfo_tab_key *rtabkey1 = (rinfo_tab_key *) key1;
-	rinfo_tab_key *rtabkey2 = (rinfo_tab_key *) key2;
 	int			result;
 
-	Assert(sizeof(rinfo_tab_key) == size);
-
 	result = rtabkey1->rinfo_serial - rtabkey2->rinfo_serial;
 	if (result)
 		return result;
@@ -758,29 +752,29 @@ rinfo_tab_key_match(const void *key1, const void *key2, Size size)
 	return !bms_equal(rtabkey1->required_relids, rtabkey2->required_relids);
 }
 
+/*
+ * Define parameters for restrictinfo hash table code generation.
+ */
+#define SH_PREFIX rinfohash
+#define SH_ELEMENT_TYPE rinfo_tab_entry
+#define SH_KEY_TYPE rinfo_tab_key
+#define SH_KEY key
+#define SH_HASH_KEY(tb, key) rinfo_tab_key_hash(&key)
+#define SH_EQUAL(tb, a, b) rinfo_tab_key_match(&a, &b) == 0
+#define SH_SCOPE static inline
+#define SH_DECLARE
+#define SH_DEFINE
+#include "lib/simplehash.h"
 /*
  * get_child_rinfo_hash
- *		Returns the child RestrictInfo hash table from PlannerInfo, creating it if
+ *		Returns the RestrictInfo hash table from PlannerInfo, creating it if
  *		necessary.
  */
-static HTAB *
+static rinfohash_hash *
 get_child_rinfo_hash(PlannerInfo *root)
 {
 	if (!root->child_rinfo_hash)
-	{
-		HASHCTL		hash_ctl = {0};
-
-		hash_ctl.keysize = sizeof(rinfo_tab_key);
-		hash_ctl.entrysize = sizeof(rinfo_tab_entry);
-		hash_ctl.hcxt = root->planner_cxt;
-		hash_ctl.hash = rinfo_tab_key_hash;
-		hash_ctl.match = rinfo_tab_key_match;
-
-		root->child_rinfo_hash = hash_create("restrictinfo hash table",
-											 1000,
-											 &hash_ctl,
-											 HASH_ELEM | HASH_CONTEXT | HASH_FUNCTION | HASH_COMPARE);
-	}
+		root->child_rinfo_hash = rinfohash_create(root->planner_cxt, 1000, NULL);
 
 	return root->child_rinfo_hash;
 }
@@ -792,14 +786,14 @@ get_child_rinfo_hash(PlannerInfo *root)
 void
 add_restrictinfo(PlannerInfo *root, RestrictInfo *rinfo)
 {
-	HTAB	   *rinfo_hash = get_child_rinfo_hash(root);
+	rinfohash_hash *rinfo_tab = get_child_rinfo_hash(root);
 	rinfo_tab_key key;
 	rinfo_tab_entry *rinfo_entry;
 	bool		found;
 
 	key.rinfo_serial = rinfo->rinfo_serial;
 	key.required_relids = rinfo->required_relids;
-	rinfo_entry = hash_search(rinfo_hash, &key, HASH_ENTER, &found);
+	rinfo_entry = rinfohash_insert(rinfo_tab, key, &found);
 
 	/*
 	 * If the given RestrictInfo is already present in the hash table,
@@ -823,15 +817,14 @@ add_restrictinfo(PlannerInfo *root, RestrictInfo *rinfo)
 RestrictInfo *
 find_restrictinfo(PlannerInfo *root, int rinfo_serial, Relids required_relids)
 {
-	HTAB	   *rinfo_hash = get_child_rinfo_hash(root);
+	rinfohash_hash *rinfo_tab = get_child_rinfo_hash(root);
 	rinfo_tab_entry *rinfo_entry;
 	rinfo_tab_key key;
 
 	key.rinfo_serial = rinfo_serial;
 	key.required_relids = required_relids;
-	rinfo_entry = hash_search(rinfo_hash, &key,
-							  HASH_FIND,
-							  NULL);
+	rinfo_entry = rinfohash_lookup(rinfo_tab, key);
+
 	return (rinfo_entry ? rinfo_entry->rinfo : NULL);
 }
 
diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h
index 58e0519bdc6..3a4ae79ba4e 100644
--- a/src/include/nodes/pathnodes.h
+++ b/src/include/nodes/pathnodes.h
@@ -320,7 +320,7 @@ struct PlannerInfo
 	int			last_rinfo_serial;
 
 	/* Hash table to store and retrieve child RestrictInfos. */
-	struct HTAB *child_rinfo_hash pg_node_attr(read_write_ignore);
+	struct rinfohash_hash *child_rinfo_hash pg_node_attr(read_write_ignore);
 
 	/* list of "canonical" PathKeys */
 	List	   *canon_pathkeys;
-- 
2.34.1

