v17-0008-Invent-specific-pointer-macros.patch

text/x-patch

Filename: v17-0008-Invent-specific-pointer-macros.patch
Type: text/x-patch
Part: 2
Message: Re: [PoC] Improve dead tuple storage for lazy vacuum

Patch

Format: format-patch
Series: patch v17-0008
Subject: Invent specific pointer macros
File+
src/include/lib/radixtree.h 88 77
src/include/lib/radixtree_search_impl.h 1 1
From 46ac0171f5a3bd80dfea8ad4061b1567650b8061 Mon Sep 17 00:00:00 2001
From: John Naylor <john.naylor@postgresql.org>
Date: Fri, 6 Jan 2023 14:20:51 +0700
Subject: [PATCH v17 8/9] Invent specific pointer macros

RT_PTR_LOCAL - a normal pointer to local memory
RT_PTR_ALLOC - the result of allocation, possibly a DSA pointer

RT_EXTEND and RT_SET_EXTEND have some code changes to show
how these are meant to be treated differently, but most punted
until later.
---
 src/include/lib/radixtree.h             | 165 +++++++++++++-----------
 src/include/lib/radixtree_search_impl.h |   2 +-
 2 files changed, 89 insertions(+), 78 deletions(-)

diff --git a/src/include/lib/radixtree.h b/src/include/lib/radixtree.h
index e4350730b7..b3d84da033 100644
--- a/src/include/lib/radixtree.h
+++ b/src/include/lib/radixtree.h
@@ -301,8 +301,12 @@ typedef struct RT_NODE
 	uint8		kind;
 } RT_NODE;
 
-#define NODE_IS_LEAF(n)			(((RT_NODE *) (n))->shift == 0)
-#define NODE_IS_EMPTY(n)		(((RT_NODE *) (n))->count == 0)
+#define RT_PTR_LOCAL RT_NODE *
+
+#define RT_PTR_ALLOC RT_PTR_LOCAL
+
+#define NODE_IS_LEAF(n)			(((RT_PTR_LOCAL) (n))->shift == 0)
+#define NODE_IS_EMPTY(n)		(((RT_PTR_LOCAL) (n))->count == 0)
 #define VAR_NODE_HAS_FREE_SLOT(node) \
 	((node)->base.n.count < (node)->base.n.fanout)
 #define FIXED_NODE_HAS_FREE_SLOT(node, class) \
@@ -366,7 +370,7 @@ typedef struct RT_NODE_INNER_4
 	RT_NODE_BASE_4 base;
 
 	/* number of children depends on size class */
-	RT_NODE    *children[FLEXIBLE_ARRAY_MEMBER];
+	RT_PTR_ALLOC children[FLEXIBLE_ARRAY_MEMBER];
 } RT_NODE_INNER_4;
 
 typedef struct RT_NODE_LEAF_4
@@ -382,7 +386,7 @@ typedef struct RT_NODE_INNER_32
 	RT_NODE_BASE_32 base;
 
 	/* number of children depends on size class */
-	RT_NODE    *children[FLEXIBLE_ARRAY_MEMBER];
+	RT_PTR_ALLOC children[FLEXIBLE_ARRAY_MEMBER];
 } RT_NODE_INNER_32;
 
 typedef struct RT_NODE_LEAF_32
@@ -398,7 +402,7 @@ typedef struct RT_NODE_INNER_125
 	RT_NODE_BASE_125 base;
 
 	/* number of children depends on size class */
-	RT_NODE    *children[FLEXIBLE_ARRAY_MEMBER];
+	RT_PTR_ALLOC children[FLEXIBLE_ARRAY_MEMBER];
 } RT_NODE_INNER_125;
 
 typedef struct RT_NODE_LEAF_125
@@ -418,7 +422,7 @@ typedef struct RT_NODE_INNER_256
 	RT_NODE_BASE_256 base;
 
 	/* Slots for 256 children */
-	RT_NODE    *children[RT_NODE_MAX_SLOTS];
+	RT_PTR_ALLOC children[RT_NODE_MAX_SLOTS];
 } RT_NODE_INNER_256;
 
 typedef struct RT_NODE_LEAF_256
@@ -458,33 +462,33 @@ static const RT_SIZE_CLASS_ELEM RT_SIZE_CLASS_INFO[] = {
 	[RT_CLASS_4_FULL] = {
 		.name = "radix tree node 4",
 		.fanout = 4,
-		.inner_size = sizeof(RT_NODE_INNER_4) + 4 * sizeof(RT_NODE *),
+		.inner_size = sizeof(RT_NODE_INNER_4) + 4 * sizeof(RT_PTR_ALLOC),
 		.leaf_size = sizeof(RT_NODE_LEAF_4) + 4 * sizeof(uint64),
-		.inner_blocksize = NODE_SLAB_BLOCK_SIZE(sizeof(RT_NODE_INNER_4) + 4 * sizeof(RT_NODE *)),
+		.inner_blocksize = NODE_SLAB_BLOCK_SIZE(sizeof(RT_NODE_INNER_4) + 4 * sizeof(RT_PTR_ALLOC)),
 		.leaf_blocksize = NODE_SLAB_BLOCK_SIZE(sizeof(RT_NODE_LEAF_4) + 4 * sizeof(uint64)),
 	},
 	[RT_CLASS_32_PARTIAL] = {
 		.name = "radix tree node 15",
 		.fanout = 15,
-		.inner_size = sizeof(RT_NODE_INNER_32) + 15 * sizeof(RT_NODE *),
+		.inner_size = sizeof(RT_NODE_INNER_32) + 15 * sizeof(RT_PTR_ALLOC),
 		.leaf_size = sizeof(RT_NODE_LEAF_32) + 15 * sizeof(uint64),
-		.inner_blocksize = NODE_SLAB_BLOCK_SIZE(sizeof(RT_NODE_INNER_32) + 15 * sizeof(RT_NODE *)),
+		.inner_blocksize = NODE_SLAB_BLOCK_SIZE(sizeof(RT_NODE_INNER_32) + 15 * sizeof(RT_PTR_ALLOC)),
 		.leaf_blocksize = NODE_SLAB_BLOCK_SIZE(sizeof(RT_NODE_LEAF_32) + 15 * sizeof(uint64)),
 	},
 	[RT_CLASS_32_FULL] = {
 		.name = "radix tree node 32",
 		.fanout = 32,
-		.inner_size = sizeof(RT_NODE_INNER_32) + 32 * sizeof(RT_NODE *),
+		.inner_size = sizeof(RT_NODE_INNER_32) + 32 * sizeof(RT_PTR_ALLOC),
 		.leaf_size = sizeof(RT_NODE_LEAF_32) + 32 * sizeof(uint64),
-		.inner_blocksize = NODE_SLAB_BLOCK_SIZE(sizeof(RT_NODE_INNER_32) + 32 * sizeof(RT_NODE *)),
+		.inner_blocksize = NODE_SLAB_BLOCK_SIZE(sizeof(RT_NODE_INNER_32) + 32 * sizeof(RT_PTR_ALLOC)),
 		.leaf_blocksize = NODE_SLAB_BLOCK_SIZE(sizeof(RT_NODE_LEAF_32) + 32 * sizeof(uint64)),
 	},
 	[RT_CLASS_125_FULL] = {
 		.name = "radix tree node 125",
 		.fanout = 125,
-		.inner_size = sizeof(RT_NODE_INNER_125) + 125 * sizeof(RT_NODE *),
+		.inner_size = sizeof(RT_NODE_INNER_125) + 125 * sizeof(RT_PTR_ALLOC),
 		.leaf_size = sizeof(RT_NODE_LEAF_125) + 125 * sizeof(uint64),
-		.inner_blocksize = NODE_SLAB_BLOCK_SIZE(sizeof(RT_NODE_INNER_125) + 125 * sizeof(RT_NODE *)),
+		.inner_blocksize = NODE_SLAB_BLOCK_SIZE(sizeof(RT_NODE_INNER_125) + 125 * sizeof(RT_PTR_ALLOC)),
 		.leaf_blocksize = NODE_SLAB_BLOCK_SIZE(sizeof(RT_NODE_LEAF_125) + 125 * sizeof(uint64)),
 	},
 	[RT_CLASS_256] = {
@@ -512,7 +516,7 @@ typedef struct RT_RADIX_TREE
 {
 	MemoryContext context;
 
-	RT_NODE    *root;
+	RT_PTR_ALLOC root;
 	uint64		max_val;
 	uint64		num_keys;
 
@@ -541,7 +545,7 @@ typedef struct RT_RADIX_TREE
  */
 typedef struct RT_NODE_ITER
 {
-	RT_NODE    *node;			/* current node being iterated */
+	RT_PTR_LOCAL node;			/* current node being iterated */
 	int			current_idx;	/* current position. -1 for initial value */
 } RT_NODE_ITER;
 
@@ -558,13 +562,13 @@ typedef struct RT_ITER
 } RT_ITER;
 
 
-static bool RT_NODE_INSERT_INNER(RT_RADIX_TREE *tree, RT_NODE *parent, RT_NODE *node,
-								 uint64 key, RT_NODE *child);
-static bool RT_NODE_INSERT_LEAF(RT_RADIX_TREE *tree, RT_NODE *parent, RT_NODE *node,
+static bool RT_NODE_INSERT_INNER(RT_RADIX_TREE *tree, RT_PTR_LOCAL parent, RT_PTR_LOCAL node,
+								 uint64 key, RT_PTR_LOCAL child);
+static bool RT_NODE_INSERT_LEAF(RT_RADIX_TREE *tree, RT_PTR_LOCAL parent, RT_PTR_LOCAL node,
 								uint64 key, uint64 value);
 
 /* verification (available only with assertion) */
-static void RT_VERIFY_NODE(RT_NODE *node);
+static void RT_VERIFY_NODE(RT_PTR_LOCAL node);
 
 /*
  * Return index of the first element in 'base' that equals 'key'. Return -1
@@ -713,10 +717,10 @@ RT_NODE_32_GET_INSERTPOS(RT_NODE_BASE_32 *node, uint8 chunk)
 
 /* Shift the elements right at 'idx' by one */
 static inline void
-RT_CHUNK_CHILDREN_ARRAY_SHIFT(uint8 *chunks, RT_NODE **children, int count, int idx)
+RT_CHUNK_CHILDREN_ARRAY_SHIFT(uint8 *chunks, RT_PTR_ALLOC *children, int count, int idx)
 {
 	memmove(&(chunks[idx + 1]), &(chunks[idx]), sizeof(uint8) * (count - idx));
-	memmove(&(children[idx + 1]), &(children[idx]), sizeof(RT_NODE *) * (count - idx));
+	memmove(&(children[idx + 1]), &(children[idx]), sizeof(RT_PTR_ALLOC) * (count - idx));
 }
 
 static inline void
@@ -728,10 +732,10 @@ RT_CHUNK_VALUES_ARRAY_SHIFT(uint8 *chunks, uint64 *values, int count, int idx)
 
 /* Delete the element at 'idx' */
 static inline void
-RT_CHUNK_CHILDREN_ARRAY_DELETE(uint8 *chunks, RT_NODE **children, int count, int idx)
+RT_CHUNK_CHILDREN_ARRAY_DELETE(uint8 *chunks, RT_PTR_ALLOC *children, int count, int idx)
 {
 	memmove(&(chunks[idx]), &(chunks[idx + 1]), sizeof(uint8) * (count - idx - 1));
-	memmove(&(children[idx]), &(children[idx + 1]), sizeof(RT_NODE *) * (count - idx - 1));
+	memmove(&(children[idx]), &(children[idx + 1]), sizeof(RT_PTR_ALLOC) * (count - idx - 1));
 }
 
 static inline void
@@ -743,12 +747,12 @@ RT_CHUNK_VALUES_ARRAY_DELETE(uint8 *chunks, uint64 *values, int count, int idx)
 
 /* Copy both chunks and children/values arrays */
 static inline void
-RT_CHUNK_CHILDREN_ARRAY_COPY(uint8 *src_chunks, RT_NODE **src_children,
-						  uint8 *dst_chunks, RT_NODE **dst_children)
+RT_CHUNK_CHILDREN_ARRAY_COPY(uint8 *src_chunks, RT_PTR_ALLOC *src_children,
+						  uint8 *dst_chunks, RT_PTR_ALLOC *dst_children)
 {
 	const int fanout = RT_SIZE_CLASS_INFO[RT_CLASS_4_FULL].fanout;
 	const Size chunk_size = sizeof(uint8) * fanout;
-	const Size children_size = sizeof(RT_NODE *) * fanout;
+	const Size children_size = sizeof(RT_PTR_ALLOC) * fanout;
 
 	memcpy(dst_chunks, src_chunks, chunk_size);
 	memcpy(dst_children, src_children, children_size);
@@ -775,7 +779,7 @@ RT_NODE_125_IS_CHUNK_USED(RT_NODE_BASE_125 *node, uint8 chunk)
 	return node->slot_idxs[chunk] != RT_NODE_125_INVALID_IDX;
 }
 
-static inline RT_NODE *
+static inline RT_PTR_ALLOC
 RT_NODE_INNER_125_GET_CHILD(RT_NODE_INNER_125 *node, uint8 chunk)
 {
 	Assert(!NODE_IS_LEAF(node));
@@ -810,7 +814,7 @@ RT_NODE_LEAF_256_IS_CHUNK_USED(RT_NODE_LEAF_256 *node, uint8 chunk)
 	return (node->isset[idx] & ((bitmapword) 1 << bitnum)) != 0;
 }
 
-static inline RT_NODE *
+static inline RT_PTR_ALLOC
 RT_NODE_INNER_256_GET_CHILD(RT_NODE_INNER_256 *node, uint8 chunk)
 {
 	Assert(!NODE_IS_LEAF(node));
@@ -828,7 +832,7 @@ RT_NODE_LEAF_256_GET_VALUE(RT_NODE_LEAF_256 *node, uint8 chunk)
 
 /* Set the child in the node-256 */
 static inline void
-RT_NODE_INNER_256_SET(RT_NODE_INNER_256 *node, uint8 chunk, RT_NODE *child)
+RT_NODE_INNER_256_SET(RT_NODE_INNER_256 *node, uint8 chunk, RT_PTR_ALLOC child)
 {
 	Assert(!NODE_IS_LEAF(node));
 	node->children[chunk] = child;
@@ -890,16 +894,16 @@ RT_SHIFT_GET_MAX_VAL(int shift)
 /*
  * Allocate a new node with the given node kind.
  */
-static RT_NODE *
+static RT_PTR_ALLOC
 RT_ALLOC_NODE(RT_RADIX_TREE *tree, RT_SIZE_CLASS size_class, bool inner)
 {
-	RT_NODE    *newnode;
+	RT_PTR_ALLOC newnode;
 
 	if (inner)
-		newnode = (RT_NODE *) MemoryContextAlloc(tree->inner_slabs[size_class],
+		newnode = (RT_PTR_ALLOC) MemoryContextAlloc(tree->inner_slabs[size_class],
 												 RT_SIZE_CLASS_INFO[size_class].inner_size);
 	else
-		newnode = (RT_NODE *) MemoryContextAlloc(tree->leaf_slabs[size_class],
+		newnode = (RT_PTR_ALLOC) MemoryContextAlloc(tree->leaf_slabs[size_class],
 												 RT_SIZE_CLASS_INFO[size_class].leaf_size);
 
 #ifdef RT_DEBUG
@@ -912,7 +916,7 @@ RT_ALLOC_NODE(RT_RADIX_TREE *tree, RT_SIZE_CLASS size_class, bool inner)
 
 /* Initialize the node contents */
 static inline void
-RT_INIT_NODE(RT_NODE *node, uint8 kind, RT_SIZE_CLASS size_class, bool inner)
+RT_INIT_NODE(RT_PTR_LOCAL node, uint8 kind, RT_SIZE_CLASS size_class, bool inner)
 {
 	if (inner)
 		MemSet(node, 0, RT_SIZE_CLASS_INFO[size_class].inner_size);
@@ -947,7 +951,7 @@ RT_NEW_ROOT(RT_RADIX_TREE *tree, uint64 key)
 {
 	int			shift = RT_KEY_GET_SHIFT(key);
 	bool		inner = shift > 0;
-	RT_NODE    *newnode;
+	RT_PTR_ALLOC newnode;
 
 	newnode = RT_ALLOC_NODE(tree, RT_CLASS_4_FULL, inner);
 	RT_INIT_NODE(newnode, RT_NODE_KIND_4, RT_CLASS_4_FULL, inner);
@@ -957,7 +961,7 @@ RT_NEW_ROOT(RT_RADIX_TREE *tree, uint64 key)
 }
 
 static inline void
-RT_COPY_NODE(RT_NODE *newnode, RT_NODE *oldnode)
+RT_COPY_NODE(RT_PTR_LOCAL newnode, RT_PTR_LOCAL oldnode)
 {
 	newnode->shift = oldnode->shift;
 	newnode->chunk = oldnode->chunk;
@@ -969,9 +973,9 @@ RT_COPY_NODE(RT_NODE *newnode, RT_NODE *oldnode)
  * count of 'node'.
  */
 static RT_NODE*
-RT_GROW_NODE_KIND(RT_RADIX_TREE *tree, RT_NODE *node, uint8 new_kind)
+RT_GROW_NODE_KIND(RT_RADIX_TREE *tree, RT_PTR_LOCAL node, uint8 new_kind)
 {
-	RT_NODE	*newnode;
+	RT_PTR_ALLOC newnode;
 	bool inner = !NODE_IS_LEAF(node);
 
 	newnode = RT_ALLOC_NODE(tree, RT_KIND_MIN_SIZE_CLASS[new_kind], inner);
@@ -983,7 +987,7 @@ RT_GROW_NODE_KIND(RT_RADIX_TREE *tree, RT_NODE *node, uint8 new_kind)
 
 /* Free the given node */
 static void
-RT_FREE_NODE(RT_RADIX_TREE *tree, RT_NODE *node)
+RT_FREE_NODE(RT_RADIX_TREE *tree, RT_PTR_ALLOC node)
 {
 	/* If we're deleting the root node, make the tree empty */
 	if (tree->root == node)
@@ -1019,8 +1023,8 @@ RT_FREE_NODE(RT_RADIX_TREE *tree, RT_NODE *node)
  * Replace old_child with new_child, and free the old one.
  */
 static void
-RT_REPLACE_NODE(RT_RADIX_TREE *tree, RT_NODE *parent, RT_NODE *old_child,
-				RT_NODE *new_child, uint64 key)
+RT_REPLACE_NODE(RT_RADIX_TREE *tree, RT_PTR_LOCAL parent, RT_PTR_ALLOC old_child,
+				RT_PTR_ALLOC new_child, uint64 key)
 {
 	Assert(old_child->chunk == new_child->chunk);
 	Assert(old_child->shift == new_child->shift);
@@ -1056,17 +1060,22 @@ RT_EXTEND(RT_RADIX_TREE *tree, uint64 key)
 	/* Grow tree from 'shift' to 'target_shift' */
 	while (shift <= target_shift)
 	{
-		RT_NODE_INNER_4 *node;
+		RT_PTR_ALLOC	allocnode;
+		RT_PTR_LOCAL	node;
+		RT_NODE_INNER_4 *n4;
+
+		allocnode = RT_ALLOC_NODE(tree, RT_CLASS_4_FULL, true);
+		node = (RT_PTR_LOCAL) allocnode;
+		RT_INIT_NODE(node, RT_NODE_KIND_4, RT_CLASS_4_FULL, true);
+		node->shift = shift;
+		node->count = 1;
 
-		node = (RT_NODE_INNER_4 *) RT_ALLOC_NODE(tree, RT_CLASS_4_FULL, true);
-		RT_INIT_NODE((RT_NODE *) node, RT_NODE_KIND_4, RT_CLASS_4_FULL, true);
-		node->base.n.shift = shift;
-		node->base.n.count = 1;
-		node->base.chunks[0] = 0;
-		node->children[0] = tree->root;
+		n4 = (RT_NODE_INNER_4 *) node;
+		n4->base.chunks[0] = 0;
+		n4->children[0] = tree->root;
 
 		tree->root->chunk = 0;
-		tree->root = (RT_NODE *) node;
+		tree->root = node;
 
 		shift += RT_NODE_SPAN;
 	}
@@ -1079,18 +1088,20 @@ RT_EXTEND(RT_RADIX_TREE *tree, uint64 key)
  * Insert inner and leaf nodes from 'node' to bottom.
  */
 static inline void
-RT_SET_EXTEND(RT_RADIX_TREE *tree, uint64 key, uint64 value, RT_NODE *parent,
-			  RT_NODE *node)
+RT_SET_EXTEND(RT_RADIX_TREE *tree, uint64 key, uint64 value, RT_PTR_LOCAL parent,
+			  RT_PTR_LOCAL node)
 {
 	int			shift = node->shift;
 
 	while (shift >= RT_NODE_SPAN)
 	{
-		RT_NODE    *newchild;
+		RT_PTR_ALLOC allocchild;
+		RT_PTR_LOCAL newchild;
 		int			newshift = shift - RT_NODE_SPAN;
 		bool		inner = newshift > 0;
 
-		newchild = RT_ALLOC_NODE(tree, RT_CLASS_4_FULL, inner);
+		allocchild = RT_ALLOC_NODE(tree, RT_CLASS_4_FULL, inner);
+		newchild = (RT_PTR_LOCAL) allocchild;
 		RT_INIT_NODE(newchild, RT_NODE_KIND_4, RT_CLASS_4_FULL, inner);
 		newchild->shift = newshift;
 		newchild->chunk = RT_GET_KEY_CHUNK(key, node->shift);
@@ -1112,7 +1123,7 @@ RT_SET_EXTEND(RT_RADIX_TREE *tree, uint64 key, uint64 value, RT_NODE *parent,
  * pointer is set to child_p.
  */
 static inline bool
-RT_NODE_SEARCH_INNER(RT_NODE *node, uint64 key, RT_NODE **child_p)
+RT_NODE_SEARCH_INNER(RT_PTR_LOCAL node, uint64 key, RT_PTR_ALLOC *child_p)
 {
 #define RT_NODE_LEVEL_INNER
 #include "lib/radixtree_search_impl.h"
@@ -1126,7 +1137,7 @@ RT_NODE_SEARCH_INNER(RT_NODE *node, uint64 key, RT_NODE **child_p)
  * to the value is set to value_p.
  */
 static inline bool
-RT_NODE_SEARCH_LEAF(RT_NODE *node, uint64 key, uint64 *value_p)
+RT_NODE_SEARCH_LEAF(RT_PTR_LOCAL node, uint64 key, uint64 *value_p)
 {
 #define RT_NODE_LEVEL_LEAF
 #include "lib/radixtree_search_impl.h"
@@ -1139,7 +1150,7 @@ RT_NODE_SEARCH_LEAF(RT_NODE *node, uint64 key, uint64 *value_p)
  * Delete the node and return true if the key is found, otherwise return false.
  */
 static inline bool
-RT_NODE_DELETE_INNER(RT_NODE *node, uint64 key)
+RT_NODE_DELETE_INNER(RT_PTR_LOCAL node, uint64 key)
 {
 #define RT_NODE_LEVEL_INNER
 #include "lib/radixtree_delete_impl.h"
@@ -1152,7 +1163,7 @@ RT_NODE_DELETE_INNER(RT_NODE *node, uint64 key)
  * Delete the node and return true if the key is found, otherwise return false.
  */
 static inline bool
-RT_NODE_DELETE_LEAF(RT_NODE *node, uint64 key)
+RT_NODE_DELETE_LEAF(RT_PTR_LOCAL node, uint64 key)
 {
 #define RT_NODE_LEVEL_LEAF
 #include "lib/radixtree_delete_impl.h"
@@ -1161,8 +1172,8 @@ RT_NODE_DELETE_LEAF(RT_NODE *node, uint64 key)
 
 /* Insert the child to the inner node */
 static bool
-RT_NODE_INSERT_INNER(RT_RADIX_TREE *tree, RT_NODE *parent, RT_NODE *node, uint64 key,
-					 RT_NODE *child)
+RT_NODE_INSERT_INNER(RT_RADIX_TREE *tree, RT_PTR_LOCAL parent, RT_PTR_LOCAL node, uint64 key,
+					 RT_PTR_ALLOC child)
 {
 #define RT_NODE_LEVEL_INNER
 #include "lib/radixtree_insert_impl.h"
@@ -1171,7 +1182,7 @@ RT_NODE_INSERT_INNER(RT_RADIX_TREE *tree, RT_NODE *parent, RT_NODE *node, uint64
 
 /* Insert the value to the leaf node */
 static bool
-RT_NODE_INSERT_LEAF(RT_RADIX_TREE *tree, RT_NODE *parent, RT_NODE *node,
+RT_NODE_INSERT_LEAF(RT_RADIX_TREE *tree, RT_PTR_LOCAL parent, RT_PTR_LOCAL node,
 					uint64 key, uint64 value)
 {
 #define RT_NODE_LEVEL_LEAF
@@ -1241,8 +1252,8 @@ RT_SET(RT_RADIX_TREE *tree, uint64 key, uint64 value)
 {
 	int			shift;
 	bool		updated;
-	RT_NODE    *node;
-	RT_NODE    *parent;
+	RT_PTR_LOCAL node;
+	RT_PTR_LOCAL parent;
 
 	/* Empty tree, create the root */
 	if (!tree->root)
@@ -1260,7 +1271,7 @@ RT_SET(RT_RADIX_TREE *tree, uint64 key, uint64 value)
 	/* Descend the tree until a leaf node */
 	while (shift >= 0)
 	{
-		RT_NODE    *child;
+		RT_PTR_LOCAL child;
 
 		if (NODE_IS_LEAF(node))
 			break;
@@ -1293,7 +1304,7 @@ RT_SET(RT_RADIX_TREE *tree, uint64 key, uint64 value)
 RT_SCOPE bool
 RT_SEARCH(RT_RADIX_TREE *tree, uint64 key, uint64 *value_p)
 {
-	RT_NODE    *node;
+	RT_PTR_LOCAL node;
 	int			shift;
 
 	Assert(value_p != NULL);
@@ -1307,7 +1318,7 @@ RT_SEARCH(RT_RADIX_TREE *tree, uint64 key, uint64 *value_p)
 	/* Descend the tree until a leaf node */
 	while (shift >= 0)
 	{
-		RT_NODE    *child;
+		RT_PTR_ALLOC child;
 
 		if (NODE_IS_LEAF(node))
 			break;
@@ -1329,8 +1340,8 @@ RT_SEARCH(RT_RADIX_TREE *tree, uint64 key, uint64 *value_p)
 RT_SCOPE bool
 RT_DELETE(RT_RADIX_TREE *tree, uint64 key)
 {
-	RT_NODE    *node;
-	RT_NODE    *stack[RT_MAX_LEVEL] = {0};
+	RT_PTR_LOCAL node;
+	RT_PTR_ALLOC stack[RT_MAX_LEVEL] = {0};
 	int			shift;
 	int			level;
 	bool		deleted;
@@ -1347,7 +1358,7 @@ RT_DELETE(RT_RADIX_TREE *tree, uint64 key)
 	level = -1;
 	while (shift > 0)
 	{
-		RT_NODE    *child;
+		RT_PTR_ALLOC child;
 
 		/* Push the current node to the stack */
 		stack[++level] = node;
@@ -1412,7 +1423,7 @@ RT_ITER_UPDATE_KEY(RT_ITER *iter, uint8 chunk, uint8 shift)
  * Advance the slot in the inner node. Return the child if exists, otherwise
  * null.
  */
-static inline RT_NODE *
+static inline RT_PTR_LOCAL
 RT_NODE_INNER_ITERATE_NEXT(RT_ITER *iter, RT_NODE_ITER *node_iter)
 {
 #define RT_NODE_LEVEL_INNER
@@ -1437,10 +1448,10 @@ RT_NODE_LEAF_ITERATE_NEXT(RT_ITER *iter, RT_NODE_ITER *node_iter,
  * Update each node_iter for inner nodes in the iterator node stack.
  */
 static void
-RT_UPDATE_ITER_STACK(RT_ITER *iter, RT_NODE *from_node, int from)
+RT_UPDATE_ITER_STACK(RT_ITER *iter, RT_PTR_LOCAL from_node, int from)
 {
 	int			level = from;
-	RT_NODE    *node = from_node;
+	RT_PTR_LOCAL node = from_node;
 
 	for (;;)
 	{
@@ -1505,7 +1516,7 @@ RT_ITERATE_NEXT(RT_ITER *iter, uint64 *key_p, uint64 *value_p)
 
 	for (;;)
 	{
-		RT_NODE    *child = NULL;
+		RT_PTR_LOCAL child = NULL;
 		uint64		value;
 		int			level;
 		bool		found;
@@ -1584,7 +1595,7 @@ RT_MEMORY_USAGE(RT_RADIX_TREE *tree)
  * Verify the radix tree node.
  */
 static void
-RT_VERIFY_NODE(RT_NODE *node)
+RT_VERIFY_NODE(RT_PTR_LOCAL node)
 {
 #ifdef USE_ASSERT_CHECKING
 	Assert(node->count >= 0);
@@ -1669,7 +1680,7 @@ rt_stats(RT_RADIX_TREE *tree)
 }
 
 static void
-rt_dump_node(RT_NODE *node, int level, bool recurse)
+rt_dump_node(RT_PTR_LOCAL node, int level, bool recurse)
 {
 	char		space[125] = {0};
 
@@ -1831,7 +1842,7 @@ rt_dump_node(RT_NODE *node, int level, bool recurse)
 void
 rt_dump_search(RT_RADIX_TREE *tree, uint64 key)
 {
-	RT_NODE    *node;
+	RT_PTR_LOCAL node;
 	int			shift;
 	int			level = 0;
 
@@ -1856,7 +1867,7 @@ rt_dump_search(RT_RADIX_TREE *tree, uint64 key)
 	shift = tree->root->shift;
 	while (shift >= 0)
 	{
-		RT_NODE    *child;
+		RT_PTR_LOCAL child;
 
 		rt_dump_node(node, level, false);
 
diff --git a/src/include/lib/radixtree_search_impl.h b/src/include/lib/radixtree_search_impl.h
index 1a0d2d3f1f..cbc357dcc8 100644
--- a/src/include/lib/radixtree_search_impl.h
+++ b/src/include/lib/radixtree_search_impl.h
@@ -17,7 +17,7 @@
 #ifdef RT_NODE_LEVEL_LEAF
 	uint64		value = 0;
 #else
-	RT_NODE    *child = NULL;
+	RT_PTR_LOCAL child = NULL;
 #endif
 
 	switch (node->kind)
-- 
2.39.0