use std::collections::BTreeMap;
use std::task::Waker;
pub(crate) struct Subscriber<C> {
pub(crate) cursor: C,
pub(crate) waker: Option<Waker>,
}
pub(crate) struct SubscriberRegistry<C> {
entries: BTreeMap<u64, Subscriber<C>>,
next_id: u64,
}
impl<C> SubscriberRegistry<C> {
pub(crate) fn with_initial(cursor: C) -> Self {
let mut entries = BTreeMap::new();
entries.insert(
0,
Subscriber {
cursor,
waker: None,
},
);
Self {
entries,
next_id: 1,
}
}
pub(crate) fn register(&mut self, cursor: C) -> u64 {
let id = self.next_id;
self.next_id += 1;
self.entries.insert(
id,
Subscriber {
cursor,
waker: None,
},
);
id
}
pub(crate) fn remove(&mut self, id: u64) {
self.entries.remove(&id);
}
pub(crate) fn get_mut(&mut self, id: u64) -> Option<&mut Subscriber<C>> {
self.entries.get_mut(&id)
}
pub(crate) fn len(&self) -> usize {
self.entries.len()
}
pub(crate) fn cursors(&self) -> impl Iterator<Item = &C> {
self.entries.values().map(|subscriber| &subscriber.cursor)
}
pub(crate) fn drain_wakers(&mut self) -> Vec<Waker> {
self.entries
.values_mut()
.filter_map(|subscriber| subscriber.waker.take())
.collect()
}
}
pub(crate) fn wake_drained(wakers: Vec<Waker>) {
for waker in wakers {
waker.wake();
}
}