Adapt Buffer class to avoid repeated compactions.

Avoid continually shuffling large output buffers down in memory,
it kills CPU caches, does nothing useful, and we can just advance
an offset instead. Of course, we do need to free memory - so do
that for lots of common cases.

Change-Id: I63240661ca87bdc0574acbce856771d9dde3fa94
Signed-off-by: Michael Meeks <michael.meeks@collabora.com>
This commit is contained in:
Michael Meeks 2020-11-19 19:55:30 +00:00 committed by Ashod Nakashian
parent e00392647b
commit 0fc91ef31c
2 changed files with 25 additions and 8 deletions

View file

@ -17,9 +17,10 @@
*/
class Buffer {
size_t _size;
size_t _offset;
std::vector<char> _buffer;
public:
Buffer() : _size(0)
Buffer() : _size(0), _offset(0)
{
}
size_t size() { return _size; }
@ -27,7 +28,7 @@ public:
const char *getBlock()
{
return &_buffer[0];
return &_buffer[_offset];
}
size_t getBlockSize()
{
@ -35,17 +36,34 @@ public:
}
void eraseFirst(size_t len)
{
_buffer.erase(_buffer.begin(), _buffer.begin() + len);
_size = _buffer.size();
assert(_offset + len <= _buffer.size());
// avoid regular shuffling down larger chunks of data
if (_buffer.size() > 16384 && // lots of queued data
len < _buffer.size() && // not a complete erase
_offset < 16384 * 64 && // do cleanup a Mb at a time or so:
_size > 512) // early cleanup if what remains is small.
{
_offset += len;
_size -= len;
return;
}
_buffer.erase(_buffer.begin(), _buffer.begin() + _offset + len);
_offset = 0;
_size = _buffer.size() - _offset;
}
void append(const char *data, const int len)
{
_buffer.insert(_buffer.end(), data, data + len);
_size = _buffer.size();
_size = _buffer.size() - _offset;
}
void dumpHex(std::ostream &os, const char *legend, const char *prefix)
{
Util::dumpHex(os, legend, prefix, _buffer);
if (_size > 0 || _offset > 0)
os << prefix << "Buffer size: " << _size << " offset: " << _offset << "\n";
if (_buffer.size() > 0)
Util::dumpHex(os, legend, prefix, _buffer);
}
};

View file

@ -554,8 +554,7 @@ void StreamSocket::dumpState(std::ostream& os)
_socketHandler->dumpState(os);
if (_inBuffer.size() > 0)
Util::dumpHex(os, "\t\tinBuffer:\n", "\t\t", _inBuffer);
if (_outBuffer.size() > 0)
_outBuffer.dumpHex(os, "\t\toutBuffer:\n", "\t\t");
_outBuffer.dumpHex(os, "\t\toutBuffer:\n", "\t\t");
}
void StreamSocket::send(Poco::Net::HTTPResponse& response)