#ifndef _BUFFERS_HPP_ #define _BUFFERS_HPP_ #include #include "objpool.hpp" template struct MemBlock { unsigned char mem[BUFSIZE]; }; class StaticBuffer { public: StaticBuffer(unsigned char* buf, uint32_t sz, std::function cb) : buffer(buf), size(sz), release_cb(cb) {}; StaticBuffer(const StaticBuffer& sb) = delete; StaticBuffer(StaticBuffer&& sb) { buffer = sb.buffer; sb.buffer = nullptr; size = sb.size; sb.size = 0; release_cb = std::move(sb.release_cb); } ~StaticBuffer() { if(release_cb) release_cb(); } unsigned char* Data() { return buffer; } uint32_t Capacity() { return size; } protected: unsigned char* buffer = nullptr; uint32_t size = 0; std::function release_cb; }; class BufferMgr { public: StaticBuffer AllocStaticBuffer(uint32_t size) { if(size <= 128) { auto memblk = pool1.Alloc(); return StaticBuffer(memblk->mem, 128, [this, memblk]() { pool1.Recycle(memblk); }); } else if(size <= 1024) { auto memblk = pool2.Alloc(); return StaticBuffer(memblk->mem, 1024, [this, memblk]() { pool2.Recycle(memblk); }); } else if(size <= 4096) { auto memblk = pool3.Alloc(); return StaticBuffer(memblk->mem, 4096, [this, memblk]() { pool3.Recycle(memblk); }); } else { auto memblk = new unsigned char[size]; return StaticBuffer(memblk, size, [memblk]() { delete[] memblk; }); } } protected: ObjectPoolNoLock> pool1; ObjectPoolNoLock> pool2; ObjectPoolNoLock> pool3; }; #endif