#[cfg(feature = "arena")]
use bumpalo::Bump;
#[cfg(not(feature = "std"))]
use alloc::string::String;
#[cfg(feature = "std")]
use std::time::Instant;
use super::{config::MemoryPoolConfig, stats::MemoryStats};
#[derive(Debug)]
pub struct MemoryPool {
pub(super) config: MemoryPoolConfig,
#[cfg(feature = "arena")]
pub(super) primary_arena: Bump,
#[cfg(feature = "arena")]
pub(super) temp_arena: Bump,
pub(super) stats: MemoryStats,
pub(super) ops_since_reset: usize,
#[cfg(feature = "std")]
pub(super) last_gc: Option<Instant>,
pub(super) memory_at_last_gc: usize,
}
impl MemoryPool {
pub fn new() -> Self {
Self::with_config(MemoryPoolConfig::default())
}
pub fn with_config(config: MemoryPoolConfig) -> Self {
Self {
config,
#[cfg(feature = "arena")]
primary_arena: Bump::new(),
#[cfg(feature = "arena")]
temp_arena: Bump::new(),
stats: MemoryStats::default(),
ops_since_reset: 0,
#[cfg(feature = "std")]
last_gc: None,
memory_at_last_gc: 0,
}
}
#[cfg(feature = "arena")]
#[must_use]
pub fn primary_arena(&self) -> &Bump {
&self.primary_arena
}
#[cfg(feature = "arena")]
pub fn primary_arena_mut(&mut self) -> &mut Bump {
self.ops_since_reset += 1;
self.check_reset_conditions();
&mut self.primary_arena
}
#[cfg(feature = "arena")]
#[must_use]
pub fn temp_arena(&self) -> &Bump {
&self.temp_arena
}
#[cfg(feature = "arena")]
pub fn temp_arena_mut(&mut self) -> &mut Bump {
&mut self.temp_arena
}
#[cfg(feature = "arena")]
pub fn reset_primary_arena(&mut self) {
self.primary_arena.reset();
self.stats.arena_resets += 1;
self.ops_since_reset = 0;
self.update_memory_stats();
}
#[cfg(feature = "arena")]
pub fn reset_temp_arena(&mut self) {
self.temp_arena.reset();
self.update_memory_stats();
}
#[cfg(feature = "arena")]
pub fn reset_all_arenas(&mut self) {
self.reset_primary_arena();
self.reset_temp_arena();
}
#[must_use]
pub fn stats(&self) -> &MemoryStats {
&self.stats
}
#[must_use]
pub fn memory_usage_string(&self) -> String {
let mb = self.stats.memory_in_use as f64 / (1024.0 * 1024.0);
format!("{mb:.2}MB")
}
#[must_use]
pub fn is_memory_usage_acceptable(&self) -> bool {
self.stats.memory_in_use <= self.config.max_arena_size
}
pub fn set_config(&mut self, config: MemoryPoolConfig) {
self.config = config;
}
#[must_use]
pub fn config(&self) -> &MemoryPoolConfig {
&self.config
}
}
impl Default for MemoryPool {
fn default() -> Self {
Self::new()
}
}