v16-0006-Preparatory-refactoring-to-simplify-templating.patch

text/x-patch

Filename: v16-0006-Preparatory-refactoring-to-simplify-templating.patch
Type: text/x-patch
Part: 11
Message: Re: [PoC] Improve dead tuple storage for lazy vacuum

Patch

Format: format-patch
Series: patch v16-0006
Subject: Preparatory refactoring to simplify templating
File+
src/backend/lib/radixtree.c 42 45
From 4573327ba7fa1179389af4383c04053251a8bf73 Mon Sep 17 00:00:00 2001
From: John Naylor <john.naylor@postgresql.org>
Date: Sun, 11 Dec 2022 16:38:08 +0700
Subject: [PATCH v16 06/12] Preparatory refactoring to simplify templating

*Remove gotos and shorten const lookups in node_insert_inner()
*Turn condition into an assert
*Don't cast to base -- use membership
---
 src/backend/lib/radixtree.c | 87 ++++++++++++++++++-------------------
 1 file changed, 42 insertions(+), 45 deletions(-)

diff --git a/src/backend/lib/radixtree.c b/src/backend/lib/radixtree.c
index abd0450727..7c993e096b 100644
--- a/src/backend/lib/radixtree.c
+++ b/src/backend/lib/radixtree.c
@@ -1294,7 +1294,7 @@ rt_node_insert_inner(radix_tree *tree, rt_node *parent, rt_node *node, uint64 ke
 				rt_node_inner_4 *n4 = (rt_node_inner_4 *) node;
 				int			idx;
 
-				idx = node_4_search_eq((rt_node_base_4 *) n4, chunk);
+				idx = node_4_search_eq(&n4->base, chunk);
 				if (idx != -1)
 				{
 					/* found the existing chunk */
@@ -1321,7 +1321,7 @@ rt_node_insert_inner(radix_tree *tree, rt_node *parent, rt_node *node, uint64 ke
 				}
 				else
 				{
-					int			insertpos = node_4_get_insertpos((rt_node_base_4 *) n4, chunk);
+					int			insertpos = node_4_get_insertpos(&n4->base, chunk);
 					uint16		count = n4->base.n.count;
 
 					/* shift chunks and children */
@@ -1337,10 +1337,12 @@ rt_node_insert_inner(radix_tree *tree, rt_node *parent, rt_node *node, uint64 ke
 			/* FALLTHROUGH */
 		case RT_NODE_KIND_32:
 			{
+				const rt_size_class_elem minclass = rt_size_class_info[RT_CLASS_32_PARTIAL];
+				const rt_size_class_elem maxclass = rt_size_class_info[RT_CLASS_32_FULL];
 				rt_node_inner_32 *n32 = (rt_node_inner_32 *) node;
 				int			idx;
 
-				idx = node_32_search_eq((rt_node_base_32 *) n32, chunk);
+				idx = node_32_search_eq(&n32->base, chunk);
 				if (idx != -1)
 				{
 					/* found the existing chunk */
@@ -1349,58 +1351,53 @@ rt_node_insert_inner(radix_tree *tree, rt_node *parent, rt_node *node, uint64 ke
 					break;
 				}
 
-				if (unlikely(!VAR_NODE_HAS_FREE_SLOT(n32)))
+				if (unlikely(!VAR_NODE_HAS_FREE_SLOT(n32)) &&
+					n32->base.n.count == minclass.fanout)
 				{
-					Assert(parent != NULL);
+					/* use the same node kind, but expand to the next size class */
+					rt_node_inner_32 *new32;
 
-					if (n32->base.n.count == rt_size_class_info[RT_CLASS_32_PARTIAL].fanout)
-					{
-						/* use the same node kind, but expand to the next size class */
-						const Size size = rt_size_class_info[RT_CLASS_32_PARTIAL].inner_size;
-						const int fanout = rt_size_class_info[RT_CLASS_32_FULL].fanout;
-						rt_node_inner_32 *new32;
+					new32 = (rt_node_inner_32 *) rt_alloc_node(tree, RT_CLASS_32_FULL, true);
+					memcpy(new32, n32, minclass.inner_size);
+					new32->base.n.fanout = maxclass.fanout;
 
-						new32 = (rt_node_inner_32 *) rt_alloc_node(tree, RT_CLASS_32_FULL, true);
-						memcpy(new32, n32, size);
-						new32->base.n.fanout = fanout;
-
-						rt_replace_node(tree, parent, (rt_node *) n32, (rt_node *) new32, key);
+					Assert(parent != NULL);
+					rt_replace_node(tree, parent, (rt_node *) n32, (rt_node *) new32, key);
 
-						/* must update both pointers here */
-						node = (rt_node *) new32;
-						n32 = new32;
+					/* must update both pointers here */
+					node = (rt_node *) new32;
+					n32 = new32;
+				}
 
-						goto retry_insert_inner_32;
-					}
-					else
-					{
-						rt_node_inner_125 *new125;
+				if (unlikely(!VAR_NODE_HAS_FREE_SLOT(n32)))
+				{
+					rt_node_inner_125 *new125;
 
-						/* grow node from 32 to 125 */
-						new125 = (rt_node_inner_125 *) rt_grow_node_kind(tree, (rt_node *) n32,
-																		 RT_NODE_KIND_125);
-						for (int i = 0; i < n32->base.n.count; i++)
-							node_inner_125_insert(new125, n32->base.chunks[i], n32->children[i]);
+					/* grow node from 32 to 125 */
+					new125 = (rt_node_inner_125 *) rt_grow_node_kind(tree, (rt_node *) n32,
+																	 RT_NODE_KIND_125);
+					for (int i = 0; i < n32->base.n.count; i++)
+						node_inner_125_insert(new125, n32->base.chunks[i], n32->children[i]);
 
-						rt_replace_node(tree, parent, (rt_node *) n32, (rt_node *) new125, key);
-						node = (rt_node *) new125;
-					}
+					Assert(parent != NULL);
+					rt_replace_node(tree, parent, (rt_node *) n32, (rt_node *) new125, key);
+					node = (rt_node *) new125;
 				}
 				else
 				{
-retry_insert_inner_32:
-					{
-						int	insertpos = node_32_get_insertpos((rt_node_base_32 *) n32, chunk);
-						int16 count = n32->base.n.count;
+					int	insertpos = node_32_get_insertpos(&n32->base, chunk);
+					int16 count = n32->base.n.count;
 
-						if (count != 0 && insertpos < count)
-							chunk_children_array_shift(n32->base.chunks, n32->children,
-													   count, insertpos);
-
-						n32->base.chunks[insertpos] = chunk;
-						n32->children[insertpos] = child;
-						break;
+					if (insertpos < count)
+					{
+						Assert(count > 0);
+						chunk_children_array_shift(n32->base.chunks, n32->children,
+												   count, insertpos);
 					}
+
+					n32->base.chunks[insertpos] = chunk;
+					n32->children[insertpos] = child;
+					break;
 				}
 			}
 			/* FALLTHROUGH */
@@ -1409,7 +1406,7 @@ retry_insert_inner_32:
 				rt_node_inner_125 *n125 = (rt_node_inner_125 *) node;
 				int			cnt = 0;
 
-				if (node_125_is_chunk_used((rt_node_base_125 *) n125, chunk))
+				if (node_125_is_chunk_used(&n125->base, chunk))
 				{
 					/* found the existing chunk */
 					chunk_exists = true;
@@ -1427,7 +1424,7 @@ retry_insert_inner_32:
 																	 RT_NODE_KIND_256);
 					for (int i = 0; i < RT_NODE_MAX_SLOTS && cnt < n125->base.n.count; i++)
 					{
-						if (!node_125_is_chunk_used((rt_node_base_125 *) n125, i))
+						if (!node_125_is_chunk_used(&n125->base, i))
 							continue;
 
 						node_inner_256_set(new256, i, node_inner_125_get_child(n125, i));
-- 
2.38.1