From d13da75dfe46d9ea7776751134fe4c22f83cd15d Mon Sep 17 00:00:00 2001 From: Masahiko Sawada Date: Wed, 25 Jan 2023 16:52:41 +0900 Subject: [PATCH v23 14/18] Improve RT_DUMP() and RT_DUMP_SEARCH() output. We don't display values since these might not be integers. --- src/include/lib/radixtree.h | 201 +++++++++++++++++++++--------------- 1 file changed, 118 insertions(+), 83 deletions(-) diff --git a/src/include/lib/radixtree.h b/src/include/lib/radixtree.h index dbf9df604f..11716fbfca 100644 --- a/src/include/lib/radixtree.h +++ b/src/include/lib/radixtree.h @@ -2023,32 +2023,46 @@ RT_VERIFY_NODE(RT_PTR_LOCAL node) RT_SCOPE void RT_STATS(RT_RADIX_TREE *tree) { - ereport(NOTICE, (errmsg("num_keys = " UINT64_FORMAT ", height = %d, n3 = %u, n15 = %u, n32 = %u, n125 = %u, n256 = %u", - tree->ctl->num_keys, - tree->ctl->root->shift / RT_NODE_SPAN, - tree->ctl->cnt[RT_CLASS_3], - tree->ctl->cnt[RT_CLASS_32_MIN], - tree->ctl->cnt[RT_CLASS_32_MAX], - tree->ctl->cnt[RT_CLASS_125], - tree->ctl->cnt[RT_CLASS_256]))); + fprintf(stderr, "max_val = " UINT64_FORMAT "\n", tree->ctl->max_val); + fprintf(stderr, "num_keys = " UINT64_FORMAT "\n", tree->ctl->num_keys); + +#ifdef RT_SHMEM + fprintf(stderr, "handle = " UINT64_FORMAT "\n", tree->ctl->handle); +#endif + + if (RT_PTR_ALLOC_IS_VALID(tree->ctl->root)) + { + RT_PTR_LOCAL root = RT_PTR_GET_LOCAL(tree, tree->ctl->root); + + fprintf(stderr, "height = %d, n3 = %u, n15 = %u, n32 = %u, n125 = %u, n256 = %u\n", + root->shift / RT_NODE_SPAN, + tree->ctl->cnt[RT_CLASS_3], + tree->ctl->cnt[RT_CLASS_32_MIN], + tree->ctl->cnt[RT_CLASS_32_MAX], + tree->ctl->cnt[RT_CLASS_125], + 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) +RT_DUMP_NODE(RT_RADIX_TREE *tree, RT_PTR_ALLOC allocnode, int level, + bool recurse, StringInfo buf) { - char space[125] = {0}; + RT_PTR_LOCAL node = RT_PTR_GET_LOCAL(tree, allocnode); + StringInfoData spaces; - fprintf(stderr, "[%s] kind %d, fanout %d, count %u, shift %u:\n", - RT_NODE_IS_LEAF(node) ? "LEAF" : "INNR", - (node->kind == RT_NODE_KIND_3) ? 3 : - (node->kind == RT_NODE_KIND_32) ? 32 : - (node->kind == RT_NODE_KIND_125) ? 125 : 256, - node->fanout == 0 ? 256 : node->fanout, - node->count, node->shift); + initStringInfo(&spaces); + appendStringInfoSpaces(&spaces, (level * 4) + 1); - if (level > 0) - sprintf(space, "%*c", level * 4, ' '); + appendStringInfo(buf, "%s%s[%s] kind %d, fanout %d, count %u, shift %u:\n", + spaces.data, + level == 0 ? "" : "-> ", + RT_NODE_IS_LEAF(node) ? "LEAF" : "INNR", + (node->kind == RT_NODE_KIND_3) ? 3 : + (node->kind == RT_NODE_KIND_32) ? 32 : + (node->kind == RT_NODE_KIND_125) ? 125 : 256, + node->fanout == 0 ? 256 : node->fanout, + node->count, node->shift); switch (node->kind) { @@ -2060,20 +2074,24 @@ RT_DUMP_NODE(RT_PTR_LOCAL node, int level, bool recurse) { RT_NODE_LEAF_3 *n3 = (RT_NODE_LEAF_3 *) node; - fprintf(stderr, "%schunk 0x%X value 0x" RT_UINT64_FORMAT_HEX "\n", - space, n3->base.chunks[i], (uint64) n3->values[i]); + appendStringInfo(buf, "%schunk[%d] 0x%X\n", + spaces.data, i, n3->base.chunks[i]); } else { RT_NODE_INNER_3 *n3 = (RT_NODE_INNER_3 *) node; - fprintf(stderr, "%schunk 0x%X ->", - space, n3->base.chunks[i]); + appendStringInfo(buf, "%schunk[%d] 0x%X", + spaces.data, i, n3->base.chunks[i]); if (recurse) - RT_DUMP_NODE(n3->children[i], level + 1, recurse); + { + appendStringInfo(buf, "\n"); + RT_DUMP_NODE(tree, n3->children[i], level + 1, + recurse, buf); + } else - fprintf(stderr, "\n"); + appendStringInfo(buf, " (skipped)\n"); } } break; @@ -2086,22 +2104,25 @@ 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" RT_UINT64_FORMAT_HEX "\n", - space, n32->base.chunks[i], (uint64) n32->values[i]); + appendStringInfo(buf, "%schunk[%d] 0x%X\n", + spaces.data, i, n32->base.chunks[i]); } else { RT_NODE_INNER_32 *n32 = (RT_NODE_INNER_32 *) node; - fprintf(stderr, "%schunk 0x%X ->", - space, n32->base.chunks[i]); + appendStringInfo(buf, "%schunk[%d] 0x%X", + spaces.data, i, n32->base.chunks[i]); if (recurse) { - RT_DUMP_NODE(n32->children[i], level + 1, recurse); + appendStringInfo(buf, "\n"); + RT_DUMP_NODE(tree, n32->children[i], level + 1, + recurse, buf); } else - fprintf(stderr, "\n"); + appendStringInfo(buf, " (skipped)\n"); + } } break; @@ -2109,26 +2130,23 @@ RT_DUMP_NODE(RT_PTR_LOCAL node, int level, bool recurse) case RT_NODE_KIND_125: { RT_NODE_BASE_125 *b125 = (RT_NODE_BASE_125 *) node; + char *sep = ""; - fprintf(stderr, "slot_idxs "); + appendStringInfo(buf, "%sslot_idxs: ", spaces.data); for (int i = 0; i < RT_NODE_MAX_SLOTS; i++) { if (!RT_NODE_125_IS_CHUNK_USED(b125, i)) continue; - fprintf(stderr, " [%d]=%d, ", i, b125->slot_idxs[i]); + appendStringInfo(buf, "%s[%d]=%d ", + sep, i, b125->slot_idxs[i]); + sep = ","; } - if (RT_NODE_IS_LEAF(node)) - { - RT_NODE_LEAF_125 *n = (RT_NODE_LEAF_125 *) node; - fprintf(stderr, ", isset-bitmap:"); - for (int i = 0; i < BM_IDX(RT_SLOT_IDX_LIMIT); i++) - { - fprintf(stderr, RT_UINT64_FORMAT_HEX " ", (uint64) n->base.isset[i]); - } - fprintf(stderr, "\n"); - } + appendStringInfo(buf, "\n%sisset-bitmap: ", spaces.data); + for (int i = 0; i < (RT_SLOT_IDX_LIMIT / BITS_PER_BYTE); i++) + appendStringInfo(buf, "%X ", ((uint8 *) b125->isset)[i]); + appendStringInfo(buf, "\n"); for (int i = 0; i < RT_NODE_MAX_SLOTS; i++) { @@ -2136,30 +2154,39 @@ RT_DUMP_NODE(RT_PTR_LOCAL node, int level, bool recurse) continue; if (RT_NODE_IS_LEAF(node)) - { - RT_NODE_LEAF_125 *n125 = (RT_NODE_LEAF_125 *) b125; - - fprintf(stderr, "%schunk 0x%X value 0x" RT_UINT64_FORMAT_HEX "\n", - space, i, (uint64) RT_NODE_LEAF_125_GET_VALUE(n125, i)); - } + appendStringInfo(buf, "%schunk 0x%X\n", + spaces.data, i); else { RT_NODE_INNER_125 *n125 = (RT_NODE_INNER_125 *) b125; - fprintf(stderr, "%schunk 0x%X ->", - space, i); + appendStringInfo(buf, "%schunk 0x%X", + spaces.data, i); if (recurse) - RT_DUMP_NODE(RT_NODE_INNER_125_GET_CHILD(n125, i), - level + 1, recurse); + { + appendStringInfo(buf, "\n"); + RT_DUMP_NODE(tree, RT_NODE_INNER_125_GET_CHILD(n125, i), + level + 1, recurse, buf); + } else - fprintf(stderr, "\n"); + appendStringInfo(buf, " (skipped)\n"); } } break; } case RT_NODE_KIND_256: { + if (RT_NODE_IS_LEAF(node)) + { + RT_NODE_LEAF_256 *n256 = (RT_NODE_LEAF_256 *) node; + + appendStringInfo(buf, "%sisset-bitmap: ", spaces.data); + for (int i = 0; i < (RT_SLOT_IDX_LIMIT / BITS_PER_BYTE); i++) + appendStringInfo(buf, "%X ", ((uint8 *) n256->isset)[i]); + appendStringInfo(buf, "\n"); + } + for (int i = 0; i < RT_NODE_MAX_SLOTS; i++) { if (RT_NODE_IS_LEAF(node)) @@ -2169,8 +2196,8 @@ RT_DUMP_NODE(RT_PTR_LOCAL node, int level, bool recurse) if (!RT_NODE_LEAF_256_IS_CHUNK_USED(n256, i)) continue; - fprintf(stderr, "%schunk 0x%X value 0x" RT_UINT64_FORMAT_HEX "\n", - space, i, (uint64) RT_NODE_LEAF_256_GET_VALUE(n256, i)); + appendStringInfo(buf, "%schunk 0x%X\n", + spaces.data, i); } else { @@ -2179,14 +2206,17 @@ RT_DUMP_NODE(RT_PTR_LOCAL node, int level, bool recurse) if (!RT_NODE_INNER_256_IS_CHUNK_USED(n256, i)) continue; - fprintf(stderr, "%schunk 0x%X ->", - space, i); + appendStringInfo(buf, "%schunk 0x%X", + spaces.data, i); if (recurse) - RT_DUMP_NODE(RT_NODE_INNER_256_GET_CHILD(n256, i), level + 1, - recurse); + { + appendStringInfo(buf, "\n"); + RT_DUMP_NODE(tree, RT_NODE_INNER_256_GET_CHILD(n256, i), + level + 1, recurse, buf); + } else - fprintf(stderr, "\n"); + appendStringInfo(buf, " (skipped)\n"); } } break; @@ -2197,38 +2227,40 @@ RT_DUMP_NODE(RT_PTR_LOCAL node, int level, bool recurse) RT_SCOPE void RT_DUMP_SEARCH(RT_RADIX_TREE *tree, uint64 key) { + RT_PTR_ALLOC allocnode; RT_PTR_LOCAL node; + StringInfoData buf; int shift; int level = 0; - elog(NOTICE, "-----------------------------------------------------------"); - elog(NOTICE, "max_val = " UINT64_FORMAT "(0x" RT_UINT64_FORMAT_HEX ")", - tree->ctl->max_val, tree->ctl->max_val); + RT_STATS(tree); - if (!tree->ctl->root) + if (!RT_PTR_ALLOC_IS_VALID(tree->ctl->root)) { - elog(NOTICE, "tree is empty"); + fprintf(stderr, "empty tree\n"); return; } if (key > tree->ctl->max_val) { - elog(NOTICE, "key " UINT64_FORMAT "(0x" RT_UINT64_FORMAT_HEX ") is larger than max val", - key, key); + fprintf(stderr, "key " UINT64_FORMAT "(0x" RT_UINT64_FORMAT_HEX ") is larger than max val\n", + key, key); return; } - node = tree->ctl->root; - shift = tree->ctl->root->shift; + initStringInfo(&buf); + allocnode = tree->ctl->root; + node = RT_PTR_GET_LOCAL(tree, allocnode); + shift = node->shift; while (shift >= 0) { - RT_PTR_LOCAL child; + RT_PTR_ALLOC child; - RT_DUMP_NODE(node, level, false); + RT_DUMP_NODE(tree, allocnode, level, false, &buf); if (RT_NODE_IS_LEAF(node)) { - uint64 dummy; + RT_VALUE_TYPE dummy; /* We reached at a leaf node, find the corresponding slot */ RT_NODE_SEARCH_LEAF(node, key, &dummy); @@ -2239,30 +2271,33 @@ RT_DUMP_SEARCH(RT_RADIX_TREE *tree, uint64 key) if (!RT_NODE_SEARCH_INNER(node, key, &child)) break; - node = child; + allocnode = child; + node = RT_PTR_GET_LOCAL(tree, allocnode); shift -= RT_NODE_SPAN; level++; } + + fprintf(stderr, "%s", buf.data); } RT_SCOPE void RT_DUMP(RT_RADIX_TREE *tree) { + StringInfoData buf; - for (int i = 0; i < RT_SIZE_CLASS_COUNT; i++) - fprintf(stderr, "%s\tinner_size %zu\tleaf_size %zu\n", - RT_SIZE_CLASS_INFO[i].name, - RT_SIZE_CLASS_INFO[i].inner_size, - RT_SIZE_CLASS_INFO[i].leaf_size); - fprintf(stderr, "max_val = " UINT64_FORMAT "\n", tree->ctl->max_val); + RT_STATS(tree); - if (!tree->ctl->root) + if (!RT_PTR_ALLOC_IS_VALID(tree->ctl->root)) { fprintf(stderr, "empty tree\n"); return; } - RT_DUMP_NODE(tree->ctl->root, 0, true); + initStringInfo(&buf); + + RT_DUMP_NODE(tree, tree->ctl->root, 0, true, &buf); + + fprintf(stderr, "%s",buf.data); } #endif -- 2.31.1