1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
/// [`Epoch`] represents the period of time the global epoch value stays the same.
///
/// [`Epoch`] rotates [`u8`] values in a range of `[0..3]` while the crate itself functions
/// correctly if the range is limited to `[0..2]`. The one additional state is useful for users to
/// determine whether a certain memory chunk can be deallocated or not by using values returned
/// from [`Guard::epoch`](crate::Guard::epoch), e.g., if an [`Owned`](crate::Owned) was retired in
/// epoch `1`, then the [`Owned`](crate::Owned) will become completely unreachable in epoch `0`.
#[derive(Clone, Copy, Debug, Default, Eq, Ord, PartialEq, PartialOrd)]
pub struct Epoch {
value: u8,
}
impl Epoch {
/// This crates uses `4` epoch values.
const NUM_EPOCHS: u8 = 4;
/// Returns a future [`Epoch`] when the current readers will not be present.
///
/// The current [`Epoch`] may lag behind the global epoch value by `1`, therefore this method
/// returns an [`Epoch`] three epochs next to `self`.
///
/// ```
/// use sdd::Epoch;
///
/// let initial = Epoch::default();
///
/// let next_generation = initial.next_generation();
/// assert_eq!(next_generation, initial.next().next().next());
/// ```
#[inline]
#[must_use]
pub const fn next_generation(self) -> Epoch {
self.prev()
}
/// Returns the next [`Epoch`] value.
///
/// ```
/// use sdd::Epoch;
///
/// let initial = Epoch::default();
///
/// let next = initial.next();
/// assert!(initial < next);
///
/// let next_next = next.next();
/// assert!(next < next_next);
/// ```
#[inline]
#[must_use]
pub const fn next(self) -> Epoch {
Epoch {
value: (self.value + 1) % Self::NUM_EPOCHS,
}
}
/// Returns the previous [`Epoch`] value.
///
/// ```
/// use sdd::Epoch;
///
/// let initial = Epoch::default();
///
/// let prev = initial.prev();
/// assert!(initial < prev);
///
/// let prev_prev = prev.prev();
/// assert!(prev_prev < prev);
/// ```
#[inline]
#[must_use]
pub const fn prev(self) -> Epoch {
Epoch {
value: (self.value + Self::NUM_EPOCHS - 1) % Self::NUM_EPOCHS,
}
}
/// Construct an [`Epoch`] from a [`u8`] value.
#[inline]
pub(super) const fn from_u8(value: u8) -> Epoch {
Epoch { value }
}
}
impl From<Epoch> for u8 {
#[inline]
fn from(epoch: Epoch) -> Self {
epoch.value
}
}