From a9982146efaa2c1b7139bc804ee33c0062be605a Mon Sep 17 00:00:00 2001 From: John Naylor Date: Fri, 23 Dec 2022 15:31:49 +0700 Subject: [PATCH v16 11/12] Template out node search functions --- src/backend/lib/radixtree.c | 168 +----------------------- src/include/lib/radixtree_search_impl.h | 151 +++++++++++++++++++++ 2 files changed, 157 insertions(+), 162 deletions(-) create mode 100644 src/include/lib/radixtree_search_impl.h diff --git a/src/backend/lib/radixtree.c b/src/backend/lib/radixtree.c index 79d12b27d2..99450c96c8 100644 --- a/src/backend/lib/radixtree.c +++ b/src/backend/lib/radixtree.c @@ -1109,87 +1109,9 @@ rt_set_extend(radix_tree *tree, uint64 key, uint64 value, rt_node *parent, static inline bool rt_node_search_inner(rt_node *node, uint64 key, rt_action action, rt_node **child_p) { - uint8 chunk = RT_GET_KEY_CHUNK(key, node->shift); - bool found = false; - rt_node *child = NULL; - - switch (node->kind) - { - case RT_NODE_KIND_4: - { - rt_node_inner_4 *n4 = (rt_node_inner_4 *) node; - int idx = node_4_search_eq((rt_node_base_4 *) n4, chunk); - - if (idx < 0) - break; - - found = true; - - if (action == RT_ACTION_FIND) - child = n4->children[idx]; - else /* RT_ACTION_DELETE */ - chunk_children_array_delete(n4->base.chunks, n4->children, - n4->base.n.count, idx); - - break; - } - case RT_NODE_KIND_32: - { - rt_node_inner_32 *n32 = (rt_node_inner_32 *) node; - int idx = node_32_search_eq((rt_node_base_32 *) n32, chunk); - - if (idx < 0) - break; - - found = true; - if (action == RT_ACTION_FIND) - child = n32->children[idx]; - else /* RT_ACTION_DELETE */ - chunk_children_array_delete(n32->base.chunks, n32->children, - n32->base.n.count, idx); - break; - } - case RT_NODE_KIND_125: - { - rt_node_inner_125 *n125 = (rt_node_inner_125 *) node; - - if (!node_125_is_chunk_used((rt_node_base_125 *) n125, chunk)) - break; - - found = true; - - if (action == RT_ACTION_FIND) - child = node_inner_125_get_child(n125, chunk); - else /* RT_ACTION_DELETE */ - node_inner_125_delete(n125, chunk); - - break; - } - case RT_NODE_KIND_256: - { - rt_node_inner_256 *n256 = (rt_node_inner_256 *) node; - - if (!node_inner_256_is_chunk_used(n256, chunk)) - break; - - found = true; - if (action == RT_ACTION_FIND) - child = node_inner_256_get_child(n256, chunk); - else /* RT_ACTION_DELETE */ - node_inner_256_delete(n256, chunk); - - break; - } - } - - /* update statistics */ - if (action == RT_ACTION_DELETE && found) - node->count--; - - if (found && child_p) - *child_p = child; - - return found; +#define RT_NODE_LEVEL_INNER +#include "lib/radixtree_search_impl.h" +#undef RT_NODE_LEVEL_INNER } /* @@ -1202,87 +1124,9 @@ rt_node_search_inner(rt_node *node, uint64 key, rt_action action, rt_node **chil static inline bool rt_node_search_leaf(rt_node *node, uint64 key, rt_action action, uint64 *value_p) { - uint8 chunk = RT_GET_KEY_CHUNK(key, node->shift); - bool found = false; - uint64 value = 0; - - switch (node->kind) - { - case RT_NODE_KIND_4: - { - rt_node_leaf_4 *n4 = (rt_node_leaf_4 *) node; - int idx = node_4_search_eq((rt_node_base_4 *) n4, chunk); - - if (idx < 0) - break; - - found = true; - - if (action == RT_ACTION_FIND) - value = n4->values[idx]; - else /* RT_ACTION_DELETE */ - chunk_values_array_delete(n4->base.chunks, (uint64 *) n4->values, - n4->base.n.count, idx); - - break; - } - case RT_NODE_KIND_32: - { - rt_node_leaf_32 *n32 = (rt_node_leaf_32 *) node; - int idx = node_32_search_eq((rt_node_base_32 *) n32, chunk); - - if (idx < 0) - break; - - found = true; - if (action == RT_ACTION_FIND) - value = n32->values[idx]; - else /* RT_ACTION_DELETE */ - chunk_values_array_delete(n32->base.chunks, (uint64 *) n32->values, - n32->base.n.count, idx); - break; - } - case RT_NODE_KIND_125: - { - rt_node_leaf_125 *n125 = (rt_node_leaf_125 *) node; - - if (!node_125_is_chunk_used((rt_node_base_125 *) n125, chunk)) - break; - - found = true; - - if (action == RT_ACTION_FIND) - value = node_leaf_125_get_value(n125, chunk); - else /* RT_ACTION_DELETE */ - node_leaf_125_delete(n125, chunk); - - break; - } - case RT_NODE_KIND_256: - { - rt_node_leaf_256 *n256 = (rt_node_leaf_256 *) node; - - if (!node_leaf_256_is_chunk_used(n256, chunk)) - break; - - found = true; - if (action == RT_ACTION_FIND) - value = node_leaf_256_get_value(n256, chunk); - else /* RT_ACTION_DELETE */ - node_leaf_256_delete(n256, chunk); - - break; - } - } - - /* update statistics */ - if (action == RT_ACTION_DELETE && found) - node->count--; - - if (found && value_p) - *value_p = value; - - return found; +#define RT_NODE_LEVEL_LEAF +#include "lib/radixtree_search_impl.h" +#undef RT_NODE_LEVEL_LEAF } /* Insert the child to the inner node */ diff --git a/src/include/lib/radixtree_search_impl.h b/src/include/lib/radixtree_search_impl.h new file mode 100644 index 0000000000..0173d9cb2f --- /dev/null +++ b/src/include/lib/radixtree_search_impl.h @@ -0,0 +1,151 @@ +#if defined(RT_NODE_LEVEL_INNER) +#define RT_NODE4_TYPE rt_node_inner_4 +#define RT_NODE32_TYPE rt_node_inner_32 +#define RT_NODE125_TYPE rt_node_inner_125 +#define RT_NODE256_TYPE rt_node_inner_256 +#elif defined(RT_NODE_LEVEL_LEAF) +#define RT_NODE4_TYPE rt_node_leaf_4 +#define RT_NODE32_TYPE rt_node_leaf_32 +#define RT_NODE125_TYPE rt_node_leaf_125 +#define RT_NODE256_TYPE rt_node_leaf_256 +#else +#error node level must be either inner or leaf +#endif + + uint8 chunk = RT_GET_KEY_CHUNK(key, node->shift); + bool found = false; + +#ifdef RT_NODE_LEVEL_LEAF + uint64 value = 0; +#else + rt_node *child = NULL; +#endif + + switch (node->kind) + { + case RT_NODE_KIND_4: + { + RT_NODE4_TYPE *n4 = (RT_NODE4_TYPE *) node; + int idx = node_4_search_eq((rt_node_base_4 *) n4, chunk); + + if (idx < 0) + break; + + found = true; + + if (action == RT_ACTION_FIND) +#ifdef RT_NODE_LEVEL_LEAF + value = n4->values[idx]; +#else + child = n4->children[idx]; +#endif + else /* RT_ACTION_DELETE */ +#ifdef RT_NODE_LEVEL_LEAF + chunk_values_array_delete(n4->base.chunks, (uint64 *) n4->values, + n4->base.n.count, idx); +#else + chunk_children_array_delete(n4->base.chunks, n4->children, + n4->base.n.count, idx); +#endif + break; + } + case RT_NODE_KIND_32: + { + RT_NODE32_TYPE *n32 = (RT_NODE32_TYPE *) node; + int idx = node_32_search_eq((rt_node_base_32 *) n32, chunk); + + if (idx < 0) + break; + + found = true; + + if (action == RT_ACTION_FIND) +#ifdef RT_NODE_LEVEL_LEAF + value = n32->values[idx]; +#else + child = n32->children[idx]; +#endif + else /* RT_ACTION_DELETE */ +#ifdef RT_NODE_LEVEL_LEAF + chunk_values_array_delete(n32->base.chunks, (uint64 *) n32->values, + n32->base.n.count, idx); +#else + chunk_children_array_delete(n32->base.chunks, n32->children, + n32->base.n.count, idx); +#endif + break; + } + case RT_NODE_KIND_125: + { + RT_NODE125_TYPE *n125 = (RT_NODE125_TYPE *) node; + + if (!node_125_is_chunk_used((rt_node_base_125 *) n125, chunk)) + break; + + found = true; + + if (action == RT_ACTION_FIND) +#ifdef RT_NODE_LEVEL_LEAF + value = node_leaf_125_get_value(n125, chunk); +#else + child = node_inner_125_get_child(n125, chunk); +#endif + else /* RT_ACTION_DELETE */ +#ifdef RT_NODE_LEVEL_LEAF + node_leaf_125_delete(n125, chunk); +#else + node_inner_125_delete(n125, chunk); +#endif + break; + } + case RT_NODE_KIND_256: + { + RT_NODE256_TYPE *n256 = (RT_NODE256_TYPE *) node; + +#ifdef RT_NODE_LEVEL_LEAF + if (!node_leaf_256_is_chunk_used(n256, chunk)) +#else + if (!node_inner_256_is_chunk_used(n256, chunk)) +#endif + break; + + found = true; + + if (action == RT_ACTION_FIND) +#ifdef RT_NODE_LEVEL_LEAF + value = node_leaf_256_get_value(n256, chunk); +#else + child = node_inner_256_get_child(n256, chunk); +#endif + else /* RT_ACTION_DELETE */ +#ifdef RT_NODE_LEVEL_LEAF + node_leaf_256_delete(n256, chunk); +#else + node_inner_256_delete(n256, chunk); +#endif + + break; + } + } + + if (found) + { + /* update statistics */ + if (action == RT_ACTION_DELETE) + node->count--; + +#ifdef RT_NODE_LEVEL_LEAF + if (value_p) + *value_p = value; +#else + if (child_p) + *child_p = child; +#endif + } + + return found; + +#undef RT_NODE4_TYPE +#undef RT_NODE32_TYPE +#undef RT_NODE125_TYPE +#undef RT_NODE256_TYPE -- 2.38.1