ruapc-bufpool
A high-performance memory pool using the buddy memory allocation algorithm for efficient fixed-size buffer management. This crate is part of the ruapc project.
Features
- Buddy Memory Allocation: Efficiently manages memory in 64 MiB blocks, supporting allocation of 1 MiB, 4 MiB, 16 MiB, and 64 MiB buffers
- Both Sync and Async APIs: Designed for tokio environments with async-first design using
tokio::sync::Mutex - Automatic Memory Reclamation: Buffers are automatically returned to the pool when dropped with O(1) deallocation
- Memory Limits: Configurable maximum memory usage with async waiting when limits are reached
- Custom Allocators: Pluggable allocator trait for custom memory allocation backends
- O(1) Buddy Merging: Intrusive doubly-linked list with O(1) free/merge operations
- Zero Copy: Direct memory access through
Buffertype that implementsDeref<Target = [u8]> - Memory Efficient: Buffer struct optimized to 32 bytes using packed fields
Installation
Add this to your Cargo.toml:
[]
= "0.1"
Quick Start
Synchronous Allocation
use BufferPoolBuilder;
Asynchronous Allocation
use BufferPoolBuilder;
async
Custom Allocator
use ;
use Result;
;
Architecture
Buddy Memory Allocation
The pool uses a buddy memory allocation algorithm with 4 levels:
| Level | Size | Blocks per 64 MiB |
|---|---|---|
| 0 | 1 MiB | 64 |
| 1 | 4 MiB | 16 |
| 2 | 16 MiB | 4 |
| 3 | 64 MiB | 1 |
When allocating:
- Find the smallest level that can satisfy the request
- If no free buffer at that level, look for a larger one
- Split larger buffers into 4 smaller ones as needed
- Return the first available buffer
When freeing:
- Mark the buffer as free
- Check if all 4 sibling buffers are free
- If so, merge them into a larger buffer
- Repeat until no more merging is possible
Memory Management
- Each 64 MiB block maintains a bit-packed state array (22 bytes for 85 nodes)
- Free lists use intrusive doubly-linked lists for O(1) operations
- Buffer holds
Arc<BufferPool>reference, ensuring pool validity - Buffer drop directly acquires lock and deallocates with O(1) operation
Thread Safety
- Uses
tokio::sync::Mutexfor synchronization - Sync allocation uses
blocking_lock() - Async allocation uses
lock().await - Buffer drop handles both sync and async contexts intelligently
Buffer Memory Layout
The Buffer struct is optimized for minimal memory footprint (32 bytes):
ptr: 8 bytes (pointer to memory)pool: 8 bytes (Arc reference to pool)block: 8 bytes (pointer to buddy block)level: 1 byte (0-3, only 4 possible values)index: 1 byte (0-63, max index at level 0)- Padding: 6 bytes for alignment
Performance Considerations
- Allocation: O(log n) where n is the number of levels (constant in practice)
- Deallocation: O(log n) for merging, O(1) for just freeing
- Memory overhead: ~22 bytes state array + free list nodes per 64 MiB block
- Best for: Large buffers (1+ MiB), frequent allocation/deallocation patterns
API Reference
See the documentation on docs.rs for detailed API reference.
License
Licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.