From 6b2805e0a931e12660bcdd8345835f81ab3b81bb Mon Sep 17 00:00:00 2001 From: jeesup0103 Date: Wed, 8 Jan 2025 14:33:52 +0900 Subject: [PATCH] INTERNAL: Change tot_elem_cnt to subtree element count in set --- engines/default/coll_set.c | 36 ++++++++++++++++++++++++++---------- engines/default/item_base.h | 2 +- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/engines/default/coll_set.c b/engines/default/coll_set.c index cef3774ae..bafb624a3 100644 --- a/engines/default/coll_set.c +++ b/engines/default/coll_set.c @@ -219,7 +219,6 @@ static void do_set_node_link(set_meta_info *info, par_node->htab[par_hidx] = node; par_node->hcnt[par_hidx] = -1; /* child hash node */ - par_node->tot_elem_cnt -= num_found; par_node->tot_hash_cnt += 1; } @@ -263,12 +262,10 @@ static void do_set_node_unlink(set_meta_info *info, assert(node->hcnt[hidx] == 0); } } - assert(fcnt == node->tot_elem_cnt); node->tot_elem_cnt = 0; par_node->htab[par_hidx] = head; par_node->hcnt[par_hidx] = fcnt; - par_node->tot_elem_cnt += fcnt; par_node->tot_hash_cnt -= 1; } @@ -287,12 +284,15 @@ static ENGINE_ERROR_CODE do_set_elem_link(set_meta_info *info, set_elem_item *el assert(info->root != NULL); set_hash_node *node = info->root; set_elem_item *find; + set_hash_node *parents[256]; int hidx = -1; + int cur_depth = 0; /* set hash value */ elem->hval = genhash_string_hash(elem->value, elem->nbytes); while (node != NULL) { + parents[cur_depth++] = node; hidx = SET_GET_HASHIDX(elem->hval, node->hdepth); if (node->hcnt[hidx] >= 0) /* set element hash chain */ break; @@ -318,6 +318,7 @@ static ENGINE_ERROR_CODE do_set_elem_link(set_meta_info *info, set_elem_item *el do_set_node_link(info, node, hidx, n_node); node = n_node; + parents[cur_depth++] = node; hidx = SET_GET_HASHIDX(elem->hval, node->hdepth); } @@ -325,6 +326,8 @@ static ENGINE_ERROR_CODE do_set_elem_link(set_meta_info *info, set_elem_item *el node->htab[hidx] = elem; node->hcnt[hidx] += 1; node->tot_elem_cnt += 1; + for (int i = 0; i < cur_depth-1; i++) + parents[i]->tot_elem_cnt++; info->ccnt++; @@ -396,10 +399,16 @@ static ENGINE_ERROR_CODE do_set_elem_traverse_delete(set_meta_info *info, set_ha set_hash_node *child_node = node->htab[hidx]; ret = do_set_elem_traverse_delete(info, child_node, hval, val, vlen); if (ret == ENGINE_SUCCESS) { - if (child_node->tot_hash_cnt == 0 && - child_node->tot_elem_cnt < (SET_MAX_HASHCHAIN_SIZE/2)) { - do_set_node_unlink(info, node, hidx); + if (child_node->tot_hash_cnt == 0) { + uint32_t child_elem_cnt = 0; + for (int i = 0; i < SET_HASHTAB_SIZE; i++) { + if (child_node->hcnt[i] > 0) + child_elem_cnt += child_node->hcnt[i]; + } + if (child_elem_cnt < (SET_MAX_HASHCHAIN_SIZE/2)) + do_set_node_unlink(info, node, hidx); } + node->tot_elem_cnt--; } } else { ret = ENGINE_ELEM_ENOENT; @@ -497,13 +506,20 @@ static int do_set_elem_traverse_dfs(set_meta_info *info, set_hash_node *node, if (node->hcnt[hidx] == -1) { set_hash_node *child_node = (set_hash_node *)node->htab[hidx]; int rcnt = (count > 0 ? (count - fcnt) : 0); - fcnt += do_set_elem_traverse_dfs(info, child_node, rcnt, delete, + int ecnt = do_set_elem_traverse_dfs(info, child_node, rcnt, delete, (elem_array==NULL ? NULL : &elem_array[fcnt])); + fcnt += ecnt; if (delete) { - if (child_node->tot_hash_cnt == 0 && - child_node->tot_elem_cnt < (SET_MAX_HASHCHAIN_SIZE/2)) { - do_set_node_unlink(info, node, hidx); + if (child_node->tot_hash_cnt == 0) { + uint32_t child_elem_cnt = 0; + for (int i = 0; i < SET_HASHTAB_SIZE; i++) { + if (child_node->hcnt[i] > 0) + child_elem_cnt += child_node->hcnt[i]; + } + if (child_elem_cnt < (SET_MAX_HASHCHAIN_SIZE/2)) + do_set_node_unlink(info, node, hidx); } + node->tot_elem_cnt -= ecnt; } } else if (node->hcnt[hidx] > 0) { set_elem_item *elem = node->htab[hidx]; diff --git a/engines/default/item_base.h b/engines/default/item_base.h index f12bcab81..99c557a36 100644 --- a/engines/default/item_base.h +++ b/engines/default/item_base.h @@ -236,7 +236,7 @@ typedef struct _set_hash_node { uint16_t refcount; uint8_t slabs_clsid; /* which slab class we're in */ uint8_t hdepth; - uint16_t tot_elem_cnt; + uint32_t tot_elem_cnt; uint16_t tot_hash_cnt; int16_t hcnt[SET_HASHTAB_SIZE]; void *htab[SET_HASHTAB_SIZE];