Skip to content

Commit

Permalink
Avoid ftell() calls by pfSizedStream.
Browse files Browse the repository at this point in the history
According to profiling, calls to `ftell()` when reading creatables is
the largest time sink when reading PRPs. On a trivial test with two
iterations of loading Garrison, the results are thus:

Before: 68.68s (34.34s avg)
After: 7.68s (3.84s avg)
  • Loading branch information
Hoikas committed Jun 7, 2021
1 parent c7af40e commit 6028e85
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 12 deletions.
24 changes: 15 additions & 9 deletions core/Stream/pfSizedStream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
#include "Debug/plDebug.h"

pfSizedStream::pfSizedStream(hsStream* S, uint32_t len)
: fBase(S), fLength(len)
: fBase(S), fLength(len), fPos()
{
if (S) {
ver = S->getVer();
Expand All @@ -41,37 +41,43 @@ void pfSizedStream::seek(uint32_t pos)
}

fBase->seek(fBegin + pos);
fPos = std::min(pos, fLength);
}

void pfSizedStream::skip(int32_t count)
{
if (pos() + count > fLength) { // pos() is the index in the sub-stream
if (fPos + count > fLength) { // fPos is the index in the sub-stream
throw hsFileReadException(__FILE__, __LINE__,
ST::format("Seek out of range: {} bytes requested, {} available",
count, (fLength - pos())).c_str());
count, (fLength - fPos)).c_str());
}

fBase->skip(count);
fPos += count;
}

size_t pfSizedStream::read(size_t size, void* buf)
{
if (pos() + size > fLength) { // pos() is the index in the sub-stream
if (fPos + size > fLength) { // fPos is the index in the sub-stream
throw hsFileReadException(__FILE__, __LINE__,
ST::format("Read past end of sized stream: {} bytes requested, {} available",
size, (fLength - pos())).c_str());
size, (fLength - fPos)).c_str());
}

return fBase->read(size, buf);
size_t nread = fBase->read(size, buf);
fPos += nread;
return nread;
}

size_t pfSizedStream::write(size_t size, const void* buf)
{
if (pos() + size > fLength) { // pos() is the index in the sub-stream
if (fPos + size > fLength) { // fPos is the index in the sub-stream
throw hsFileReadException(__FILE__, __LINE__,
ST::format("Write past end of sized stream: {} bytes requested, {} available",
size, (fLength - pos())).c_str());
size, (fLength - fPos)).c_str());
}

return fBase->write(size, buf);
size_t nwrite = fBase->write(size, buf);
fPos += nwrite;
return nwrite;
}
7 changes: 4 additions & 3 deletions core/Stream/pfSizedStream.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,21 @@

#include "hsStream.h"

class PLASMA_DLL pfSizedStream : public hsStream
class PLASMA_DLL pfSizedStream HS_FINAL : public hsStream
{
private:
hsStream* fBase;
uint32_t fLength; //!< the length of the substream - not the end position of it!
uint32_t fBegin;
uint32_t fPos;

public:
pfSizedStream(hsStream* S, uint32_t len);
~pfSizedStream() { } // Do NOT free fBase!!!

uint32_t size() const HS_OVERRIDE { return fLength; }
uint32_t pos() const HS_OVERRIDE { return fBase->pos() - fBegin; }
bool eof() const HS_OVERRIDE { return fBase->eof() || pos() == fLength; }
uint32_t pos() const HS_OVERRIDE { return fPos; }
bool eof() const HS_OVERRIDE { return fPos == fLength || fBase->eof(); }

void seek(uint32_t pos) HS_OVERRIDE;
void skip(int32_t count) HS_OVERRIDE;
Expand Down

0 comments on commit 6028e85

Please sign in to comment.