From 4573327ba7fa1179389af4383c04053251a8bf73 Mon Sep 17 00:00:00 2001 From: John Naylor 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