use crate::formats::CoordSource;
use crate::LngLat;
#[cfg(feature = "batch")]
use super::parallel;
use super::sequential::{pairwise_haversine_any_extend, pairwise_haversine_iter_extend};
pub struct BufferPool {
buffers: Vec<Vec<f64>>,
initial_capacity: usize,
max_pool_size: usize,
}
impl BufferPool {
pub fn new(initial_capacity: usize) -> Self {
Self {
buffers: Vec::new(),
initial_capacity,
max_pool_size: 8,
}
}
pub fn with_max_size(initial_capacity: usize, max_pool_size: usize) -> Self {
Self {
buffers: Vec::new(),
initial_capacity,
max_pool_size,
}
}
pub fn get_buffer(&mut self) -> Vec<f64> {
self.buffers
.pop()
.unwrap_or_else(|| Vec::with_capacity(self.initial_capacity))
}
pub fn return_buffer(&mut self, mut buffer: Vec<f64>) {
if self.buffers.len() < self.max_pool_size {
buffer.clear();
self.buffers.push(buffer);
}
}
pub fn with_buffer<F, R>(&mut self, f: F) -> R
where
F: FnOnce(&mut Vec<f64>) -> R,
{
let mut buffer = self.get_buffer();
let result = f(&mut buffer);
self.return_buffer(buffer);
result
}
pub fn pairwise_haversine_iter<I>(&mut self, iter: I) -> Vec<f64>
where
I: Iterator<Item = LngLat>,
{
let mut result = self.get_buffer();
pairwise_haversine_iter_extend(iter, &mut result);
result
}
pub fn pairwise_haversine_any<T: CoordSource>(&mut self, coords: &T) -> Vec<f64> {
let mut result = self.get_buffer();
pairwise_haversine_any_extend(coords, &mut result);
result
}
#[cfg(feature = "batch")]
pub fn pairwise_haversine_par_iter<I>(&mut self, iter: I) -> Vec<f64>
where
I: Iterator<Item = LngLat>,
{
let mut result = self.get_buffer();
parallel::pairwise_haversine_par_iter_extend(iter, &mut result);
result
}
#[cfg(feature = "batch")]
pub fn pairwise_haversine_par_any<T: CoordSource + Sync>(&mut self, coords: &T) -> Vec<f64> {
let mut result = self.get_buffer();
parallel::pairwise_haversine_par_any_extend(coords, &mut result);
result
}
pub fn pool_size(&self) -> usize {
self.buffers.len()
}
pub fn clear_pool(&mut self) {
self.buffers.clear();
}
}