34 (void)initial_pool_size;
37 static constexpr std::array<size_t, 4> BUCKET_SIZES = {
44 for (
size_t i = 0; i < buckets_.size(); ++i) {
45 buckets_[i].size_ = BUCKET_SIZES[i];
46 buckets_[i].capacity_ = max_pool_size / buckets_.size();
47 buckets_[i].buffers_.reserve(buckets_[i].capacity_);
57 auto buffer = create_buffer(size);
59 total_allocations_.fetch_add(1, std::memory_order_relaxed);
63 auto& bucket = get_bucket(size);
64 return acquire_from_bucket(bucket);
68 return acquire(
static_cast<size_t>(buffer_size));
81 auto& bucket = get_bucket(size);
82 release_to_bucket(bucket, std::move(buffer));
88 stats.
pool_hits = pool_hits_.load(std::memory_order_relaxed);
93 size_t total = total_allocations_.load(std::memory_order_relaxed);
94 if (total == 0)
return 0.0;
96 size_t hits = pool_hits_.load(std::memory_order_relaxed);
97 return static_cast<double>(hits) /
static_cast<double>(total);
107 size_t total_allocs = total_allocations_.load(std::memory_order_relaxed);
108 size_t current_usage = total_allocs * 4096;
109 return std::make_pair(current_usage, current_usage);
131 MemoryPool::PoolBucket& MemoryPool::get_bucket(
size_t size) {
return buckets_[get_bucket_index(size)]; }
133 size_t MemoryPool::get_bucket_index(
size_t size)
const {
141 std::unique_ptr<uint8_t[]> MemoryPool::acquire_from_bucket(PoolBucket& bucket) {
142 std::unique_ptr<uint8_t[]> buffer;
145 std::lock_guard<std::mutex> lock(bucket.mutex_);
148 if (!bucket.buffers_.empty()) {
149 buffer = std::move(bucket.buffers_.back());
150 bucket.buffers_.pop_back();
155 pool_hits_.fetch_add(1, std::memory_order_relaxed);
156 total_allocations_.fetch_add(1, std::memory_order_relaxed);
161 buffer = create_buffer(bucket.size_);
163 total_allocations_.fetch_add(1, std::memory_order_relaxed);
169 void MemoryPool::release_to_bucket(PoolBucket& bucket, std::unique_ptr<uint8_t[]> buffer) {
171 std::lock_guard<std::mutex> lock(bucket.mutex_);
174 if (bucket.buffers_.size() < bucket.capacity_) {
175 bucket.buffers_.push_back(std::move(buffer));
185 std::unique_ptr<uint8_t[]> MemoryPool::create_buffer(
size_t size) {
186 uint8_t* raw_buffer =
new (std::nothrow) uint8_t[size];
190 throw std::bad_alloc();
192 return std::unique_ptr<uint8_t[]>(raw_buffer);
195 void MemoryPool::validate_size(
size_t size)
const {
196 if (size == 0 || size > 64 * 1024 * 1024) {
197 throw std::invalid_argument(
"Invalid buffer size");
205 MemoryPool::PoolBucket::PoolBucket(PoolBucket&& other) noexcept
206 : buffers_(std::move(other.buffers_)), mutex_(), size_(other.size_), capacity_(other.capacity_) {
211 MemoryPool::PoolBucket& MemoryPool::PoolBucket::operator=(PoolBucket&& other) noexcept {
212 if (
this != &other) {
213 buffers_ = std::move(other.buffers_);
215 capacity_ = other.capacity_;
232 : size_(static_cast<size_t>(buffer_size)), pool_(&
GlobalMemoryPool::instance()) {
233 buffer_ = pool_->
acquire(size_);
237 if (buffer_ && pool_) {
238 pool_->
release(std::move(buffer_), size_);
243 : buffer_(std::move(other.buffer_)), size_(other.size_), pool_(other.pool_) {
244 other.buffer_ =
nullptr;
246 other.pool_ =
nullptr;
250 if (
this != &other) {
251 if (buffer_ && pool_) {
253 pool_->release(std::move(buffer_), size_);
259 buffer_ = std::move(other.buffer_);
263 other.buffer_ =
nullptr;
265 other.pool_ =
nullptr;
281 if (!buffer_ || index >= size_) {
282 throw std::out_of_range(
"Buffer index out of range");
284 return buffer_[index];
288 if (!buffer_ || index >= size_) {
289 throw std::out_of_range(
"Buffer index out of range");
291 return buffer_[index];
294 void PooledBuffer::check_bounds(
size_t index)
const {
295 if (!buffer_ || index >= size_) {
296 throw std::out_of_range(
"Buffer index out of range");
Global memory pool instance.
double get_hit_rate() const
void resize_pool(size_t new_size)
std::pair< size_t, size_t > get_memory_usage() const
MemoryPool(size_t initial_pool_size=400, size_t max_pool_size=2000)
std::unique_ptr< uint8_t[]> acquire(size_t size)
PoolStats get_stats() const
void cleanup_old_buffers(std::chrono::milliseconds max_age=std::chrono::minutes(5))
HealthMetrics get_health_metrics() const
void release(std::unique_ptr< uint8_t[]> buffer, size_t size)
RAII wrapper for memory pool buffers with enhanced safety.
PooledBuffer(size_t size)
uint8_t & operator[](size_t index)
PooledBuffer & operator=(const PooledBuffer &)=delete
uint8_t & at(size_t index)
#define MEMORY_TRACK_DEALLOCATION(ptr)
#define MEMORY_TRACK_ALLOCATION(ptr, size)