File 2131-Improve-caching-in-disk_log.patch of Package erlang

From eda5c4859f561fae7d3a3b74f19dd8596c212966 Mon Sep 17 00:00:00 2001
From: Richard Carlsson <richardc@klarna.com>
Date: Tue, 1 Nov 2016 15:36:57 +0100
Subject: [PATCH 11/12] 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.
---
 lib/kernel/src/disk_log.hrl        |  1 +
 lib/kernel/src/disk_log_1.erl      | 32 ++++++++++++++++++++++----------
 lib/kernel/test/disk_log_SUITE.erl |  4 ++--
 3 files changed, 25 insertions(+), 12 deletions(-)

diff --git a/lib/kernel/src/disk_log.hrl b/lib/kernel/src/disk_log.hrl
index 3cf8a3b3a..593dbb31a 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 2e61363aa..d83c30f35 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 a25b315d9..23fe975ef 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),
-- 
2.11.0

openSUSE Build Service is sponsored by