use fastalloc::{GrowingPool, GrowthStrategy, PoolConfig};
#[test]
fn test_linear_growth() {
let config = PoolConfig::builder()
.capacity(10)
.growth_strategy(GrowthStrategy::Linear { amount: 5 })
.build()
.unwrap();
let pool = GrowingPool::<i32>::with_config(config).unwrap();
assert_eq!(pool.capacity(), 10);
let mut handles = Vec::new();
for i in 0..10 {
handles.push(pool.allocate(i).unwrap());
}
handles.push(pool.allocate(10).unwrap());
assert_eq!(pool.capacity(), 15);
for i in 11..16 {
handles.push(pool.allocate(i).unwrap());
}
assert_eq!(pool.capacity(), 20);
}
#[test]
fn test_exponential_growth() {
let config = PoolConfig::builder()
.capacity(10)
.growth_strategy(GrowthStrategy::Exponential { factor: 2.0 })
.build()
.unwrap();
let pool = GrowingPool::<i32>::with_config(config).unwrap();
let mut handles = Vec::new();
for i in 0..10 {
handles.push(pool.allocate(i).unwrap());
}
assert_eq!(pool.capacity(), 10);
handles.push(pool.allocate(10).unwrap());
assert_eq!(pool.capacity(), 20);
for i in 11..21 {
handles.push(pool.allocate(i).unwrap());
}
assert_eq!(pool.capacity(), 40);
}
#[test]
fn test_custom_growth() {
let config = PoolConfig::builder()
.capacity(10)
.growth_strategy(GrowthStrategy::Custom {
compute: Box::new(|current| current / 2),
})
.build()
.unwrap();
let pool = GrowingPool::<i32>::with_config(config).unwrap();
let mut handles = Vec::new();
for i in 0..10 {
handles.push(pool.allocate(i).unwrap());
}
handles.push(pool.allocate(10).unwrap());
assert_eq!(pool.capacity(), 15);
}
#[test]
fn test_no_growth_behaves_like_fixed() {
let config = PoolConfig::builder()
.capacity(5)
.growth_strategy(GrowthStrategy::None)
.build()
.unwrap();
let pool = GrowingPool::<i32>::with_config(config).unwrap();
let mut handles = Vec::new();
for i in 0..5 {
handles.push(pool.allocate(i).unwrap());
}
assert_eq!(pool.capacity(), 5);
assert!(pool.is_full());
let result = pool.allocate(5);
assert!(result.is_err());
}
#[test]
fn test_max_capacity_limit() {
let config = PoolConfig::builder()
.capacity(5)
.max_capacity(Some(10))
.growth_strategy(GrowthStrategy::Linear { amount: 10 })
.build()
.unwrap();
let pool = GrowingPool::<i32>::with_config(config).unwrap();
let mut handles = Vec::new();
for i in 0..5 {
handles.push(pool.allocate(i).unwrap());
}
for i in 5..10 {
handles.push(pool.allocate(i).unwrap());
}
assert_eq!(pool.capacity(), 10);
let result = pool.allocate(10);
assert!(result.is_err());
}
#[test]
fn test_growth_with_deallocation() {
let config = PoolConfig::builder()
.capacity(5)
.growth_strategy(GrowthStrategy::Linear { amount: 5 })
.build()
.unwrap();
let pool = GrowingPool::<i32>::with_config(config).unwrap();
let mut handles = Vec::new();
for i in 0..10 {
handles.push(pool.allocate(i).unwrap());
}
assert_eq!(pool.capacity(), 10);
handles.drain(0..5);
assert_eq!(pool.allocated(), 5);
assert_eq!(pool.available(), 5);
for i in 10..15 {
handles.push(pool.allocate(i).unwrap());
}
assert_eq!(pool.capacity(), 10); assert_eq!(pool.allocated(), 10);
}
#[test]
fn test_multiple_growth_cycles() {
let config = PoolConfig::builder()
.capacity(2)
.max_capacity(Some(100))
.growth_strategy(GrowthStrategy::Exponential { factor: 2.0 })
.build()
.unwrap();
let pool = GrowingPool::<i32>::with_config(config).unwrap();
let mut handles = Vec::new();
let expected_capacities = vec![2, 4, 8, 16, 32, 64];
for (cycle, &expected_cap) in expected_capacities.iter().enumerate() {
while pool.allocated() < expected_cap {
handles.push(pool.allocate(cycle as i32).unwrap());
}
assert_eq!(pool.capacity(), expected_cap);
}
}