use std::thread;
use crate::pool::{BufferPool, PoolState};
use crate::size_class::ClassTable;
const DEFAULT_MIN_BUFFER_SIZE: usize = 4 * 1024;
const fn default_tls_cache_size(num_cpus: usize) -> usize {
match num_cpus {
0..=2 => 2,
3..=4 => 4,
5..=8 => 6,
_ => 8,
}
}
const fn default_max_buffers_per_class(num_cpus: usize) -> usize {
const BASE: usize = 32;
let scaling = match num_cpus {
0..16 => 1,
16..32 => 2,
32..64 => 3,
_ => 4,
};
BASE * scaling
}
const fn default_batch_size(tls_cache_size: usize) -> usize {
let half = tls_cache_size / 2;
if half < 2 { 2 } else { half }
}
#[derive(Debug, Clone, Default)]
pub struct Builder {
tls_cache_size: Option<usize>,
max_buffers_per_class: Option<usize>,
min_buffer_size: Option<usize>,
pinned_memory: Option<bool>,
batch_size: Option<usize>,
}
impl Builder {
pub fn min_buffer_size(mut self, size: usize) -> Self {
self.min_buffer_size = Some(size);
self
}
pub fn tls_cache_size(mut self, size: usize) -> Self {
self.tls_cache_size = Some(size);
self
}
pub fn max_buffers_per_class(mut self, count: usize) -> Self {
self.max_buffers_per_class = Some(count);
self
}
pub fn pinned_memory(mut self, enabled: bool) -> Self {
self.pinned_memory = Some(enabled);
self
}
pub fn batch_size(mut self, size: usize) -> Self {
self.batch_size = Some(size);
self
}
pub fn build(self) -> BufferPool {
let num_cpus = thread::available_parallelism().map_or(4, std::num::NonZero::get);
let tls_cache_size =
self.tls_cache_size.unwrap_or_else(|| default_tls_cache_size(num_cpus));
let max_buffers_per_class = self
.max_buffers_per_class
.unwrap_or_else(|| default_max_buffers_per_class(num_cpus));
assert!(tls_cache_size > 0, "tls_cache_size must be > 0");
assert!(max_buffers_per_class > 0, "max_buffers_per_class must be > 0");
let batch_size = self.batch_size.unwrap_or_else(|| default_batch_size(tls_cache_size));
BufferPool::from_state(PoolState {
id: BufferPool::next_id(),
table: ClassTable::new(max_buffers_per_class),
tls_cache_size,
min_buffer_size: self.min_buffer_size.unwrap_or(DEFAULT_MIN_BUFFER_SIZE),
pinned_memory: self.pinned_memory.unwrap_or(false),
batch_size,
})
}
}