- optimize memory usage

This commit is contained in:
2026-07-06 12:33:45 +03:00
parent 25e30a6ba7
commit 7f638a5aef
3 changed files with 41 additions and 10 deletions
+28 -4
View File
@@ -497,12 +497,12 @@ size_t BufferReader::count() const
} }
// -------------- BufferWriter ---------------------- // -------------- BufferWriter ----------------------
BufferWriter::BufferWriter(ByteBuffer &buffer) BufferWriter::BufferWriter(ByteBuffer &buffer, size_t startOffset)
:mData(buffer.mutableData()), mIndex(0) :mBuffer(&buffer), mData(buffer.mutableData() + startOffset), mBase(startOffset), mIndex(0), mCapacity(0)
{} {}
BufferWriter::BufferWriter(void *output) BufferWriter::BufferWriter(void *output, size_t capacity)
:mData(reinterpret_cast<uint8_t*>(output)), mIndex(0) :mBuffer(nullptr), mData(reinterpret_cast<uint8_t*>(output)), mBase(0), mIndex(0), mCapacity(capacity)
{} {}
@@ -545,6 +545,30 @@ void BufferWriter::writeIp(const NetworkAddress& ip)
void BufferWriter::writeBuffer(const void* dataPtr, size_t dataSize) void BufferWriter::writeBuffer(const void* dataPtr, size_t dataSize)
{ {
if (dataSize == 0)
return;
if (mBuffer)
{
// Growable mode: ensure the backing buffer is large enough, then refresh
// the cached pointer in case resize() reallocated the storage.
size_t needed = mBase + mIndex + dataSize;
if (needed > mBuffer->size())
mBuffer->resize(needed);
mData = mBuffer->mutableData() + mBase;
}
else
{
// Bounded mode: never write past the caller-supplied capacity.
if (mIndex + dataSize > mCapacity)
{
assert(0 && "BufferWriter capacity exceeded");
dataSize = mIndex < mCapacity ? mCapacity - mIndex : 0;
if (dataSize == 0)
return;
}
}
memmove(mData + mIndex, dataPtr, dataSize); memmove(mData + mIndex, dataPtr, dataSize);
mIndex += dataSize; mIndex += dataSize;
} }
+9 -4
View File
@@ -172,12 +172,17 @@ namespace ice
class BufferWriter class BufferWriter
{ {
protected: protected:
uint8_t* mData; ByteBuffer* mBuffer; // Non-null => growable: writes resize this buffer to fit
size_t mIndex; uint8_t* mData; // Cached write pointer (refreshed on growth in growable mode)
size_t mBase; // Start offset within mBuffer (growable mode)
size_t mIndex; // Bytes written since mBase
size_t mCapacity; // Usable capacity from mData (raw/bounded mode)
public: public:
BufferWriter(void* output); // Bounded writer over caller-owned memory. Writes past 'capacity' are refused.
BufferWriter(ByteBuffer& buffer); BufferWriter(void* output, size_t capacity);
// Growable writer: the backing buffer is resized as needed so writes never overflow.
BufferWriter(ByteBuffer& buffer, size_t startOffset = 0);
void writeUInt(uint32_t value); void writeUInt(uint32_t value);
void writeUShort(uint16_t value); void writeUShort(uint16_t value);
+4 -2
View File
@@ -216,8 +216,10 @@ void StunMessage::buildPacket(ByteBuffer& buffer, const std::string& password)
for (size_t i=0; i<4; i++) for (size_t i=0; i<4; i++)
bitstream.writeBit(bit(msgtype, 3-i)); bitstream.writeBit(bit(msgtype, 3-i));
// Enqueue 2 bytes of length - now it is zero // Enqueue 2 bytes of length - now it is zero.
BufferWriter stream(buffer.mutableData() + bitstream.count() / 8); // Growable writer starting right after the bits already emitted; it resizes
// 'buffer' as attributes are appended so an oversized message cannot overflow.
BufferWriter stream(buffer, bitstream.count() / 8);
stream.writeUShort(0); stream.writeUShort(0);
// Enqueue magic cookie value // Enqueue magic cookie value