aboutsummaryrefslogtreecommitdiffstats
path: root/lib/stdlib
diff options
context:
space:
mode:
authorRaimo Niskanen <[email protected]>2018-10-29 20:31:48 +0100
committerRaimo Niskanen <[email protected]>2018-11-16 14:40:43 +0100
commit6f0a9a08023ea4825dbdcefae0d976b08566729a (patch)
treec313d8f4e862f97c39799c328630601db326067b /lib/stdlib
parent785e6c73a586b0978953bf2457fab514c9dc8207 (diff)
downloadotp-6f0a9a08023ea4825dbdcefae0d976b08566729a.tar.gz
otp-6f0a9a08023ea4825dbdcefae0d976b08566729a.tar.bz2
otp-6f0a9a08023ea4825dbdcefae0d976b08566729a.zip
Optimize sys:log
Diffstat (limited to 'lib/stdlib')
-rw-r--r--lib/stdlib/src/sys.erl68
1 files changed, 56 insertions, 12 deletions
diff --git a/lib/stdlib/src/sys.erl b/lib/stdlib/src/sys.erl
index 8f654841b6..7b161460b0 100644
--- a/lib/stdlib/src/sys.erl
+++ b/lib/stdlib/src/sys.erl
@@ -595,9 +595,6 @@ stat({out, _Msg, _To}, {Time, Reds, In, Out}) -> {Time, Reds, In, Out+1};
stat({out, _Msg, _To, _State}, {Time, Reds, In, Out}) -> {Time, Reds, In, Out+1};
stat(_, StatData) -> StatData.
-trim(N, LogData) ->
- lists:sublist(LogData, 1, N-1).
-
%%-----------------------------------------------------------------
%% Debug structure manipulating functions
%%-----------------------------------------------------------------
@@ -640,22 +637,69 @@ close_log_file(Debug) ->
%%-----------------------------------------------------------------
%% Keep the last N Log functions
%%-----------------------------------------------------------------
+%%
+%% Streamlined Okasaki queue as base for "keep the last N" log.
+%%
+%% To the reverse list head we cons new items.
+%% The forward list contains elements in insertion order,
+%% so the head is the oldest and the one to drop off
+%% when the log is full.
+%%
+%% Here is how we can get away with only using one cons cell
+%% to wrap the forward and reverse list, and the log size:
+%%
+%% A full log does not need a counter; we just cons one
+%% and drop one:
+%%
+%% [ReverseList|ForwardList]
+%%
+%% A non-full log is filling up to N elements;
+%% use a down counter instead of a list as first element:
+%%
+%% [RemainingToFullCount|ReverseList]
nlog_new() ->
nlog_new(10).
%%
-nlog_new(N) when is_integer(N) ->
- {N, []};
-nlog_new(NLog) ->
- nlog_new(10, NLog).
+nlog_new([_|_] = NLog) ->
+ nlog_new(10, NLog);
+nlog_new(N) ->
+ [N]. % Empty log size N >= 1
%%
-nlog_new(NewN, {_N, R}) ->
- {NewN, trim(NewN, R)}.
+nlog_new(N, NLog) ->
+ lists:foldl(
+ fun (Item, NL) -> nlog_put(Item, NL) end,
+ nlog_new(N),
+ nlog_get(NLog)).
-nlog_put(Item, {N, R}) ->
- {N, [Item | trim(N, R)]}.
+%%
+nlog_put(Item, NLog) ->
+ case NLog of
+ [R|FF] when is_list(R) ->
+ %% Full log
+ case FF of
+ [_|F] ->
+ %% Cons to reverse list, drop from forward list
+ [[Item|R]|F];
+ [] ->
+ %% Create new forward list from reverse list,
+ %% create new empty reverse list
+ [_|F] = lists:reverse(R, [Item]),
+ [[]|F]
+ end;
+ [1|R] ->
+ %% Log now gets full
+ [[Item|R]];
+ [J|R] ->
+ %% Filling up to N elements
+ [J - 1,Item|R]
+ end.
-nlog_get({_N, R}) ->
+nlog_get([[]|F]) ->
+ F;
+nlog_get([[_|_] = R|F]) ->
+ F ++ lists:reverse(R);
+nlog_get([_J|R]) ->
lists:reverse(R).
%%-----------------------------------------------------------------