use crate::MapletResult;
#[derive(Debug, Clone)]
pub struct DeletionManager {
instance_counts: std::collections::HashMap<u64, usize>,
slot_instances: std::collections::HashMap<usize, Vec<u64>>,
}
impl Default for DeletionManager {
fn default() -> Self {
Self::new()
}
}
impl DeletionManager {
#[must_use]
pub fn new() -> Self {
Self {
instance_counts: std::collections::HashMap::new(),
slot_instances: std::collections::HashMap::new(),
}
}
pub fn add_instance(&mut self, fingerprint: u64, slot: usize) {
*self.instance_counts.entry(fingerprint).or_insert(0) += 1;
self.slot_instances
.entry(slot)
.or_default()
.push(fingerprint);
}
pub fn remove_instance(&mut self, fingerprint: u64, slot: usize) -> MapletResult<bool> {
if let Some(count) = self.instance_counts.get_mut(&fingerprint)
&& *count > 0
{
*count -= 1;
if *count == 0 {
self.instance_counts.remove(&fingerprint);
}
if let Some(instances) = self.slot_instances.get_mut(&slot) {
instances.retain(|&fp| fp != fingerprint);
}
return Ok(true);
}
Ok(false)
}
#[must_use]
pub fn instance_count(&self, fingerprint: u64) -> usize {
self.instance_counts.get(&fingerprint).copied().unwrap_or(0)
}
#[must_use]
pub fn has_instances(&self, fingerprint: u64) -> bool {
self.instance_count(fingerprint) > 0
}
#[must_use]
pub fn get_slot_fingerprints(&self, slot: usize) -> Vec<u64> {
self.slot_instances.get(&slot).cloned().unwrap_or_default()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_deletion_manager() {
let mut manager = DeletionManager::new();
manager.add_instance(0x1234, 0);
manager.add_instance(0x1234, 1);
manager.add_instance(0x5678, 2);
assert_eq!(manager.instance_count(0x1234), 2);
assert_eq!(manager.instance_count(0x5678), 1);
assert!(manager.has_instances(0x1234));
assert!(manager.remove_instance(0x1234, 0).unwrap());
assert_eq!(manager.instance_count(0x1234), 1);
assert!(manager.remove_instance(0x1234, 1).unwrap());
assert_eq!(manager.instance_count(0x1234), 0);
assert!(!manager.has_instances(0x1234));
}
}