Performance improvements to savegame loading
This commit is contained in:
@@ -320,18 +320,115 @@ struct ReadBuffer {
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
inline byte ReadByte()
|
void SkipBytesSlowPath(size_t bytes)
|
||||||
{
|
{
|
||||||
if (this->bufp == this->bufe) {
|
bytes -= (this->bufe - this->bufp);
|
||||||
|
while (true) {
|
||||||
size_t len = this->reader->Read(this->buf, lengthof(this->buf));
|
size_t len = this->reader->Read(this->buf, lengthof(this->buf));
|
||||||
if (len == 0) SlErrorCorrupt("Unexpected end of chunk");
|
if (len == 0) SlErrorCorrupt("Unexpected end of chunk");
|
||||||
|
|
||||||
this->read += len;
|
this->read += len;
|
||||||
this->bufp = this->buf;
|
if (len >= bytes) {
|
||||||
this->bufe = this->buf + len;
|
this->bufp = this->buf + bytes;
|
||||||
|
this->bufe = this->buf + len;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
bytes -= len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void SkipBytes(size_t bytes)
|
||||||
|
{
|
||||||
|
byte *b = this->bufp + bytes;
|
||||||
|
if (likely(b <= this->bufe)) {
|
||||||
|
this->bufp = b;
|
||||||
|
} else {
|
||||||
|
SkipBytesSlowPath(bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AcquireBytes()
|
||||||
|
{
|
||||||
|
size_t remainder = this->bufe - this->bufp;
|
||||||
|
if (remainder) {
|
||||||
|
memmove(this->buf, this->bufp, remainder);
|
||||||
|
}
|
||||||
|
size_t len = this->reader->Read(this->buf + remainder, lengthof(this->buf) - remainder);
|
||||||
|
if (len == 0) SlErrorCorrupt("Unexpected end of chunk");
|
||||||
|
|
||||||
|
this->read += len;
|
||||||
|
this->bufp = this->buf;
|
||||||
|
this->bufe = this->buf + remainder + len;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline byte RawReadByte()
|
||||||
|
{
|
||||||
|
return *this->bufp++;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline byte ReadByte()
|
||||||
|
{
|
||||||
|
if (unlikely(this->bufp == this->bufe)) {
|
||||||
|
this->AcquireBytes();
|
||||||
}
|
}
|
||||||
|
|
||||||
return *this->bufp++;
|
return RawReadByte();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void CheckBytes(size_t bytes)
|
||||||
|
{
|
||||||
|
while (unlikely(this->bufp + bytes > this->bufe)) this->AcquireBytes();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int RawReadUint16()
|
||||||
|
{
|
||||||
|
#if OTTD_ALIGNMENT == 0
|
||||||
|
int x = FROM_BE16(*((const uint16*) this->bufp));
|
||||||
|
this->bufp += 2;
|
||||||
|
return x;
|
||||||
|
#else
|
||||||
|
int x = this->RawReadByte() << 8;
|
||||||
|
return x | this->RawReadByte();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint32 RawReadUint32()
|
||||||
|
{
|
||||||
|
#if OTTD_ALIGNMENT == 0
|
||||||
|
uint32 x = FROM_BE32(*((const uint32*) this->bufp));
|
||||||
|
this->bufp += 4;
|
||||||
|
return x;
|
||||||
|
#else
|
||||||
|
uint32 x = this->RawReadUint16() << 16;
|
||||||
|
return x | this->RawReadUint16();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint64 RawReadUint64()
|
||||||
|
{
|
||||||
|
#if OTTD_ALIGNMENT == 0
|
||||||
|
uint64 x = FROM_BE64(*((const uint64*) this->bufp));
|
||||||
|
this->bufp += 8;
|
||||||
|
return x;
|
||||||
|
#else
|
||||||
|
uint32 x = this->RawReadUint32();
|
||||||
|
uint32 y = this->RawReadUint32();
|
||||||
|
return (uint64)x << 32 | y;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void CopyBytes(byte *ptr, size_t length)
|
||||||
|
{
|
||||||
|
while (length) {
|
||||||
|
if (unlikely(this->bufp == this->bufe)) {
|
||||||
|
this->AcquireBytes();
|
||||||
|
}
|
||||||
|
size_t to_copy = min<size_t>(this->bufe - this->bufp, length);
|
||||||
|
memcpy(ptr, this->bufp, to_copy);
|
||||||
|
this->bufp += to_copy;
|
||||||
|
ptr += to_copy;
|
||||||
|
length -= to_copy;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -648,6 +745,34 @@ byte SlReadByte()
|
|||||||
return _sl.reader->ReadByte();
|
return _sl.reader->ReadByte();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read in bytes from the file/data structure but don't do
|
||||||
|
* anything with them, discarding them in effect
|
||||||
|
* @param length The amount of bytes that is being treated this way
|
||||||
|
*/
|
||||||
|
void SlSkipBytes(size_t length)
|
||||||
|
{
|
||||||
|
return _sl.reader->SkipBytes(length);
|
||||||
|
}
|
||||||
|
|
||||||
|
int SlReadUint16()
|
||||||
|
{
|
||||||
|
_sl.reader->CheckBytes(2);
|
||||||
|
return _sl.reader->RawReadUint16();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 SlReadUint32()
|
||||||
|
{
|
||||||
|
_sl.reader->CheckBytes(4);
|
||||||
|
return _sl.reader->RawReadUint32();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64 SlReadUint64()
|
||||||
|
{
|
||||||
|
_sl.reader->CheckBytes(8);
|
||||||
|
return _sl.reader->RawReadUint64();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrapper for writing a byte to the dumper.
|
* Wrapper for writing a byte to the dumper.
|
||||||
* @param b The byte to write.
|
* @param b The byte to write.
|
||||||
@@ -946,7 +1071,7 @@ static void SlCopyBytes(void *ptr, size_t length)
|
|||||||
switch (_sl.action) {
|
switch (_sl.action) {
|
||||||
case SLA_LOAD_CHECK:
|
case SLA_LOAD_CHECK:
|
||||||
case SLA_LOAD:
|
case SLA_LOAD:
|
||||||
for (; length != 0; length--) *p++ = SlReadByte();
|
_sl.reader->CopyBytes(p, length);
|
||||||
break;
|
break;
|
||||||
case SLA_SAVE:
|
case SLA_SAVE:
|
||||||
for (; length != 0; length--) SlWriteByte(*p++);
|
for (; length != 0; length--) SlWriteByte(*p++);
|
||||||
|
@@ -679,24 +679,9 @@ size_t SlCalcObjLength(const void *object, const SaveLoad *sld);
|
|||||||
byte SlReadByte();
|
byte SlReadByte();
|
||||||
void SlWriteByte(byte b);
|
void SlWriteByte(byte b);
|
||||||
|
|
||||||
static inline int SlReadUint16()
|
int SlReadUint16();
|
||||||
{
|
uint32 SlReadUint32();
|
||||||
int x = SlReadByte() << 8;
|
uint64 SlReadUint64();
|
||||||
return x | SlReadByte();
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32 SlReadUint32()
|
|
||||||
{
|
|
||||||
uint32 x = SlReadUint16() << 16;
|
|
||||||
return x | SlReadUint16();
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint64 SlReadUint64()
|
|
||||||
{
|
|
||||||
uint32 x = SlReadUint32();
|
|
||||||
uint32 y = SlReadUint32();
|
|
||||||
return (uint64)x << 32 | y;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void SlWriteUint16(uint16 v)
|
static inline void SlWriteUint16(uint16 v)
|
||||||
{
|
{
|
||||||
@@ -716,15 +701,7 @@ static inline void SlWriteUint64(uint64 x)
|
|||||||
SlWriteUint32((uint32)x);
|
SlWriteUint32((uint32)x);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
void SlSkipBytes(size_t length);
|
||||||
* Read in bytes from the file/data structure but don't do
|
|
||||||
* anything with them, discarding them in effect
|
|
||||||
* @param length The amount of bytes that is being treated this way
|
|
||||||
*/
|
|
||||||
static inline void SlSkipBytes(size_t length)
|
|
||||||
{
|
|
||||||
for (; length != 0; length--) SlReadByte();
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t SlGetBytesRead();
|
size_t SlGetBytesRead();
|
||||||
size_t SlGetBytesWritten();
|
size_t SlGetBytesWritten();
|
||||||
|
Reference in New Issue
Block a user