#[derive(Copy, Clone)]
pub(crate) struct SparseEntry {
dense_index_or_next_free: usize,
epoch_or_next_epoch: usize,
}
const DEAD_BIT: usize = 1 << (size_of::<usize>() * 8 - 1);
pub(crate) const MAX_SPARSE_INDEX: usize = DEAD_BIT - 1;
pub(crate) const MAX_EPOCH: usize = usize::MAX;
impl SparseEntry {
pub(crate) fn new_alive(dense_index: usize, epoch: usize) -> Self {
Self {
dense_index_or_next_free: dense_index,
epoch_or_next_epoch: epoch,
}
}
pub(crate) fn mark_free(&mut self, next_free: usize) {
debug_assert!(self.is_alive());
self.dense_index_or_next_free = next_free | DEAD_BIT;
self.epoch_or_next_epoch = usize::wrapping_add(self.epoch_or_next_epoch, 1);
}
pub(crate) fn replace_pointed_to_value(&mut self, new_dense_index: usize) {
debug_assert!(self.is_alive());
self.dense_index_or_next_free = new_dense_index;
}
pub(crate) fn is_alive(&self) -> bool {
self.dense_index_or_next_free & DEAD_BIT == 0
}
pub(crate) fn dense_index(&self) -> usize {
debug_assert!(self.is_alive());
self.dense_index_or_next_free
}
pub(crate) fn epoch(&self) -> usize {
debug_assert!(self.is_alive());
self.epoch_or_next_epoch
}
pub(crate) fn next_free(&self) -> usize {
debug_assert!(!self.is_alive());
self.dense_index_or_next_free & !DEAD_BIT
}
pub(crate) fn next_epoch(&self) -> usize {
debug_assert!(!self.is_alive());
self.epoch_or_next_epoch
}
pub(crate) fn set_dense_index(&mut self, dense_index: usize) {
debug_assert!(self.is_alive());
self.dense_index_or_next_free = dense_index;
}
pub(crate) fn dense_index_move_left(&mut self) {
debug_assert!(self.is_alive());
self.dense_index_or_next_free -= 1;
}
}