Optimize FileReadStream seeking if new position is within the cached buffer

This commit is contained in:
Wojtek Figat
2024-05-13 22:40:27 +02:00
parent 3593f835cd
commit a742ce1d32
2 changed files with 41 additions and 1 deletions

View File

@@ -4,6 +4,8 @@
#include "Engine/Core/Log.h"
#include "Engine/Platform/File.h"
#define USE_FILE_POS (1)
FileReadStream* FileReadStream::Open(const StringView& path)
{
const auto file = File::Open(path, FileMode::OpenExisting, FileAccess::Read, FileShare::Read);
@@ -24,8 +26,12 @@ FileReadStream::FileReadStream(File* file)
: _file(file)
, _virtualPosInBuffer(0)
, _bufferSize(0)
#if USE_FILE_POS
, _filePosition(file->GetPosition())
#else
, _filePosition(0)
#endif
{
ASSERT_LOW_LAYER(_file);
}
FileReadStream::~FileReadStream()
@@ -62,16 +68,40 @@ uint32 FileReadStream::GetLength()
uint32 FileReadStream::GetPosition()
{
#if USE_FILE_POS
return _filePosition - _bufferSize + _virtualPosInBuffer;
#else
return _file->GetPosition() - _bufferSize + _virtualPosInBuffer;
#endif
}
void FileReadStream::SetPosition(uint32 seek)
{
#if USE_FILE_POS
// Skip if position won't change
if (GetPosition() == seek)
{
return;
}
// Try to seek with virtual position
uint32 bufferStartPos = _filePosition - _bufferSize;
if (seek >= GetPosition() && seek < _filePosition)
{
_virtualPosInBuffer = seek - bufferStartPos;
return;
}
#endif
// Seek
_file->SetPosition(seek);
_filePosition = _file->GetPosition();
// Update buffer
_hasError |= _file->Read(_buffer, FILESTREAM_BUFFER_SIZE, &_bufferSize) != 0;
#if USE_FILE_POS
_filePosition += _bufferSize;
#endif
_virtualPosInBuffer = 0;
}
@@ -88,6 +118,9 @@ void FileReadStream::ReadBytes(void* data, uint32 bytes)
{
CHECK(_virtualPosInBuffer == 0);
_hasError |= _file->Read(_buffer, FILESTREAM_BUFFER_SIZE, &_bufferSize) != 0;
#if USE_FILE_POS
_filePosition += _bufferSize;
#endif
}
// Check if buffer has enough data for this read
@@ -107,6 +140,9 @@ void FileReadStream::ReadBytes(void* data, uint32 bytes)
bytes -= bufferBytesLeft;
_virtualPosInBuffer = 0;
_hasError |= _file->Read(_buffer, FILESTREAM_BUFFER_SIZE, &_bufferSize) != 0;
#if USE_FILE_POS
_filePosition += _bufferSize;
#endif
}
// Read as much as can using whole buffer
@@ -116,6 +152,9 @@ void FileReadStream::ReadBytes(void* data, uint32 bytes)
data = (byte*)data + FILESTREAM_BUFFER_SIZE;
bytes -= FILESTREAM_BUFFER_SIZE;
_hasError |= _file->Read(_buffer, FILESTREAM_BUFFER_SIZE, &_bufferSize) != 0;
#if USE_FILE_POS
_filePosition += _bufferSize;
#endif
}
// Read the rest of the buffer but without flushing its data

View File

@@ -15,6 +15,7 @@ private:
File* _file;
uint32 _virtualPosInBuffer; // Current position in the buffer (index)
uint32 _bufferSize; // Amount of loaded bytes from the file to the buffer
uint32 _filePosition; // Cached position in the file (native)
byte _buffer[FILESTREAM_BUFFER_SIZE];
public: