use crate::SyncCompletion;
use futures::FutureExt as _;
pub(crate) struct Barrier {
boundary: u64,
pending: Option<(u64, SyncCompletion)>,
}
impl Barrier {
pub(crate) const fn new(boundary: u64) -> Self {
Self {
boundary,
pending: None,
}
}
pub(crate) fn boundary(&mut self) -> u64 {
self.observe();
self.boundary
}
fn observe(&mut self) {
let Some((boundary, completion)) = &mut self.pending else {
return;
};
let Some(result) = completion.now_or_never() else {
return;
};
if result.is_ok() {
self.boundary = self.boundary.max(*boundary);
}
self.pending = None;
}
pub(crate) const fn settled(&self) -> bool {
self.pending.is_none()
}
pub(crate) fn mark_durable(&mut self, boundary: u64) {
self.boundary = self.boundary.max(boundary);
if matches!(self.pending, Some((pending, _)) if pending <= boundary) {
self.pending = None;
}
}
pub(crate) fn record(&mut self, boundary: u64, completion: SyncCompletion) {
self.observe();
self.pending = Some((boundary, completion));
}
pub(crate) fn truncate(&mut self, boundary: u64) {
self.boundary = self.boundary.min(boundary);
self.pending = None;
}
}