aboutsummaryrefslogtreecommitdiffstats
path: root/lib/kernel
diff options
context:
space:
mode:
authorRichard Carlsson <[email protected]>2016-11-01 15:36:57 +0100
committerRichard Carlsson <[email protected]>2016-11-29 10:31:43 +0100
commiteda5c4859f561fae7d3a3b74f19dd8596c212966 (patch)
treec957eb3248ceb4618fe062af90d28201faf58a48 /lib/kernel
parent5a8a1a963edd6d6dbb35bf615a4bad7d77041443 (diff)
downloadotp-eda5c4859f561fae7d3a3b74f19dd8596c212966.tar.gz
otp-eda5c4859f561fae7d3a3b74f19dd8596c212966.tar.bz2
otp-eda5c4859f561fae7d3a3b74f19dd8596c212966.zip
Improve caching in disk_log
Avoid starting timers for flushing when the written data is empty or larger than the max cache size. Previously, a single huge write to an empty cache would be put in the cache until the next write or the timer event. Also increase the cache size from 16K to 64K.
Diffstat (limited to 'lib/kernel')
-rw-r--r--lib/kernel/src/disk_log.hrl1
-rw-r--r--lib/kernel/src/disk_log_1.erl32
-rw-r--r--lib/kernel/test/disk_log_SUITE.erl4
3 files changed, 25 insertions, 12 deletions
diff --git a/lib/kernel/src/disk_log.hrl b/lib/kernel/src/disk_log.hrl
index 3cf8a3b3a2..593dbb31ab 100644
--- a/lib/kernel/src/disk_log.hrl
+++ b/lib/kernel/src/disk_log.hrl
@@ -39,6 +39,7 @@
-define(MAX_FILES, 65000).
-define(MAX_BYTES, ((1 bsl 64) - 1)).
-define(MAX_CHUNK_SIZE, 65536).
+-define(MAX_FWRITE_CACHE, 65536).
%% Object defines
-define(LOGMAGIC, <<1,2,3,4>>).
diff --git a/lib/kernel/src/disk_log_1.erl b/lib/kernel/src/disk_log_1.erl
index 2e61363aa6..d83c30f35f 100644
--- a/lib/kernel/src/disk_log_1.erl
+++ b/lib/kernel/src/disk_log_1.erl
@@ -1416,24 +1416,36 @@ open_truncate(FileName) ->
%%% Functions that access files, and throw on error.
--define(MAX, 16384). % bytes
-define(TIMEOUT, 2000). % ms
%% -> {Reply, cache()}; Reply = ok | Error
-fwrite(#cache{c = []} = FdC, _FN, B, Size) ->
+fwrite(FdC, _FN, _B, 0) ->
+ {ok, FdC}; % avoid starting a timer for empty writes
+fwrite(#cache{fd = Fd, c = C, sz = Sz} = FdC, FileName, B, Size) ->
+ Sz1 = Sz + Size,
+ C1 = cache_append(C, B),
+ if Sz1 > ?MAX_FWRITE_CACHE ->
+ write_cache(Fd, FileName, C1);
+ true ->
+ maybe_start_timer(C),
+ {ok, FdC#cache{sz = Sz1, c = C1}}
+ end.
+
+cache_append([], B) -> B;
+cache_append(C, B) -> [C | B].
+
+%% if the cache was empty, start timer (unless it's already running)
+maybe_start_timer([]) ->
case get(write_cache_timer_is_running) of
- true ->
+ true ->
ok;
- _ ->
+ _ ->
put(write_cache_timer_is_running, true),
erlang:send_after(?TIMEOUT, self(), {self(), write_cache}),
ok
- end,
- {ok, FdC#cache{sz = Size, c = B}};
-fwrite(#cache{sz = Sz, c = C} = FdC, _FN, B, Size) when Sz < ?MAX ->
- {ok, FdC#cache{sz = Sz+Size, c = [C | B]}};
-fwrite(#cache{fd = Fd, c = C}, FileName, B, _Size) ->
- write_cache(Fd, FileName, [C | B]).
+ end;
+maybe_start_timer(_C) ->
+ ok.
fwrite_header(Fd, B, Size) ->
{ok, #cache{fd = Fd, sz = Size, c = B}}.
diff --git a/lib/kernel/test/disk_log_SUITE.erl b/lib/kernel/test/disk_log_SUITE.erl
index a25b315d9d..23fe975ef7 100644
--- a/lib/kernel/test/disk_log_SUITE.erl
+++ b/lib/kernel/test/disk_log_SUITE.erl
@@ -4666,7 +4666,7 @@ other_groups(Conf) when is_list(Conf) ->
ok.
--define(MAX, 16384). % MAX in disk_log_1.erl
+-define(MAX, ?MAX_FWRITE_CACHE). % as in disk_log_1.erl
%% Evil cases such as closed file descriptor port.
evil(Conf) when is_list(Conf) ->
Dir = ?privdir(Conf),
@@ -4690,7 +4690,7 @@ evil(Conf) when is_list(Conf) ->
{size,?MAX+50},{format,external}]),
[Fd] = erlang:ports() -- Ports0,
{B,_} = x_mk_bytes(30),
- ok = disk_log:blog(Log, <<0:(?MAX+1)/unit:8>>),
+ ok = disk_log:blog(Log, <<0:(?MAX-1)/unit:8>>),
exit(Fd, kill),
{error, {file_error,_,einval}} = disk_log:blog_terms(Log, [B,B]),
ok= disk_log:close(Log),