From d91e017803aca3b75dbb3d1cfca26a811022c1d4 Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Mon, 1 Apr 2019 22:57:55 +1100 Subject: [PATCH] Buffer writes in blocks of 4Kb when writing buffers to files Could make kakoune more compatible with tools looking for file modifications by reducing the amount of writes done. As discussed in #2812 --- src/file.cc | 44 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/src/file.cc b/src/file.cc index b8bf2de8..7b49595e 100644 --- a/src/file.cc +++ b/src/file.cc @@ -257,6 +257,41 @@ void write(int fd, StringView data) } } +struct BufferedWriter +{ + BufferedWriter(int fd) : fd{fd} {} + + ~BufferedWriter() + { + if (pos != 0) + Kakoune::write(fd, {buffer, pos}); + } + + void write(StringView data) + { + while (not data.empty()) + { + const ByteCount length = data.length(); + const ByteCount write_len = std::min(length, size - pos); + memcpy(buffer + (int)pos, data.data(), (int)write_len); + pos += write_len; + if (pos == size) + { + Kakoune::write(fd, {buffer, size}); + pos = 0; + } + data = data.substr(write_len); + } + } + +private: + static constexpr ByteCount size = 4096; + int fd; + ByteCount pos = 0; + char buffer[(int)size]; +}; + + void write_buffer_to_fd(Buffer& buffer, int fd) { auto eolformat = buffer.options()["eolformat"].get(); @@ -266,17 +301,18 @@ void write_buffer_to_fd(Buffer& buffer, int fd) else eoldata = "\n"; + + BufferedWriter writer{fd}; if (buffer.options()["BOM"].get() == ByteOrderMark::Utf8) - if (::write(fd, "\xEF\xBB\xBF", 3) < 0) - throw runtime_error(format("unable to write data to the buffer (fd: {}; errno: {})", fd, ::strerror(errno))); + writer.write("\xEF\xBB\xBF"); for (LineCount i = 0; i < buffer.line_count(); ++i) { // end of lines are written according to eolformat but always // stored as \n StringView linedata = buffer[i]; - write(fd, linedata.substr(0, linedata.length()-1)); - write(fd, eoldata); + writer.write(linedata.substr(0, linedata.length()-1)); + writer.write(eoldata); } }