This is an automated email from the ASF dual-hosted git repository. iilyak pushed a commit to branch couch-stats-resource-tracker-v3-rebase-http-2 in repository https://gitbox.apache.org/repos/asf/couchdb.git
commit 3c27b489e8515bb3d6a2bd89dab262c0d916498b Author: ILYA Khlopotov <[email protected]> AuthorDate: Fri Jun 27 09:42:12 2025 -0700 Split query function into query_{group_by|sort_by|count_by} --- .../src/couch_stats_resource_tracker.hrl | 2 +- src/couch_stats/src/csrt.erl | 64 ++++++++++++++++--- src/couch_stats/src/csrt_httpd.erl | 6 +- src/couch_stats/src/csrt_query.erl | 73 ++++++++++++---------- 4 files changed, 99 insertions(+), 46 deletions(-) diff --git a/src/couch_stats/src/couch_stats_resource_tracker.hrl b/src/couch_stats/src/couch_stats_resource_tracker.hrl index bf03a88b4..aba38c16e 100644 --- a/src/couch_stats/src/couch_stats_resource_tracker.hrl +++ b/src/couch_stats/src/couch_stats_resource_tracker.hrl @@ -191,7 +191,7 @@ -type tuple_of_field_values() :: tuple(). -type tuple_of_field_names() :: tuple(). --type query_options() :: #{aggregation => group_by | sort_by | count_by, limit => pos_integer()}. +-type query_options() :: #{limit => pos_integer()}. -type aggregation_key() :: tuple_of_field_names(). -type aggregation_values() :: tuple_of_field_values(). -type query_result() :: #{aggregation_key() => non_neg_integer()}. diff --git a/src/couch_stats/src/csrt.erl b/src/couch_stats/src/csrt.erl index 1864f9f44..1efdf5ec3 100644 --- a/src/couch_stats/src/csrt.erl +++ b/src/couch_stats/src/csrt.erl @@ -92,8 +92,12 @@ find_workers_by_pidref/1, group_by/2, group_by/3, - query/2, - query/4, + query_group_by/3, + query_group_by/4, + query_sort_by/3, + query_sort_by/4, + query_count_by/2, + query_count_by/3, query_matcher/1, query_matcher/2, sorted/1, @@ -495,21 +499,63 @@ query_matcher(MatcherName) -> query_matcher(MatcherName, Limit) -> csrt_query:query_matcher(MatcherName, Limit). --spec query(MatcherName :: string(), Keys :: binary() | rctx_field() | [binary()] | [rctx_field()]) -> +-spec query_group_by(MatcherName, AggregationKeys, ValueKey) -> {ok, query_result()} - | {error, any()}. -query(MatcherName, AggregationKeys) -> - csrt_query:query(MatcherName, AggregationKeys). + | {error, any()} +when + MatcherName :: string(), + AggregationKeys :: binary() | rctx_field() | [binary()] | [rctx_field()], + ValueKey :: binary() | rctx_field(). +query_group_by(MatcherName, AggregationKeys, ValueKey) -> + csrt_query:query_group_by(MatcherName, AggregationKeys, ValueKey, #{}). + +-spec query_group_by(MatcherName, AggregationKeys, ValueKey, Options :: query_options()) -> + {ok, query_result()} + | {error, any()} +when + MatcherName :: string(), + AggregationKeys :: binary() | rctx_field() | [binary()] | [rctx_field()], + ValueKey :: binary() | rctx_field(). +query_group_by(MatcherName, AggregationKeys, ValueKey, Options) -> + csrt_query:query_group_by(MatcherName, AggregationKeys, ValueKey, Options). + +-spec query_sort_by(MatcherName, AggregationKeys, ValueKey) -> + {ok, query_result()} + | {error, any()} +when + MatcherName :: string(), + AggregationKeys :: binary() | rctx_field() | [binary()] | [rctx_field()], + ValueKey :: binary() | rctx_field(). +query_sort_by(MatcherName, AggregationKeys, ValueKey) -> + csrt_query:query_sort_by(MatcherName, AggregationKeys, ValueKey, #{}). --spec query(MatcherName, AggregationKeys, ValueKey, Options :: query_options()) -> +-spec query_sort_by(MatcherName, AggregationKeys, ValueKey, Options :: query_options()) -> {ok, query_result()} | {error, any()} when MatcherName :: string(), AggregationKeys :: binary() | rctx_field() | [binary()] | [rctx_field()], ValueKey :: binary() | rctx_field(). -query(MatcherName, AggregationKeys, ValueKey, Options) -> - csrt_query:query(MatcherName, AggregationKeys, ValueKey, Options). +query_sort_by(MatcherName, AggregationKeys, ValueKey, Options) -> + csrt_query:query_sort_by(MatcherName, AggregationKeys, ValueKey, Options). + +-spec query_count_by(MatcherName, AggregationKeys) -> + {ok, query_result()} + | {error, any()} +when + MatcherName :: string(), + AggregationKeys :: binary() | rctx_field() | [binary()] | [rctx_field()]. +query_count_by(MatcherName, AggregationKeys) -> + csrt_query:query_count_by(MatcherName, AggregationKeys, #{}). + +-spec query_count_by(MatcherName, AggregationKeys, Options :: query_options()) -> + {ok, query_result()} + | {error, any()} +when + MatcherName :: string(), + AggregationKeys :: binary() | rctx_field() | [binary()] | [rctx_field()]. +query_count_by(MatcherName, AggregationKeys, Options) -> + csrt_query:query_count_by(MatcherName, AggregationKeys, Options). sorted(Map) -> csrt_query:sorted(Map). diff --git a/src/couch_stats/src/csrt_httpd.erl b/src/couch_stats/src/csrt_httpd.erl index 577651205..3fb4f0212 100644 --- a/src/couch_stats/src/csrt_httpd.erl +++ b/src/couch_stats/src/csrt_httpd.erl @@ -64,7 +64,7 @@ handle_resource_status_req(Req) -> handle_count_by(Req, MatcherName, CountBy) -> AggregationKeys = couch_util:get_value(<<"aggregate_keys">>, CountBy), - case csrt:query(MatcherName, AggregationKeys, undefined, #{aggregation => count_by}) of + case csrt:query_count_by(MatcherName, AggregationKeys) of {ok, Map} -> send_json(Req, {aggregation_result_to_json(Map)}); Else -> @@ -75,7 +75,7 @@ handle_count_by(Req, MatcherName, CountBy) -> handle_sort_by(Req, MatcherName, SortBy) -> AggregationKeys = couch_util:get_value(<<"aggregate_keys">>, SortBy), CounterKey = couch_util:get_value(<<"counter_key">>, SortBy), - case csrt:query(MatcherName, AggregationKeys, CounterKey, #{aggregation => sort_by}) of + case csrt:query_sort_by(MatcherName, AggregationKeys, CounterKey) of {ok, Map} -> send_json(Req, {aggregation_result_to_json(Map)}); Else -> @@ -86,7 +86,7 @@ handle_sort_by(Req, MatcherName, SortBy) -> handle_group_by(Req, MatcherName, GroupBy) -> AggregationKeys = couch_util:get_value(<<"aggregate_keys">>, GroupBy), CounterKey = couch_util:get_value(<<"counter_key">>, GroupBy), - case csrt:query(MatcherName, AggregationKeys, CounterKey, #{aggregation => group_by}) of + case csrt:query_group_by(MatcherName, AggregationKeys, CounterKey) of {ok, Map} -> send_json(Req, {aggregation_result_to_json(Map)}); Else -> diff --git a/src/couch_stats/src/csrt_query.erl b/src/couch_stats/src/csrt_query.erl index f96e3fc65..bacc44db3 100644 --- a/src/couch_stats/src/csrt_query.erl +++ b/src/couch_stats/src/csrt_query.erl @@ -34,8 +34,9 @@ find_workers_by_pidref/1, group_by/3, group_by/4, - query/2, - query/4, + query_group_by/4, + query_sort_by/4, + query_count_by/3, query_matcher/1, query_matcher/2, query_matcher_rows/1, @@ -322,14 +323,27 @@ get_matcher(MatcherName) -> {ok, Matcher} end. --spec query(MatcherName :: string(), Keys :: binary() | rctx_field() | [binary()] | [rctx_field()]) -> +-spec query_group_by(MatcherName, AggregationKeys, ValueKey, Options :: query_options()) -> {ok, query_result()} - | {error, any()}. + | {error, any()} +when + MatcherName :: string(), + AggregationKeys :: binary() | rctx_field() | [binary()] | [rctx_field()], + ValueKey :: binary() | rctx_field(). %% {ok, #{{<<"adm">>,<<"bench-yktbb3as46rzffea">>} => 2}} -query(MatcherName, AggregationKeys) -> - query(MatcherName, AggregationKeys, undefined, #{}). +query_group_by(MatcherName, AggregationKeys, ValueKey, Options) -> + AggregationKey = parse_key(AggregationKeys), + VKey = parse_key(ValueKey), + Limit = maps:get(limit, Options, query_limit()), + maybe + ok ?= validate_not_error(AggregationKey), + ok ?= validate_not_error(VKey), + ok ?= validate_limit(Limit), + {ok, Matcher} ?= get_matcher(MatcherName), + group_by(Matcher, AggregationKey, VKey) + end. --spec query(MatcherName, AggregationKeys, ValueKey, Options :: query_options()) -> +-spec query_sort_by(MatcherName, AggregationKeys, ValueKey, Options :: query_options()) -> {ok, query_result()} | {error, any()} when @@ -337,29 +351,33 @@ when AggregationKeys :: binary() | rctx_field() | [binary()] | [rctx_field()], ValueKey :: binary() | rctx_field(). %% {ok, #{{<<"adm">>,<<"bench-yktbb3as46rzffea">>} => 2}} -query(MatcherName, AggregationKeys, ValueKey, Options) -> +query_sort_by(MatcherName, AggregationKeys, ValueKey, Options) -> AggregationKey = parse_key(AggregationKeys), VKey = parse_key(ValueKey), Limit = maps:get(limit, Options, query_limit()), - Aggregation = maps:get(aggregation, Options, none), maybe ok ?= validate_not_error(AggregationKey), ok ?= validate_not_error(VKey), ok ?= validate_limit(Limit), - ok ?= validate_aggregation(Aggregation), {ok, Matcher} ?= get_matcher(MatcherName), - case Aggregation of - group_by -> - group_by(Matcher, AggregationKey, VKey); - sort_by -> - sort_by(Matcher, AggregationKey, VKey); - count_by when VKey == undefined -> - count_by(Matcher, AggregationKey); - count_by -> - {error, {extra_argument, value_key}}; - none -> - query_matcher_rows(Matcher, Limit) - end + sort_by(Matcher, AggregationKey, VKey) + end. + +-spec query_count_by(MatcherName, AggregationKeys, Options :: query_options()) -> + {ok, query_result()} + | {error, any()} +when + MatcherName :: string(), + AggregationKeys :: binary() | rctx_field() | [binary()] | [rctx_field()]. +%% {ok, #{{<<"adm">>,<<"bench-yktbb3as46rzffea">>} => 2}} +query_count_by(MatcherName, AggregationKeys, Options) -> + AggregationKey = parse_key(AggregationKeys), + Limit = maps:get(limit, Options, query_limit()), + maybe + ok ?= validate_not_error(AggregationKey), + ok ?= validate_limit(Limit), + {ok, Matcher} ?= get_matcher(MatcherName), + count_by(Matcher, AggregationKey) end. validate_not_error({error, _} = Error) -> @@ -380,17 +398,6 @@ validate_limit(Limit) when is_integer(Limit) -> validate_limit(Limit) -> {error, {invalid_limit, Limit}}. -validate_aggregation(none) -> - ok; -validate_aggregation(group_by) -> - ok; -validate_aggregation(sort_by) -> - ok; -validate_aggregation(count_by) -> - ok; -validate_aggregation(Other) -> - {error, {invalid_aggregation, Other}}. - -spec parse_key(Keys :: binary() | atom() | [binary()] | [atom()]) -> [rctx_field()] | throw({bad_request, Reason :: binary()}).
