You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by ch...@apache.org on 2024/02/12 23:36:11 UTC

(couchdb) 10/28: Add unsafe_foldl for perf testing

This is an automated email from the ASF dual-hosted git repository.

chewbranca pushed a commit to branch couch-stats-resource-tracker-rebase
in repository https://gitbox.apache.org/repos/asf/couchdb.git

commit 0fd93a50a7364f222115b0b6cd6835ab7a0f237a
Author: Russell Branca <ch...@apache.org>
AuthorDate: Wed Nov 15 16:03:20 2023 -0800

    Add unsafe_foldl for perf testing
---
 .../src/couch_stats_resource_tracker.erl           | 43 +++++++++++++++++-----
 src/fabric/src/fabric_rpc.erl                      |  2 +-
 2 files changed, 35 insertions(+), 10 deletions(-)

diff --git a/src/couch_stats/src/couch_stats_resource_tracker.erl b/src/couch_stats/src/couch_stats_resource_tracker.erl
index 0a5b2e335..d2dd4406c 100644
--- a/src/couch_stats/src/couch_stats_resource_tracker.erl
+++ b/src/couch_stats/src/couch_stats_resource_tracker.erl
@@ -53,10 +53,13 @@
     count_by/1,
     group_by/2,
     group_by/3,
+    group_by/4,
     sorted/1,
     sorted_by/1,
     sorted_by/2,
-    sorted_by/3
+    sorted_by/3,
+
+    unsafe_foldl/3
 ]).
 
 -export([
@@ -393,20 +396,24 @@ group_by(KeyFun, ValFun) ->
     group_by(KeyFun, ValFun, fun erlang:'+'/2).
 
 
+group_by(KeyFun, ValFun, AggFun) ->
+    group_by(KeyFun, ValFun, AggFun, fun ets:foldl/3).
+
+
 %% eg: group_by(mfa, docs_read).
 %% eg: group_by(fun(#rctx{mfa=MFA,docs_read=DR}) -> {MFA, DR} end, ioq_calls).
 %% eg: ^^ or: group_by([mfa, docs_read], ioq_calls).
 %% eg: group_by([username, dbname, mfa], docs_read).
 %% eg: group_by([username, dbname, mfa], ioq_calls).
 %% eg: group_by([username, dbname, mfa], js_filters).
-group_by(KeyL, ValFun, AggFun) when is_list(KeyL) ->
+group_by(KeyL, ValFun, AggFun, Fold) when is_list(KeyL) ->
     KeyFun = fun(Ele) -> list_to_tuple([field(Ele, Key) || Key <- KeyL]) end,
-    group_by(KeyFun, ValFun, AggFun);
-group_by(Key, ValFun, AggFun) when is_atom(Key) ->
-    group_by(curry_field(Key), ValFun, AggFun);
-group_by(KeyFun, Val, AggFun) when is_atom(Val) ->
-    group_by(KeyFun, curry_field(Val), AggFun);
-group_by(KeyFun, ValFun, AggFun) ->
+    group_by(KeyFun, ValFun, AggFun, Fold);
+group_by(Key, ValFun, AggFun, Fold) when is_atom(Key) ->
+    group_by(curry_field(Key), ValFun, AggFun, Fold);
+group_by(KeyFun, Val, AggFun, Fold) when is_atom(Val) ->
+    group_by(KeyFun, curry_field(Val), AggFun, Fold);
+group_by(KeyFun, ValFun, AggFun, Fold) ->
     FoldFun = fun(Ele, Acc) ->
         Key = KeyFun(Ele),
         Val = ValFun(Ele),
@@ -414,7 +421,8 @@ group_by(KeyFun, ValFun, AggFun) ->
         NewVal = AggFun(CurrVal, Val),
         maps:put(Key, NewVal, Acc)
     end,
-    ets:foldl(FoldFun, #{}, ?MODULE).
+    Fold(FoldFun, #{}, ?MODULE).
+
 
 sorted(Map) when is_map(Map) ->
     lists:sort(fun({_K1, A}, {_K2, B}) -> B < A end, maps:to_list(Map)).
@@ -924,3 +932,20 @@ log_process_lifetime_report(PidRef) ->
     %% TODO: catch error out of here, report crashes on depth>1 json
     io:format("CSRT RCTX: ~p~n", [to_flat_json(Rctx)]),
     couch_log:report("csrt-pid-usage-lifetime", to_flat_json(Rctx)).
+
+
+%% Reimplementation of: https://github.com/erlang/otp/blob/b2ee4fc9a0b81a139dad2033e9b2bfc178146886/lib/stdlib/src/ets.erl#L633-L658
+%% with wrapping of ets:safe_fixtable/2 removed
+unsafe_foldl(F, Accu, T) ->
+    First = ets:first(T),
+    do_foldl(F, Accu, First, T).
+
+do_foldl(F, Accu0, Key, T) ->
+    case Key of
+        '$end_of_table' ->
+            Accu0;
+        _ ->
+            do_foldl(F,
+                lists:foldl(F, Accu0, ets:lookup(T, Key)),
+                ets:next(T, Key), T)
+    end.
diff --git a/src/fabric/src/fabric_rpc.erl b/src/fabric/src/fabric_rpc.erl
index bfd039aad..2c8ba1654 100644
--- a/src/fabric/src/fabric_rpc.erl
+++ b/src/fabric/src/fabric_rpc.erl
@@ -331,7 +331,7 @@ reset_validation_funs(DbName) ->
 
 open_shard(Name, Opts) ->
     set_io_priority(Name, Opts),
-    couch_stats_resource_tracker:set_context_dbname(DbName),
+    couch_stats_resource_tracker:set_context_dbname(Name),
     try
         rexi:reply(mem3_util:get_or_create_db(Name, Opts))
     catch