use lilypads::Pond;
#[test]
fn alloc() {
let mut pool = Pond::new();
let idx1 = pool.alloc(42);
let idx2 = pool.alloc(123);
assert_eq!(*pool.get(idx1).unwrap(), 42);
assert_eq!(*pool.get(idx2).unwrap(), 123);
}
#[test]
fn get() {
let mut pool = Pond::new();
let idx = pool.alloc(42);
assert_eq!(*pool.get(idx).unwrap(), 42);
assert_eq!(pool.get(idx + 1), None);
}
#[test]
fn mut_get() {
let mut pool = Pond::new();
let idx = pool.alloc(42);
let data2 = pool.get_mut(idx).unwrap();
*data2 = 13;
assert_eq!(*pool.get(idx).unwrap(), 13);
}
#[test]
fn free() {
let mut pool = Pond::new();
let idx = pool.alloc(42);
assert_eq!(*pool.get(idx).unwrap(), 42);
pool.free(idx);
assert_eq!(pool.get(idx), None);
assert_eq!(pool.free(idx), None);
}
#[test]
fn write() {
let mut pool = Pond::new();
let idx = pool.alloc(42);
let old = pool.write(idx, 155).unwrap();
assert_eq!(old, 42);
assert_eq!(*pool.get(idx).unwrap(), 155);
let idx2 = 13;
pool.write(idx2, 29);
assert_eq!(*pool.get(idx2).unwrap(), 29);
}
#[test]
fn memory_reuse() {
let mut pool = Pond::new();
let idx1 = pool.alloc(1);
let idx2 = pool.alloc(2);
pool.free(idx1);
let idx3 = pool.alloc(3);
assert_eq!(idx1, idx3);
assert_eq!(*pool.get(idx2).unwrap(), 2);
assert_eq!(*pool.get(idx3).unwrap(), 3);
}
#[test]
fn defrag() {
let mut pool = Pond::new();
let mut indices: Vec<_> = (0..5).map(|i| pool.alloc(i) ).collect();
pool.free(indices[1]).unwrap();
pool.free(indices[3]).unwrap();
let remapped = pool.defrag();
for (old, new) in remapped.iter() { indices[*old] = *new }
assert_eq!(*pool.get(indices[0]).unwrap(), 0);
assert_eq!(*pool.get(indices[2]).unwrap(), 2);
assert_eq!(*pool.get(indices[4]).unwrap(), 4);
assert_eq!(pool.next_allocated(), 3);
}
#[test]
fn trim_normal() {
let mut pool = Pond::new();
let mut indices: Vec<_> = (0..5).map(|i| pool.alloc(i)).collect();
pool.free(indices[3]).unwrap();
pool.free(indices[4]).unwrap();
let remapped = pool.trim();
for (old, new) in remapped.iter() { indices[*old] = *new }
assert!(matches!(pool.get(2), Some(_)));
assert!(matches!(pool.get(3), None));
assert_eq!(pool.next_allocated(), 3);
assert_eq!(*pool.get(indices[0]).unwrap(), 0);
assert_eq!(*pool.get(indices[1]).unwrap(), 1);
assert_eq!(*pool.get(indices[2]).unwrap(), 2);
}
#[test]
fn trim_all_free() {
let mut pool = Pond::new();
let idx1 = pool.alloc(1);
let idx2 = pool.alloc(2);
pool.free(idx1).unwrap();
pool.free(idx2).unwrap();
_ = pool.trim();
assert_eq!(pool.get(0), None);
assert_eq!(pool.next_allocated(), 0);
}
#[test]
fn trim_empty() {
let mut pool = Pond::<i32>::new();
_ = pool.trim();
assert_eq!(pool.get(0), None);
assert_eq!(pool.next_allocated(), 0);
}
#[test]
fn trim_free() {
let mut pool = Pond::<i32>::new();
pool.resize(16);
_ = pool.trim();
assert_eq!(pool.get(0), None);
assert_eq!(pool.next_allocated(), 0);
}
#[test]
fn stress() {
const N: u32 = 1_000_000;
let mut pool = Pond::new();
pool.resize(N as usize);
for i in 0..N { let _ = pool.alloc(i); }
}