mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 06:27:45 +00:00
LibCore: Keep track of file offset to avoid system call for tell()
This optimization makes the new test run 2x faster.
This commit is contained in:
parent
111fd1e5fe
commit
10edd38543
3 changed files with 33 additions and 1 deletions
|
@ -92,6 +92,25 @@ TEST_CASE(file_seeking_around)
|
||||||
EXPECT_EQ(buffer_contents, expected_seek_contents3);
|
EXPECT_EQ(buffer_contents, expected_seek_contents3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BENCHMARK_CASE(file_tell)
|
||||||
|
{
|
||||||
|
auto file = TRY_OR_FAIL(Core::File::open("/usr/Tests/LibCore/10kb.txt"sv, Core::File::OpenMode::Read));
|
||||||
|
auto expected_file_offset = 0u;
|
||||||
|
auto ten_byte_buffer = TRY_OR_FAIL(ByteBuffer::create_uninitialized(1));
|
||||||
|
for (auto i = 0u; i < 4000; ++i) {
|
||||||
|
TRY_OR_FAIL(file->read_until_filled(ten_byte_buffer));
|
||||||
|
expected_file_offset += 1u;
|
||||||
|
EXPECT_EQ(expected_file_offset, TRY_OR_FAIL(file->tell()));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto i = 0u; i < 4000; ++i) {
|
||||||
|
auto seek_file_offset = TRY_OR_FAIL(file->seek(-1, SeekMode::FromCurrentPosition));
|
||||||
|
expected_file_offset -= 1;
|
||||||
|
EXPECT_EQ(seek_file_offset, TRY_OR_FAIL(file->tell()));
|
||||||
|
EXPECT_EQ(expected_file_offset, TRY_OR_FAIL(file->tell()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE(file_adopt_fd)
|
TEST_CASE(file_adopt_fd)
|
||||||
{
|
{
|
||||||
int rc = ::open("/usr/Tests/LibCore/long_lines.txt", O_RDONLY);
|
int rc = ::open("/usr/Tests/LibCore/long_lines.txt", O_RDONLY);
|
||||||
|
|
|
@ -117,6 +117,7 @@ ErrorOr<Bytes> File::read_some(Bytes buffer)
|
||||||
|
|
||||||
ssize_t nread = TRY(System::read(m_fd, buffer));
|
ssize_t nread = TRY(System::read(m_fd, buffer));
|
||||||
m_last_read_was_eof = nread == 0;
|
m_last_read_was_eof = nread == 0;
|
||||||
|
m_file_offset += nread;
|
||||||
return buffer.trim(nread);
|
return buffer.trim(nread);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,7 +136,9 @@ ErrorOr<size_t> File::write_some(ReadonlyBytes buffer)
|
||||||
return Error::from_errno(EBADF);
|
return Error::from_errno(EBADF);
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRY(System::write(m_fd, buffer));
|
auto nwritten = TRY(System::write(m_fd, buffer));
|
||||||
|
m_file_offset += nwritten;
|
||||||
|
return nwritten;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool File::is_eof() const { return m_last_read_was_eof; }
|
bool File::is_eof() const { return m_last_read_was_eof; }
|
||||||
|
@ -177,15 +180,22 @@ ErrorOr<size_t> File::seek(i64 offset, SeekMode mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t seek_result = TRY(System::lseek(m_fd, offset, syscall_mode));
|
size_t seek_result = TRY(System::lseek(m_fd, offset, syscall_mode));
|
||||||
|
m_file_offset = seek_result;
|
||||||
m_last_read_was_eof = false;
|
m_last_read_was_eof = false;
|
||||||
return seek_result;
|
return seek_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ErrorOr<size_t> File::tell() const
|
||||||
|
{
|
||||||
|
return m_file_offset;
|
||||||
|
}
|
||||||
|
|
||||||
ErrorOr<void> File::truncate(size_t length)
|
ErrorOr<void> File::truncate(size_t length)
|
||||||
{
|
{
|
||||||
if (length > static_cast<size_t>(NumericLimits<off_t>::max()))
|
if (length > static_cast<size_t>(NumericLimits<off_t>::max()))
|
||||||
return Error::from_string_literal("Length is larger than the maximum supported length");
|
return Error::from_string_literal("Length is larger than the maximum supported length");
|
||||||
|
|
||||||
|
m_file_offset = min(length, m_file_offset);
|
||||||
return System::ftruncate(m_fd, length);
|
return System::ftruncate(m_fd, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -67,6 +67,7 @@ public:
|
||||||
virtual bool is_open() const override;
|
virtual bool is_open() const override;
|
||||||
virtual void close() override;
|
virtual void close() override;
|
||||||
virtual ErrorOr<size_t> seek(i64 offset, SeekMode) override;
|
virtual ErrorOr<size_t> seek(i64 offset, SeekMode) override;
|
||||||
|
virtual ErrorOr<size_t> tell() const override;
|
||||||
virtual ErrorOr<void> truncate(size_t length) override;
|
virtual ErrorOr<void> truncate(size_t length) override;
|
||||||
|
|
||||||
// Sets the blocking mode of the file. If blocking mode is disabled, reads
|
// Sets the blocking mode of the file. If blocking mode is disabled, reads
|
||||||
|
@ -109,6 +110,8 @@ private:
|
||||||
int m_fd { -1 };
|
int m_fd { -1 };
|
||||||
bool m_last_read_was_eof { false };
|
bool m_last_read_was_eof { false };
|
||||||
ShouldCloseFileDescriptor m_should_close_file_descriptor { ShouldCloseFileDescriptor::Yes };
|
ShouldCloseFileDescriptor m_should_close_file_descriptor { ShouldCloseFileDescriptor::Yes };
|
||||||
|
|
||||||
|
size_t m_file_offset { 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
AK_ENUM_BITWISE_OPERATORS(File::OpenMode)
|
AK_ENUM_BITWISE_OPERATORS(File::OpenMode)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue