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
This commit is contained in:
parent
a32da9d3ee
commit
d91e017803
44
src/file.cc
44
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)
|
void write_buffer_to_fd(Buffer& buffer, int fd)
|
||||||
{
|
{
|
||||||
auto eolformat = buffer.options()["eolformat"].get<EolFormat>();
|
auto eolformat = buffer.options()["eolformat"].get<EolFormat>();
|
||||||
|
@ -266,17 +301,18 @@ void write_buffer_to_fd(Buffer& buffer, int fd)
|
||||||
else
|
else
|
||||||
eoldata = "\n";
|
eoldata = "\n";
|
||||||
|
|
||||||
|
|
||||||
|
BufferedWriter writer{fd};
|
||||||
if (buffer.options()["BOM"].get<ByteOrderMark>() == ByteOrderMark::Utf8)
|
if (buffer.options()["BOM"].get<ByteOrderMark>() == ByteOrderMark::Utf8)
|
||||||
if (::write(fd, "\xEF\xBB\xBF", 3) < 0)
|
writer.write("\xEF\xBB\xBF");
|
||||||
throw runtime_error(format("unable to write data to the buffer (fd: {}; errno: {})", fd, ::strerror(errno)));
|
|
||||||
|
|
||||||
for (LineCount i = 0; i < buffer.line_count(); ++i)
|
for (LineCount i = 0; i < buffer.line_count(); ++i)
|
||||||
{
|
{
|
||||||
// end of lines are written according to eolformat but always
|
// end of lines are written according to eolformat but always
|
||||||
// stored as \n
|
// stored as \n
|
||||||
StringView linedata = buffer[i];
|
StringView linedata = buffer[i];
|
||||||
write(fd, linedata.substr(0, linedata.length()-1));
|
writer.write(linedata.substr(0, linedata.length()-1));
|
||||||
write(fd, eoldata);
|
writer.write(eoldata);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user