aboutsummaryrefslogtreecommitdiffstats
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
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.
-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),