use std::collections::{BTreeMap, BTreeSet};
use sim_lib_mutation::ManagedId;
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct FinalizationRecord {
pub registration: u64,
pub target: ManagedId,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
enum RegistrationState {
Registered,
Cancelled,
Admitted,
}
#[derive(Default)]
pub struct FinalizationRegistry {
next: u64,
entries: BTreeMap<u64, (ManagedId, RegistrationState)>,
}
impl FinalizationRegistry {
pub fn register(&mut self, target: ManagedId) -> u64 {
let id = self.next;
self.next = self.next.saturating_add(1);
self.entries
.insert(id, (target, RegistrationState::Registered));
id
}
pub fn cancel(&mut self, registration: u64) -> bool {
let Some((_, state)) = self.entries.get_mut(®istration) else {
return false;
};
if *state != RegistrationState::Registered {
return false;
}
*state = RegistrationState::Cancelled;
true
}
pub(crate) fn ready(&self, swept: &BTreeSet<ManagedId>) -> Vec<FinalizationRecord> {
self.entries
.iter()
.filter_map(|(®istration, &(target, state))| {
(state == RegistrationState::Registered && swept.contains(&target)).then_some(
FinalizationRecord {
registration,
target,
},
)
})
.collect()
}
pub(crate) fn mark_admitted(&mut self, records: &[FinalizationRecord]) {
for record in records {
if let Some((_, state)) = self.entries.get_mut(&record.registration) {
*state = RegistrationState::Admitted;
}
}
}
}