use alloc::collections::BinaryHeap;
use core::cmp::Reverse;
#[derive(Clone, Debug, Default)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
pub struct IdPool {
free_ids: BinaryHeap<Reverse<u32>>,
next_index: u32,
}
impl IdPool {
#[inline(always)]
pub const fn new() -> Self {
Self {
free_ids: BinaryHeap::new(),
next_index: 0,
}
}
#[inline(always)]
pub fn with_capacity(capacity: usize) -> Self {
Self {
free_ids: BinaryHeap::with_capacity(capacity),
next_index: 0,
}
}
#[inline(always)]
pub fn alloc(&mut self) -> u32 {
if let Some(id) = self.free_ids.pop() {
id.0
} else {
let id = self.next_index;
self.next_index += 1;
id
}
}
#[inline(always)]
pub fn free(&mut self, id: u32) {
debug_assert!(id < self.next_index);
self.free_ids.push(Reverse(id));
}
#[inline(always)]
pub fn clear(&mut self) {
self.free_ids.clear();
self.next_index = 0;
}
#[inline(always)]
pub fn next_id(&self) -> u32 {
if let Some(id) = self.free_ids.peek() {
id.0
} else {
self.next_index
}
}
#[inline(always)]
pub fn len(&self) -> usize {
self.next_index as usize - self.free_ids.len()
}
#[inline(always)]
pub fn free_len(&self) -> usize {
self.free_ids.len()
}
#[inline(always)]
pub fn total_len(&self) -> usize {
self.next_index as usize
}
#[inline(always)]
pub fn is_empty(&self) -> bool {
self.len() == 0
}
}