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 2022/08/08 22:48:37 UTC

[couchdb] 01/03: Cost counting hackery

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

chewbranca pushed a commit to branch cost-counting
in repository https://gitbox.apache.org/repos/asf/couchdb.git

commit 94dfaac5a7d09a39098f3565d8ec5da26d768c62
Author: Russell Branca <ch...@apache.org>
AuthorDate: Mon Jul 18 16:26:00 2022 -0700

    Cost counting hackery
---
 src/couch/src/couch_cost.erl  | 42 ++++++++++++++++++++++++++++++++++++++++++
 src/couch/src/couch_db.erl    |  1 +
 src/fabric/src/fabric_rpc.erl |  2 ++
 src/rexi/src/rexi.erl         |  6 ++++--
 src/rexi/src/rexi_utils.erl   | 20 ++++++++++++++++++++
 5 files changed, 69 insertions(+), 2 deletions(-)

diff --git a/src/couch/src/couch_cost.erl b/src/couch/src/couch_cost.erl
new file mode 100644
index 000000000..b37f34381
--- /dev/null
+++ b/src/couch/src/couch_cost.erl
@@ -0,0 +1,42 @@
+-module(couch_cost).
+
+-export([
+    inc_doc/0, inc_doc/1, inc_doc/2,
+    inc_ioq/0, inc_ioq/1, inc_ioq/2%%,
+    %%io_bytes_read/1, io_bytes_read/2,
+    %%io_bytes_written/1, io_bytes_written/2,
+    %%inc_js_evals/0, inc_js_evals/1, inc_js_evals/2
+]).
+
+-export([
+    get_cost/0
+]).
+
+-record(cost, {
+    docs_read = 0,
+    ioq_calls = 0,
+    io_bytes_read = 0,
+    io_bytes_written = 0,
+    js_evals = 0
+}).
+
+get_cost() ->
+    case get(cost_accounting_context) of
+        undefined ->
+            Cost = #cost{},
+            update_cost(Cost),
+            Cost;
+        #cost{}=Cost ->
+            Cost
+    end.
+
+update_cost(#cost{}=Cost) ->
+    put(cost_accounting_context, Cost).
+
+inc_doc() -> inc_doc(1).
+inc_doc(N) -> inc_doc(N, get_cost()).
+inc_doc(N, #cost{docs_read=DR0}=Cost) -> update_cost(Cost#cost{docs_read=DR0+N}).
+
+inc_ioq() -> inc_ioq(1).
+inc_ioq(N) -> inc_ioq(N, get_cost()).
+inc_ioq(N, #cost{ioq_calls=IOQ0}=Cost) -> update_cost(Cost#cost{ioq_calls=IOQ0+N}).
diff --git a/src/couch/src/couch_db.erl b/src/couch/src/couch_db.erl
index c7f1c8b5f..13c8894be 100644
--- a/src/couch/src/couch_db.erl
+++ b/src/couch/src/couch_db.erl
@@ -295,6 +295,7 @@ open_doc(Db, IdOrDocInfo) ->
 
 open_doc(Db, Id, Options) ->
     increment_stat(Db, [couchdb, database_reads]),
+    couch_cost:inc_doc(),
     case open_doc_int(Db, Id, Options) of
         {ok, #doc{deleted = true} = Doc} ->
             case lists:member(deleted, Options) of
diff --git a/src/fabric/src/fabric_rpc.erl b/src/fabric/src/fabric_rpc.erl
index 5db84458a..253294280 100644
--- a/src/fabric/src/fabric_rpc.erl
+++ b/src/fabric/src/fabric_rpc.erl
@@ -491,6 +491,8 @@ view_cb({meta, Meta}, Acc) ->
     ok = rexi:stream2({meta, Meta}),
     {ok, Acc};
 view_cb({row, Row}, Acc) ->
+    %% TODO: distinguish between rows and docs
+    couch_cost:inc_doc(),
     % Adding another row
     ViewRow = #view_row{
         id = couch_util:get_value(id, Row),
diff --git a/src/rexi/src/rexi.erl b/src/rexi/src/rexi.erl
index 77830996e..ffa5b2713 100644
--- a/src/rexi/src/rexi.erl
+++ b/src/rexi/src/rexi.erl
@@ -129,7 +129,8 @@ async_server_call(Server, Caller, Request) ->
 -spec reply(any()) -> any().
 reply(Reply) ->
     {Caller, Ref} = get(rexi_from),
-    erlang:send(Caller, {Ref, Reply}).
+    Cost = couch_cost:get_cost(),
+    erlang:send(Caller, {Ref,Reply,{cost,Cost}}).
 
 %% @equiv sync_reply(Reply, 300000)
 sync_reply(Reply) ->
@@ -214,7 +215,8 @@ stream(Msg, Limit, Timeout) ->
         {ok, Count} ->
             put(rexi_unacked, Count + 1),
             {Caller, Ref} = get(rexi_from),
-            erlang:send(Caller, {Ref, self(), Msg}),
+            Cost = couch_cost:get_cost(),
+            erlang:send(Caller, {Ref, self(), Msg, {cost, Cost}}),
             ok
     catch
         throw:timeout ->
diff --git a/src/rexi/src/rexi_utils.erl b/src/rexi/src/rexi_utils.erl
index d59c5ea0f..ae05bf7a6 100644
--- a/src/rexi/src/rexi_utils.erl
+++ b/src/rexi/src/rexi_utils.erl
@@ -83,7 +83,26 @@ process_message(RefList, Keypos, Fun, Acc0, TimeoutRef, PerMsgTO) ->
             end;
         {rexi, '$rexi_ping'} ->
             {ok, Acc0};
+        {Ref, Msg, {cost,Cost}} ->
+            io:format("GOT COST: ~p -- ~p~n", [Cost, Msg]),
+            case lists:keyfind(Ref, Keypos, RefList) of
+            false ->
+                % this was some non-matching message which we will ignore
+                {ok, Acc0};
+            Worker ->
+                Fun(Msg, Worker, Acc0)
+            end;
+        {Ref, From, Msg, {cost,Cost}} ->
+            %%io:format("GOT COST: ~p~n", [Cost]),
+            io:format("GOT COST: ~p -- ~p~n", [Cost, Msg]),
+            case lists:keyfind(Ref, Keypos, RefList) of
+            false ->
+                {ok, Acc0};
+            Worker ->
+                Fun(Msg, {Worker, From}, Acc0)
+            end;
         {Ref, Msg} ->
+            io:format("GOT NON COST MSG: ~p~n", [Msg]),
             case lists:keyfind(Ref, Keypos, RefList) of
                 false ->
                     % this was some non-matching message which we will ignore
@@ -92,6 +111,7 @@ process_message(RefList, Keypos, Fun, Acc0, TimeoutRef, PerMsgTO) ->
                     Fun(Msg, Worker, Acc0)
             end;
         {Ref, From, Msg} ->
+            io:format("GOT NON COST MSG: ~p~n", [Msg]),
             case lists:keyfind(Ref, Keypos, RefList) of
                 false ->
                     {ok, Acc0};