v21-0007-Make-value-type-configurable.patch

text/x-patch

Filename: v21-0007-Make-value-type-configurable.patch
Type: text/x-patch
Part: 9
Message: Re: [PoC] Improve dead tuple storage for lazy vacuum

Patch

Format: format-patch
Series: patch v21-0007
Subject: Make value type configurable
File+
src/include/lib/radixtree_delete_impl.h 2 2
src/include/lib/radixtree.h 41 38
src/include/lib/radixtree_iter_impl.h 1 1
src/include/lib/radixtree_search_impl.h 1 1
src/test/modules/test_radixtree/test_radixtree.c 24 17
From 9b6adf0d916cb4bce3dd0e329b59cd1b27013e67 Mon Sep 17 00:00:00 2001
From: John Naylor <john.naylor@postgresql.org>
Date: Fri, 20 Jan 2023 14:19:15 +0700
Subject: [PATCH v21 07/22] Make value type configurable

Tests pass with uint32, although the test module builds
with warnings.
---
 src/include/lib/radixtree.h                   | 79 ++++++++++---------
 src/include/lib/radixtree_delete_impl.h       |  4 +-
 src/include/lib/radixtree_iter_impl.h         |  2 +-
 src/include/lib/radixtree_search_impl.h       |  2 +-
 .../modules/test_radixtree/test_radixtree.c   | 41 ++++++----
 5 files changed, 69 insertions(+), 59 deletions(-)

diff --git a/src/include/lib/radixtree.h b/src/include/lib/radixtree.h
index 98e4597eac..0a39bd6664 100644
--- a/src/include/lib/radixtree.h
+++ b/src/include/lib/radixtree.h
@@ -44,6 +44,7 @@
  *		declarations reside
  *	  - RT_SHMEM - if defined, the radix tree is created in the DSA area
  *		so that multiple processes can access it simultaneously.
+ *	  - RT_VALUE_TYPE - the type of the value.
  *
  *	  Optional parameters:
  *	  - RT_DEBUG - if defined add stats tracking and debugging functions
@@ -222,14 +223,14 @@ RT_SCOPE RT_RADIX_TREE * RT_CREATE(MemoryContext ctx);
 #endif
 RT_SCOPE void RT_FREE(RT_RADIX_TREE *tree);
 
-RT_SCOPE bool RT_SEARCH(RT_RADIX_TREE *tree, uint64 key, uint64 *val_p);
-RT_SCOPE bool RT_SET(RT_RADIX_TREE *tree, uint64 key, uint64 val);
+RT_SCOPE bool RT_SEARCH(RT_RADIX_TREE *tree, uint64 key, RT_VALUE_TYPE *val_p);
+RT_SCOPE bool RT_SET(RT_RADIX_TREE *tree, uint64 key, RT_VALUE_TYPE val);
 #ifdef RT_USE_DELETE
 RT_SCOPE bool RT_DELETE(RT_RADIX_TREE *tree, uint64 key);
 #endif
 
 RT_SCOPE RT_ITER * RT_BEGIN_ITERATE(RT_RADIX_TREE *tree);
-RT_SCOPE bool RT_ITERATE_NEXT(RT_ITER *iter, uint64 *key_p, uint64 *value_p);
+RT_SCOPE bool RT_ITERATE_NEXT(RT_ITER *iter, uint64 *key_p, RT_VALUE_TYPE *value_p);
 RT_SCOPE void RT_END_ITERATE(RT_ITER *iter);
 
 RT_SCOPE uint64 RT_MEMORY_USAGE(RT_RADIX_TREE *tree);
@@ -435,7 +436,7 @@ typedef struct RT_NODE_LEAF_4
 	RT_NODE_BASE_4 base;
 
 	/* number of values depends on size class */
-	uint64		values[FLEXIBLE_ARRAY_MEMBER];
+	RT_VALUE_TYPE	values[FLEXIBLE_ARRAY_MEMBER];
 } RT_NODE_LEAF_4;
 
 typedef struct RT_NODE_INNER_32
@@ -451,7 +452,7 @@ typedef struct RT_NODE_LEAF_32
 	RT_NODE_BASE_32 base;
 
 	/* number of values depends on size class */
-	uint64		values[FLEXIBLE_ARRAY_MEMBER];
+	RT_VALUE_TYPE	values[FLEXIBLE_ARRAY_MEMBER];
 } RT_NODE_LEAF_32;
 
 typedef struct RT_NODE_INNER_125
@@ -467,7 +468,7 @@ typedef struct RT_NODE_LEAF_125
 	RT_NODE_BASE_125 base;
 
 	/* number of values depends on size class */
-	uint64		values[FLEXIBLE_ARRAY_MEMBER];
+	RT_VALUE_TYPE	values[FLEXIBLE_ARRAY_MEMBER];
 } RT_NODE_LEAF_125;
 
 /*
@@ -490,7 +491,7 @@ typedef struct RT_NODE_LEAF_256
 	bitmapword	isset[BM_IDX(RT_NODE_MAX_SLOTS)];
 
 	/* Slots for 256 values */
-	uint64		values[RT_NODE_MAX_SLOTS];
+	RT_VALUE_TYPE	values[RT_NODE_MAX_SLOTS];
 } RT_NODE_LEAF_256;
 
 /* Information for each size class */
@@ -520,33 +521,33 @@ static const RT_SIZE_CLASS_ELEM RT_SIZE_CLASS_INFO[] = {
 		.name = "radix tree node 4",
 		.fanout = 4,
 		.inner_size = sizeof(RT_NODE_INNER_4) + 4 * sizeof(RT_PTR_ALLOC),
-		.leaf_size = sizeof(RT_NODE_LEAF_4) + 4 * sizeof(uint64),
+		.leaf_size = sizeof(RT_NODE_LEAF_4) + 4 * sizeof(RT_VALUE_TYPE),
 		.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)),
+		.leaf_blocksize = NODE_SLAB_BLOCK_SIZE(sizeof(RT_NODE_LEAF_4) + 4 * sizeof(RT_VALUE_TYPE)),
 	},
 	[RT_CLASS_32_PARTIAL] = {
 		.name = "radix tree node 15",
 		.fanout = 15,
 		.inner_size = sizeof(RT_NODE_INNER_32) + 15 * sizeof(RT_PTR_ALLOC),
-		.leaf_size = sizeof(RT_NODE_LEAF_32) + 15 * sizeof(uint64),
+		.leaf_size = sizeof(RT_NODE_LEAF_32) + 15 * sizeof(RT_VALUE_TYPE),
 		.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)),
+		.leaf_blocksize = NODE_SLAB_BLOCK_SIZE(sizeof(RT_NODE_LEAF_32) + 15 * sizeof(RT_VALUE_TYPE)),
 	},
 	[RT_CLASS_32_FULL] = {
 		.name = "radix tree node 32",
 		.fanout = 32,
 		.inner_size = sizeof(RT_NODE_INNER_32) + 32 * sizeof(RT_PTR_ALLOC),
-		.leaf_size = sizeof(RT_NODE_LEAF_32) + 32 * sizeof(uint64),
+		.leaf_size = sizeof(RT_NODE_LEAF_32) + 32 * sizeof(RT_VALUE_TYPE),
 		.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)),
+		.leaf_blocksize = NODE_SLAB_BLOCK_SIZE(sizeof(RT_NODE_LEAF_32) + 32 * sizeof(RT_VALUE_TYPE)),
 	},
 	[RT_CLASS_125_FULL] = {
 		.name = "radix tree node 125",
 		.fanout = 125,
 		.inner_size = sizeof(RT_NODE_INNER_125) + 125 * sizeof(RT_PTR_ALLOC),
-		.leaf_size = sizeof(RT_NODE_LEAF_125) + 125 * sizeof(uint64),
+		.leaf_size = sizeof(RT_NODE_LEAF_125) + 125 * sizeof(RT_VALUE_TYPE),
 		.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)),
+		.leaf_blocksize = NODE_SLAB_BLOCK_SIZE(sizeof(RT_NODE_LEAF_125) + 125 * sizeof(RT_VALUE_TYPE)),
 	},
 	[RT_CLASS_256] = {
 		.name = "radix tree node 256",
@@ -648,7 +649,7 @@ typedef struct RT_ITER
 static bool RT_NODE_INSERT_INNER(RT_RADIX_TREE *tree, RT_PTR_LOCAL parent, RT_PTR_ALLOC stored_node, RT_PTR_LOCAL node,
 								 uint64 key, RT_PTR_ALLOC child);
 static bool RT_NODE_INSERT_LEAF(RT_RADIX_TREE *tree, RT_PTR_LOCAL parent, RT_PTR_ALLOC stored_node, RT_PTR_LOCAL node,
-								uint64 key, uint64 value);
+								uint64 key, RT_VALUE_TYPE value);
 
 /* verification (available only with assertion) */
 static void RT_VERIFY_NODE(RT_PTR_LOCAL node);
@@ -828,10 +829,10 @@ RT_CHUNK_CHILDREN_ARRAY_SHIFT(uint8 *chunks, RT_PTR_ALLOC *children, int count,
 }
 
 static inline void
-RT_CHUNK_VALUES_ARRAY_SHIFT(uint8 *chunks, uint64 *values, int count, int idx)
+RT_CHUNK_VALUES_ARRAY_SHIFT(uint8 *chunks, RT_VALUE_TYPE *values, int count, int idx)
 {
 	memmove(&(chunks[idx + 1]), &(chunks[idx]), sizeof(uint8) * (count - idx));
-	memmove(&(values[idx + 1]), &(values[idx]), sizeof(uint64) * (count - idx));
+	memmove(&(values[idx + 1]), &(values[idx]), sizeof(RT_VALUE_TYPE) * (count - idx));
 }
 
 /* Delete the element at 'idx' */
@@ -843,10 +844,10 @@ RT_CHUNK_CHILDREN_ARRAY_DELETE(uint8 *chunks, RT_PTR_ALLOC *children, int count,
 }
 
 static inline void
-RT_CHUNK_VALUES_ARRAY_DELETE(uint8 *chunks, uint64 *values, int count, int idx)
+RT_CHUNK_VALUES_ARRAY_DELETE(uint8 *chunks, RT_VALUE_TYPE *values, int count, int idx)
 {
 	memmove(&(chunks[idx]), &(chunks[idx + 1]), sizeof(uint8) * (count - idx - 1));
-	memmove(&(values[idx]), &(values[idx + 1]), sizeof(uint64) * (count - idx - 1));
+	memmove(&(values[idx]), &(values[idx + 1]), sizeof(RT_VALUE_TYPE) * (count - idx - 1));
 }
 
 /* Copy both chunks and children/values arrays */
@@ -863,12 +864,12 @@ RT_CHUNK_CHILDREN_ARRAY_COPY(uint8 *src_chunks, RT_PTR_ALLOC *src_children,
 }
 
 static inline void
-RT_CHUNK_VALUES_ARRAY_COPY(uint8 *src_chunks, uint64 *src_values,
-						uint8 *dst_chunks, uint64 *dst_values)
+RT_CHUNK_VALUES_ARRAY_COPY(uint8 *src_chunks, RT_VALUE_TYPE *src_values,
+						uint8 *dst_chunks, RT_VALUE_TYPE *dst_values)
 {
 	const int fanout = RT_SIZE_CLASS_INFO[RT_CLASS_4_FULL].fanout;
 	const Size chunk_size = sizeof(uint8) * fanout;
-	const Size values_size = sizeof(uint64) * fanout;
+	const Size values_size = sizeof(RT_VALUE_TYPE) * fanout;
 
 	memcpy(dst_chunks, src_chunks, chunk_size);
 	memcpy(dst_values, src_values, values_size);
@@ -890,7 +891,7 @@ RT_NODE_INNER_125_GET_CHILD(RT_NODE_INNER_125 *node, uint8 chunk)
 	return node->children[node->base.slot_idxs[chunk]];
 }
 
-static inline uint64
+static inline RT_VALUE_TYPE
 RT_NODE_LEAF_125_GET_VALUE(RT_NODE_LEAF_125 *node, uint8 chunk)
 {
 	Assert(NODE_IS_LEAF(node));
@@ -926,7 +927,7 @@ RT_NODE_INNER_256_GET_CHILD(RT_NODE_INNER_256 *node, uint8 chunk)
 	return node->children[chunk];
 }
 
-static inline uint64
+static inline RT_VALUE_TYPE
 RT_NODE_LEAF_256_GET_VALUE(RT_NODE_LEAF_256 *node, uint8 chunk)
 {
 	Assert(NODE_IS_LEAF(node));
@@ -944,7 +945,7 @@ RT_NODE_INNER_256_SET(RT_NODE_INNER_256 *node, uint8 chunk, RT_PTR_ALLOC child)
 
 /* Set the value in the node-256 */
 static inline void
-RT_NODE_LEAF_256_SET(RT_NODE_LEAF_256 *node, uint8 chunk, uint64 value)
+RT_NODE_LEAF_256_SET(RT_NODE_LEAF_256 *node, uint8 chunk, RT_VALUE_TYPE value)
 {
 	int			idx = BM_IDX(chunk);
 	int			bitnum = BM_BIT(chunk);
@@ -1215,7 +1216,7 @@ 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_PTR_LOCAL parent,
+RT_SET_EXTEND(RT_RADIX_TREE *tree, uint64 key, RT_VALUE_TYPE value, RT_PTR_LOCAL parent,
 			  RT_PTR_ALLOC stored_node, RT_PTR_LOCAL node)
 {
 	int			shift = node->shift;
@@ -1266,7 +1267,7 @@ RT_NODE_SEARCH_INNER(RT_PTR_LOCAL node, uint64 key, RT_PTR_ALLOC *child_p)
  * to the value is set to value_p.
  */
 static inline bool
-RT_NODE_SEARCH_LEAF(RT_PTR_LOCAL node, uint64 key, uint64 *value_p)
+RT_NODE_SEARCH_LEAF(RT_PTR_LOCAL node, uint64 key, RT_VALUE_TYPE *value_p)
 {
 #define RT_NODE_LEVEL_LEAF
 #include "lib/radixtree_search_impl.h"
@@ -1320,7 +1321,7 @@ RT_NODE_INSERT_INNER(RT_RADIX_TREE *tree, RT_PTR_LOCAL parent, RT_PTR_ALLOC stor
 /* Like, RT_NODE_INSERT_INNER, but for leaf nodes */
 static bool
 RT_NODE_INSERT_LEAF(RT_RADIX_TREE *tree, RT_PTR_LOCAL parent, RT_PTR_ALLOC stored_node, RT_PTR_LOCAL node,
-					uint64 key, uint64 value)
+					uint64 key, RT_VALUE_TYPE value)
 {
 #define RT_NODE_LEVEL_LEAF
 #include "lib/radixtree_insert_impl.h"
@@ -1522,7 +1523,7 @@ RT_FREE(RT_RADIX_TREE *tree)
  * and return true. Returns false if entry doesn't yet exist.
  */
 RT_SCOPE bool
-RT_SET(RT_RADIX_TREE *tree, uint64 key, uint64 value)
+RT_SET(RT_RADIX_TREE *tree, uint64 key, RT_VALUE_TYPE value)
 {
 	int			shift;
 	bool		updated;
@@ -1582,7 +1583,7 @@ RT_SET(RT_RADIX_TREE *tree, uint64 key, uint64 value)
  * not be NULL.
  */
 RT_SCOPE bool
-RT_SEARCH(RT_RADIX_TREE *tree, uint64 key, uint64 *value_p)
+RT_SEARCH(RT_RADIX_TREE *tree, uint64 key, RT_VALUE_TYPE *value_p)
 {
 	RT_PTR_LOCAL node;
 	int			shift;
@@ -1730,7 +1731,7 @@ RT_NODE_INNER_ITERATE_NEXT(RT_ITER *iter, RT_NODE_ITER *node_iter)
  */
 static inline bool
 RT_NODE_LEAF_ITERATE_NEXT(RT_ITER *iter, RT_NODE_ITER *node_iter,
-						  uint64 *value_p)
+						  RT_VALUE_TYPE *value_p)
 {
 #define RT_NODE_LEVEL_LEAF
 #include "lib/radixtree_iter_impl.h"
@@ -1803,7 +1804,7 @@ RT_BEGIN_ITERATE(RT_RADIX_TREE *tree)
  * return false.
  */
 RT_SCOPE bool
-RT_ITERATE_NEXT(RT_ITER *iter, uint64 *key_p, uint64 *value_p)
+RT_ITERATE_NEXT(RT_ITER *iter, uint64 *key_p, RT_VALUE_TYPE *value_p)
 {
 	/* Empty tree */
 	if (!iter->tree->ctl->root)
@@ -1812,7 +1813,7 @@ RT_ITERATE_NEXT(RT_ITER *iter, uint64 *key_p, uint64 *value_p)
 	for (;;)
 	{
 		RT_PTR_LOCAL child = NULL;
-		uint64		value;
+		RT_VALUE_TYPE value;
 		int			level;
 		bool		found;
 
@@ -1971,6 +1972,7 @@ RT_STATS(RT_RADIX_TREE *tree)
 						 tree->ctl->cnt[RT_CLASS_256])));
 }
 
+/* XXX For display, assumes value type is numeric */
 static void
 RT_DUMP_NODE(RT_PTR_LOCAL node, int level, bool recurse)
 {
@@ -1998,7 +2000,7 @@ RT_DUMP_NODE(RT_PTR_LOCAL node, int level, bool recurse)
 						RT_NODE_LEAF_4 *n4 = (RT_NODE_LEAF_4 *) node;
 
 						fprintf(stderr, "%schunk 0x%X value 0x" UINT64_FORMAT_HEX "\n",
-								space, n4->base.chunks[i], n4->values[i]);
+								space, n4->base.chunks[i], (uint64) n4->values[i]);
 					}
 					else
 					{
@@ -2024,7 +2026,7 @@ RT_DUMP_NODE(RT_PTR_LOCAL node, int level, bool recurse)
 						RT_NODE_LEAF_32 *n32 = (RT_NODE_LEAF_32 *) node;
 
 						fprintf(stderr, "%schunk 0x%X value 0x" UINT64_FORMAT_HEX "\n",
-								space, n32->base.chunks[i], n32->values[i]);
+								space, n32->base.chunks[i], (uint64) n32->values[i]);
 					}
 					else
 					{
@@ -2077,7 +2079,7 @@ RT_DUMP_NODE(RT_PTR_LOCAL node, int level, bool recurse)
 						RT_NODE_LEAF_125 *n125 = (RT_NODE_LEAF_125 *) b125;
 
 						fprintf(stderr, "%schunk 0x%X value 0x" UINT64_FORMAT_HEX "\n",
-								space, i, RT_NODE_LEAF_125_GET_VALUE(n125, i));
+								space, i, (uint64) RT_NODE_LEAF_125_GET_VALUE(n125, i));
 					}
 					else
 					{
@@ -2107,7 +2109,7 @@ RT_DUMP_NODE(RT_PTR_LOCAL node, int level, bool recurse)
 							continue;
 
 						fprintf(stderr, "%schunk 0x%X value 0x" UINT64_FORMAT_HEX "\n",
-								space, i, RT_NODE_LEAF_256_GET_VALUE(n256, i));
+								space, i, (uint64) RT_NODE_LEAF_256_GET_VALUE(n256, i));
 					}
 					else
 					{
@@ -2213,6 +2215,7 @@ RT_DUMP(RT_RADIX_TREE *tree)
 #undef RT_SCOPE
 #undef RT_DECLARE
 #undef RT_DEFINE
+#undef RT_VALUE_TYPE
 
 /* locally declared macros */
 #undef NODE_IS_LEAF
diff --git a/src/include/lib/radixtree_delete_impl.h b/src/include/lib/radixtree_delete_impl.h
index eb87866b90..2612730481 100644
--- a/src/include/lib/radixtree_delete_impl.h
+++ b/src/include/lib/radixtree_delete_impl.h
@@ -33,7 +33,7 @@
 					return false;
 
 #ifdef RT_NODE_LEVEL_LEAF
-				RT_CHUNK_VALUES_ARRAY_DELETE(n4->base.chunks, (uint64 *) n4->values,
+				RT_CHUNK_VALUES_ARRAY_DELETE(n4->base.chunks, n4->values,
 										  n4->base.n.count, idx);
 #else
 				RT_CHUNK_CHILDREN_ARRAY_DELETE(n4->base.chunks, n4->children,
@@ -50,7 +50,7 @@
 					return false;
 
 #ifdef RT_NODE_LEVEL_LEAF
-				RT_CHUNK_VALUES_ARRAY_DELETE(n32->base.chunks, (uint64 *) n32->values,
+				RT_CHUNK_VALUES_ARRAY_DELETE(n32->base.chunks, n32->values,
 										  n32->base.n.count, idx);
 #else
 				RT_CHUNK_CHILDREN_ARRAY_DELETE(n32->base.chunks, n32->children,
diff --git a/src/include/lib/radixtree_iter_impl.h b/src/include/lib/radixtree_iter_impl.h
index 0b8b68df6c..5c06f8b414 100644
--- a/src/include/lib/radixtree_iter_impl.h
+++ b/src/include/lib/radixtree_iter_impl.h
@@ -16,7 +16,7 @@
 	uint8		key_chunk;
 
 #ifdef RT_NODE_LEVEL_LEAF
-	uint64		value;
+	RT_VALUE_TYPE		value;
 
 	Assert(NODE_IS_LEAF(node_iter->node));
 #else
diff --git a/src/include/lib/radixtree_search_impl.h b/src/include/lib/radixtree_search_impl.h
index 31e4978e4f..365abaa46d 100644
--- a/src/include/lib/radixtree_search_impl.h
+++ b/src/include/lib/radixtree_search_impl.h
@@ -15,7 +15,7 @@
 	uint8		chunk = RT_GET_KEY_CHUNK(key, node->shift);
 
 #ifdef RT_NODE_LEVEL_LEAF
-	uint64		value = 0;
+	RT_VALUE_TYPE		value = 0;
 
 	Assert(NODE_IS_LEAF(node));
 #else
diff --git a/src/test/modules/test_radixtree/test_radixtree.c b/src/test/modules/test_radixtree/test_radixtree.c
index d8323f587f..64d46dfe9a 100644
--- a/src/test/modules/test_radixtree/test_radixtree.c
+++ b/src/test/modules/test_radixtree/test_radixtree.c
@@ -24,6 +24,12 @@
 
 #define UINT64_HEX_FORMAT "%" INT64_MODIFIER "X"
 
+/*
+ * The tests pass with uint32, but build with warnings because the string
+ * format expects uint64.
+ */
+typedef uint64 TestValueType;
+
 /*
  * If you enable this, the "pattern" tests will print information about
  * how long populating, probing, and iterating the test set takes, and
@@ -105,6 +111,7 @@ static const test_spec test_specs[] = {
 #define RT_DECLARE
 #define RT_DEFINE
 #define RT_USE_DELETE
+#define RT_VALUE_TYPE TestValueType
 // WIP: compiles with warnings because rt_attach is defined but not used
 // #define RT_SHMEM
 #include "lib/radixtree.h"
@@ -128,9 +135,9 @@ test_empty(void)
 {
 	rt_radix_tree *radixtree;
 	rt_iter		*iter;
-	uint64		dummy;
+	TestValueType		dummy;
 	uint64		key;
-	uint64		val;
+	TestValueType		val;
 
 #ifdef RT_SHMEM
 	int			tranche_id = LWLockNewTrancheId();
@@ -202,26 +209,26 @@ test_basic(int children, bool test_inner)
 	/* insert keys */
 	for (int i = 0; i < children; i++)
 	{
-		if (rt_set(radixtree, keys[i], keys[i]))
+		if (rt_set(radixtree, keys[i], (TestValueType) keys[i]))
 			elog(ERROR, "new inserted key 0x" UINT64_HEX_FORMAT " is found ", keys[i]);
 	}
 
 	/* look up keys */
 	for (int i = 0; i < children; i++)
 	{
-		uint64 value;
+		TestValueType value;
 
 		if (!rt_search(radixtree, keys[i], &value))
 			elog(ERROR, "could not find key 0x" UINT64_HEX_FORMAT, keys[i]);
-		if (value != keys[i])
+		if (value != (TestValueType) keys[i])
 			elog(ERROR, "rt_search returned 0x" UINT64_HEX_FORMAT ", expected " UINT64_HEX_FORMAT,
-				 value, keys[i]);
+				 value, (TestValueType) keys[i]);
 	}
 
 	/* update keys */
 	for (int i = 0; i < children; i++)
 	{
-		if (!rt_set(radixtree, keys[i], keys[i] + 1))
+		if (!rt_set(radixtree, keys[i], (TestValueType) (keys[i] + 1)))
 			elog(ERROR, "could not update key 0x" UINT64_HEX_FORMAT, keys[i]);
 	}
 
@@ -230,7 +237,7 @@ test_basic(int children, bool test_inner)
 	{
 		if (!rt_delete(radixtree, keys[i]))
 			elog(ERROR, "could not delete key 0x" UINT64_HEX_FORMAT, keys[i]);
-		if (rt_set(radixtree, keys[i], keys[i]))
+		if (rt_set(radixtree, keys[i], (TestValueType) keys[i]))
 			elog(ERROR, "new inserted key 0x" UINT64_HEX_FORMAT " is found ", keys[i]);
 	}
 
@@ -248,12 +255,12 @@ check_search_on_node(rt_radix_tree *radixtree, uint8 shift, int start, int end,
 	for (int i = start; i < end; i++)
 	{
 		uint64		key = ((uint64) i << shift);
-		uint64		val;
+		TestValueType		val;
 
 		if (!rt_search(radixtree, key, &val))
 			elog(ERROR, "key 0x" UINT64_HEX_FORMAT " is not found on node-%d",
 				 key, end);
-		if (val != key)
+		if (val != (TestValueType) key)
 			elog(ERROR, "rt_search with key 0x" UINT64_HEX_FORMAT " returns 0x" UINT64_HEX_FORMAT ", expected 0x" UINT64_HEX_FORMAT,
 				 key, val, key);
 	}
@@ -274,7 +281,7 @@ test_node_types_insert(rt_radix_tree *radixtree, uint8 shift, bool insert_asc)
 		uint64		key = ((uint64) i << shift);
 		bool		found;
 
-		found = rt_set(radixtree, key, key);
+		found = rt_set(radixtree, key, (TestValueType) key);
 		if (found)
 			elog(ERROR, "newly inserted key 0x" UINT64_HEX_FORMAT " is found", key);
 
@@ -440,7 +447,7 @@ test_pattern(const test_spec * spec)
 
 			x = last_int + pattern_values[i];
 
-			found = rt_set(radixtree, x, x);
+			found = rt_set(radixtree, x, (TestValueType) x);
 
 			if (found)
 				elog(ERROR, "newly inserted key 0x" UINT64_HEX_FORMAT " found", x);
@@ -495,7 +502,7 @@ test_pattern(const test_spec * spec)
 		bool		found;
 		bool		expected;
 		uint64		x;
-		uint64		v;
+		TestValueType		v;
 
 		/*
 		 * Pick next value to probe at random.  We limit the probes to the
@@ -526,7 +533,7 @@ test_pattern(const test_spec * spec)
 
 		if (found != expected)
 			elog(ERROR, "mismatch at 0x" UINT64_HEX_FORMAT ": %d vs %d", x, found, expected);
-		if (found && (v != x))
+		if (found && (v != (TestValueType) x))
 			elog(ERROR, "found 0x" UINT64_HEX_FORMAT ", expected 0x" UINT64_HEX_FORMAT,
 				 v, x);
 	}
@@ -549,7 +556,7 @@ test_pattern(const test_spec * spec)
 		{
 			uint64		expected = last_int + pattern_values[i];
 			uint64		x;
-			uint64		val;
+			TestValueType		val;
 
 			if (!rt_iterate_next(iter, &x, &val))
 				break;
@@ -558,7 +565,7 @@ test_pattern(const test_spec * spec)
 				elog(ERROR,
 					 "iterate returned wrong key; got 0x" UINT64_HEX_FORMAT ", expected 0x" UINT64_HEX_FORMAT " at %d",
 					 x, expected, i);
-			if (val != expected)
+			if (val != (TestValueType) expected)
 				elog(ERROR,
 					 "iterate returned wrong value; got 0x" UINT64_HEX_FORMAT ", expected 0x" UINT64_HEX_FORMAT " at %d", x, expected, i);
 			n++;
@@ -588,7 +595,7 @@ test_pattern(const test_spec * spec)
 	{
 		bool		found;
 		uint64		x;
-		uint64		v;
+		TestValueType		v;
 
 		/*
 		 * Pick next value to probe at random.  We limit the probes to the
-- 
2.39.0