From 67776cc58cc5c2288f7453b89f86caa54d8be433 Mon Sep 17 00:00:00 2001 From: hxy7yx <1595670487@qq.com> Date: Mon, 15 Jul 2024 14:01:18 +0800 Subject: [PATCH] refactor(read paginate): optimize efficiency without filtering errors --- include/neuron/msg.h | 1 + plugins/restful/rw_handle.c | 111 +++++++++++++++++++++++------------- src/adapter/driver/driver.c | 11 +++- src/base/group.c | 47 +++++++++++++++ src/base/group.h | 4 ++ 5 files changed, 132 insertions(+), 42 deletions(-) diff --git a/include/neuron/msg.h b/include/neuron/msg.h index 8ffbe143..6617c904 100644 --- a/include/neuron/msg.h +++ b/include/neuron/msg.h @@ -933,6 +933,7 @@ typedef struct { int current_page; int page_size; bool is_error; + int total_count; // tags count without pagination UT_array *tags; // neu_resp_tag_value_meta_paginate_t } neu_resp_read_group_paginate_t; diff --git a/plugins/restful/rw_handle.c b/plugins/restful/rw_handle.c index 2a810949..5182e9ff 100644 --- a/plugins/restful/rw_handle.c +++ b/plugins/restful/rw_handle.c @@ -380,8 +380,9 @@ void handle_read_resp(nng_aio *aio, neu_resp_read_group_t *resp) void handle_read_paginate_resp(nng_aio * aio, neu_resp_read_group_paginate_t *resp) { - neu_json_read_paginate_resp_t api_res = { 0 }; - char * result = NULL; + neu_json_read_paginate_resp_t api_res = { 0 }; + char * result = NULL; + unsigned int total_tags = resp->total_count; if (resp->is_error) { UT_array *filtered_tags; @@ -419,51 +420,79 @@ void handle_read_paginate_resp(nng_aio * aio, utarray_free(resp->tags); resp->tags = filtered_tags; - } + total_tags = utarray_len(resp->tags); - unsigned int total_tags = utarray_len(resp->tags); + if (resp->current_page > 0 && resp->page_size > 0) { + unsigned int start_index = + (resp->current_page - 1) * resp->page_size; + unsigned int end_index = start_index + resp->page_size; + + if (start_index >= total_tags) { + api_res.n_tag = 0; + api_res.tags = + calloc(1, sizeof(neu_json_read_paginate_resp_tag_t)); + } else { + if (end_index > total_tags) { + end_index = total_tags; + } + + api_res.n_tag = end_index - start_index; + api_res.tags = calloc( + api_res.n_tag, sizeof(neu_json_read_paginate_resp_tag_t)); + + for (unsigned int i = start_index; i < end_index; i++) { + neu_resp_tag_value_meta_paginate_t *tag_value = + (neu_resp_tag_value_meta_paginate_t *) utarray_eltptr( + resp->tags, i); + neu_tag_value_to_json_paginate( + tag_value, &api_res.tags[i - start_index]); + } + } + } else { + api_res.n_tag = total_tags; + api_res.tags = calloc(api_res.n_tag, + sizeof(neu_json_read_paginate_resp_tag_t)); + int index = 0; + + utarray_foreach(resp->tags, neu_resp_tag_value_meta_paginate_t *, + tag_value) + { + neu_tag_value_to_json_paginate(tag_value, + &api_res.tags[index++]); + } + } + } else { + + if (resp->current_page > 0 && resp->page_size > 0) { + api_res.n_tag = utarray_len(resp->tags); + api_res.tags = calloc(api_res.n_tag, + sizeof(neu_json_read_paginate_resp_tag_t)); + int index = 0; + utarray_foreach(resp->tags, neu_resp_tag_value_meta_paginate_t *, + tag_value) + { + neu_tag_value_to_json_paginate(tag_value, + &api_res.tags[index++]); + } + } else { + api_res.n_tag = total_tags; + api_res.tags = calloc(api_res.n_tag, + sizeof(neu_json_read_paginate_resp_tag_t)); + int index = 0; + + utarray_foreach(resp->tags, neu_resp_tag_value_meta_paginate_t *, + tag_value) + { + neu_tag_value_to_json_paginate(tag_value, + &api_res.tags[index++]); + } + } + } api_res.meta.current_page = resp->current_page; api_res.meta.page_size = resp->page_size; api_res.meta.total = total_tags; - if (resp->current_page > 0 && resp->page_size > 0) { - unsigned int start_index = (resp->current_page - 1) * resp->page_size; - unsigned int end_index = start_index + resp->page_size; - - if (start_index >= total_tags) { - api_res.n_tag = 0; - api_res.tags = calloc(1, sizeof(neu_json_read_paginate_resp_tag_t)); - } else { - if (end_index > total_tags) { - end_index = total_tags; - } - - api_res.n_tag = end_index - start_index; - api_res.tags = calloc(api_res.n_tag, - sizeof(neu_json_read_paginate_resp_tag_t)); - - for (unsigned int i = start_index; i < end_index; i++) { - neu_resp_tag_value_meta_paginate_t *tag_value = - (neu_resp_tag_value_meta_paginate_t *) utarray_eltptr( - resp->tags, i); - neu_tag_value_to_json_paginate(tag_value, - &api_res.tags[i - start_index]); - } - } - } else { - api_res.n_tag = total_tags; - api_res.tags = - calloc(api_res.n_tag, sizeof(neu_json_read_paginate_resp_tag_t)); - int index = 0; - - utarray_foreach(resp->tags, neu_resp_tag_value_meta_paginate_t *, - tag_value) - { - neu_tag_value_to_json_paginate(tag_value, &api_res.tags[index++]); - } - } - neu_json_encode_by_fn(&api_res, neu_json_encode_read_paginate_resp, &result); diff --git a/src/adapter/driver/driver.c b/src/adapter/driver/driver.c index 5d25bdda..ea87316e 100644 --- a/src/adapter/driver/driver.c +++ b/src/adapter/driver/driver.c @@ -565,7 +565,16 @@ void neu_adapter_driver_read_group_paginate(neu_adapter_driver_t *driver, neu_resp_read_group_paginate_t resp = { 0 }; neu_group_t * group = g->group; - UT_array *tags = neu_group_query_read_tag(group, cmd->name, cmd->desc); + UT_array * tags; + + if (cmd->is_error != true && cmd->current_page > 0 && cmd->page_size > 0) { + tags = neu_group_query_read_tag_paginate( + group, cmd->name, cmd->desc, cmd->current_page, cmd->page_size, + &resp.total_count); + } else { + tags = neu_group_query_read_tag(group, cmd->name, cmd->desc); + resp.total_count = utarray_len(tags); + } utarray_new(resp.tags, neu_resp_tag_value_meta_paginate_icd()); diff --git a/src/base/group.c b/src/base/group.c index a06ad639..344edd0b 100644 --- a/src/base/group.c +++ b/src/base/group.c @@ -209,6 +209,34 @@ filter_tags(tag_elem_t *tags, return array; } +static inline UT_array *filter_tags_by_page( + tag_elem_t *tags, bool (*predicate)(const neu_datatag_t *, void *data), + void *data, int current_page, int page_size, int *total_count) +{ + tag_elem_t *el = NULL, *tmp = NULL; + UT_array * array = NULL; + int count = 0; + int start_index = (current_page - 1) * page_size; + int end_index = start_index + page_size; + + utarray_new(array, neu_tag_get_icd()); + HASH_ITER(hh, tags, el, tmp) + { + if (predicate(el->tag, data)) { + if (count >= start_index && count < end_index) { + utarray_push_back(array, el->tag); + } + count++; + } + } + + if (total_count) { + *total_count = count; + } + + return array; +} + static inline bool is_readable(const neu_datatag_t *tag, void *data) { (void) data; @@ -275,6 +303,25 @@ UT_array *neu_group_query_read_tag(neu_group_t *group, const char *name, return array; } +UT_array *neu_group_query_read_tag_paginate(neu_group_t *group, + const char *name, const char *desc, + int current_page, int page_size, + int *total_count) +{ + UT_array * array = NULL; + struct query q = { + .name = (char *) name, + .desc = (char *) desc, + }; + + pthread_mutex_lock(&group->mtx); + array = filter_tags_by_page(group->tags, is_readable_and_match_query, &q, + current_page, page_size, total_count); + pthread_mutex_unlock(&group->mtx); + + return array; +} + UT_array *neu_group_get_read_tag(neu_group_t *group) { UT_array *array = NULL; diff --git a/src/base/group.h b/src/base/group.h index a5ed41c4..1164f504 100644 --- a/src/base/group.h +++ b/src/base/group.h @@ -43,6 +43,10 @@ UT_array * neu_group_query_tag(neu_group_t *group, const char *name); UT_array * neu_group_get_read_tag(neu_group_t *group); UT_array * neu_group_query_read_tag(neu_group_t *group, const char *name, const char *desc); +UT_array * neu_group_query_read_tag_paginate(neu_group_t *group, + const char *name, const char *desc, + int current_page, int page_size, + int *total_count); uint16_t neu_group_tag_size(const neu_group_t *group); neu_datatag_t *neu_group_find_tag(neu_group_t *group, const char *tag); void neu_group_split_static_tags(neu_group_t *group, UT_array **static_tags,