impl PooledBuffer {
fn new(data: Vec<u8>, pool_type: PoolType, manager: Arc<MemoryManager>) -> Self {
Self {
data,
pool_type,
manager: Some(manager),
}
}
#[must_use]
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub fn as_slice(&self) -> &[u8] {
&self.data
}
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub fn as_mut_slice(&mut self) -> &mut [u8] {
&mut self.data
}
#[must_use]
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub fn capacity(&self) -> usize {
self.data.capacity()
}
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub fn resize(&mut self, new_size: usize) {
self.data.resize(new_size, 0);
}
}
impl Drop for PooledBuffer {
fn drop(&mut self) {
if let Some(manager) = self.manager.take() {
manager.return_buffer(self.pool_type, std::mem::take(&mut self.data));
}
}
}
impl StringInterner {
fn new(max_size: usize) -> Self {
Self {
strings: RwLock::new(FxHashSet::default()),
total_size: Mutex::new(0),
max_size,
}
}
fn intern(&self, s: &str) -> Result<Arc<str>> {
{
let strings = self.strings.read();
if let Some(existing) = strings.get(s) {
return Ok(Arc::clone(existing));
}
}
{
let current_size = *self.total_size.lock();
if current_size + s.len() > self.max_size {
return Err(anyhow!("String interning pool exhausted"));
}
}
let mut strings = self.strings.write();
let mut total_size = self.total_size.lock();
if let Some(existing) = strings.get(s) {
return Ok(Arc::clone(existing));
}
let arc_str: Arc<str> = Arc::from(s);
*total_size += s.len();
strings.insert(Arc::clone(&arc_str));
Ok(arc_str)
}
fn memory_usage(&self) -> usize {
*self.total_size.lock()
}
fn clear(&self) {
self.strings.write().clear();
*self.total_size.lock() = 0;
}
}
impl MemoryPool {
fn new(max_size: usize) -> Self {
Self {
buffers: Mutex::new(VecDeque::new()),
total_size: Mutex::new(0),
max_size,
allocation_count: Mutex::new(0),
reuse_count: Mutex::new(0),
}
}
fn get_buffer(&self, min_size: usize) -> Vec<u8> {
let mut buffers = self.buffers.lock();
let mut total_size = self.total_size.lock();
if let Some(mut buffer) = buffers.pop_front() {
if buffer.capacity() >= min_size {
buffer.clear();
buffer.resize(min_size, 0);
*self.reuse_count.lock() += 1;
return buffer;
}
*total_size -= buffer.capacity();
}
*self.allocation_count.lock() += 1;
let mut buffer = Vec::with_capacity(min_size.max(4096)); buffer.resize(min_size, 0);
*total_size += buffer.capacity();
buffer
}
fn return_buffer(&self, mut buffer: Vec<u8>) {
let mut buffers = self.buffers.lock();
let total_size = self.total_size.lock();
if *total_size + buffer.capacity() > self.max_size {
return;
}
buffer.clear();
buffers.push_back(buffer);
}
fn stats(&self) -> PoolStats {
let buffers = self.buffers.lock();
let total_size = *self.total_size.lock();
let allocation_count = *self.allocation_count.lock();
let reuse_count = *self.reuse_count.lock();
PoolStats {
buffer_count: buffers.len(),
total_size,
allocation_count,
reuse_count,
reuse_ratio: if allocation_count > 0 {
reuse_count as f64 / allocation_count as f64
} else {
0.0
},
}
}
fn clear(&self) {
self.buffers.lock().clear();
*self.total_size.lock() = 0;
}
}