use std::hash::Hash;
use std::net::IpAddr;
use crate::bounds::{Key, Value};
use crate::clock::Timestamp;
use crate::entry::Entry;
use super::{version_hash, Replica};
impl<K: Key + Hash, V: Value> Replica<K, V> {
pub(crate) fn gc_remove(&self, key: &K) -> Option<Entry<Timestamp, V>> {
let mut guard = self.map.write();
self.live_tombstones.write().remove(key);
self.projection.write().remove(key);
guard.remove(key)
}
pub(crate) fn is_tombstone_stable(&self, key: &K, version: u64) -> bool {
let members = self.members.read();
if members.is_empty() {
return true;
}
let acks = self.tombstone_acks.read();
let Some(key_acks) = acks.get(key) else {
return false;
};
members
.iter()
.all(|peer| key_acks.get(peer) == Some(&version))
}
pub(crate) fn forget_tombstone(&self, key: &K) {
self.tombstone_acks.write().remove(key);
}
pub(crate) fn has_pending_tombstone_acks(&self, peer: IpAddr) -> bool {
let live = self.live_tombstones.read();
if live.is_empty() {
return false;
}
let map = self.map.read();
let acks = self.tombstone_acks.read();
live.iter().any(|key| {
let Some(entry) = map.get(key) else {
return false;
};
let version = version_hash(entry);
acks.get(key).and_then(|peer_acks| peer_acks.get(&peer)) != Some(&version)
})
}
}