Implement deltas server, replacing beam_stats_state.
[beam_stats.git] / src / beam_stats_delta.erl
diff --git a/src/beam_stats_delta.erl b/src/beam_stats_delta.erl
new file mode 100644 (file)
index 0000000..d563507
--- /dev/null
@@ -0,0 +1,85 @@
+-module(beam_stats_delta).
+
+-export_type(
+    [ t/0
+    ]).
+
+-export(
+    [ start/0
+    , stop/1
+    , of_context_switches/1
+    , of_io/1
+    ]).
+
+-record(?MODULE,
+    { erlang_statistics :: ets:tid()
+    }).
+
+-define(T, #?MODULE).
+
+-opaque t()  ::
+    ?T{}.
+
+-spec start() ->
+    t().
+start() ->
+    Options =
+        [ set
+        , public
+        ],
+    ?T
+    { erlang_statistics = ets:new(beam_stats_delta_erlang_statistics, Options)
+    }.
+
+-spec stop(t()) ->
+    {}.
+stop(?T
+    { erlang_statistics = TidErlangStatistics
+    }
+) ->
+    true = ets:delete(TidErlangStatistics),
+    {}.
+
+-spec of_context_switches(t()) ->
+    non_neg_integer().
+of_context_switches(?T{erlang_statistics=Table}) ->
+    Key = context_switches,
+    {Current, 0} = beam_stats_source:erlang_statistics(Key),
+    delta(Table, Key, Current).
+
+-spec of_io(t()) ->
+    { {io_bytes_in  , non_neg_integer()}
+    , {io_bytes_out , non_neg_integer()}
+    }.
+of_io(?T{erlang_statistics=Table}) ->
+    Key = io,
+    { {input  , CurrentIn}
+    , {output , CurrentOut}
+    } = beam_stats_source:erlang_statistics(Key),
+    DeltaIn  = delta(Table, io_bytes_in , CurrentIn),
+    DeltaOut = delta(Table, io_bytes_out, CurrentOut),
+    { {io_bytes_in  , DeltaIn}
+    , {io_bytes_out , DeltaOut}
+    }.
+
+-spec delta(ets:tid(), atom(), non_neg_integer()) ->
+    non_neg_integer().
+delta(Table, Key, CurrentTotal) ->
+    PreviousTotalOpt = find(Table, Key),
+    PreviousTotal = hope_option:get(PreviousTotalOpt, 0),
+    save(Table, Key, CurrentTotal),
+    CurrentTotal - PreviousTotal.
+
+-spec find(ets:tid(), term()) ->
+    hope_option:t(term()).
+find(Table, K) ->
+    case ets:lookup(Table, K)
+    of  []       -> none
+    ;   [{K, V}] -> {some, V}
+    end.
+
+-spec save(ets:tid(), term(), term()) ->
+    {}.
+save(Table, K, V) ->
+    true = ets:insert(Table, {K, V}),
+    {}.
This page took 0.031148 seconds and 4 git commands to generate.