use std::sync::Arc;
use crate::timing_wheel::entry::Entry;
#[derive(Debug, Default)]
pub(crate) struct Bucket {
expiration_ms: Option<u64>,
entries: Vec<Arc<Entry>>,
}
impl Bucket {
pub(crate) fn expiration_ms(&self) -> Option<u64> {
self.expiration_ms
}
pub(crate) fn set_expiration_ms(&mut self, expiration_ms: u64) -> bool {
if self.expiration_ms == Some(expiration_ms) {
return false;
}
self.expiration_ms = Some(expiration_ms);
true
}
pub(crate) fn add(&mut self, entry: Arc<Entry>) {
self.entries.push(entry);
}
pub(crate) fn drain(&mut self) -> Vec<Arc<Entry>> {
self.expiration_ms = None;
std::mem::take(&mut self.entries)
}
}
#[cfg(test)]
mod tests {
use std::sync::Arc;
use crate::timing_wheel::entry::Entry;
use crate::timing_wheel::state::TimeoutState;
use super::Bucket;
#[test]
fn bucket_drains_entries_and_clears_expiration() {
let mut bucket = Bucket::default();
let entry = Arc::new(Entry::new(1, 10, Arc::new(TimeoutState::scheduled())));
assert!(bucket.set_expiration_ms(10));
bucket.add(Arc::clone(&entry));
assert_eq!(bucket.drain().len(), 1);
assert_eq!(bucket.expiration_ms(), None);
assert!(bucket.drain().is_empty());
}
}