use super::{ObjectId, ValidationMetadata};
pub(super) const EXCLUDED: u8 = 1;
pub(super) const CANDIDATE: u8 = 2;
pub(super) const PENDING: u8 = 4;
pub(super) const DONE: u8 = 8;
pub(super) const BORDER: u8 = 16;
pub(super) const UNSHALLOW: u8 = 32;
pub(super) const CLIENT_SHALLOW: u8 = 64;
#[derive(Clone, Copy, Debug)]
pub struct RevisionLimits {
pub max_exclusions: usize,
}
#[derive(Clone, Copy, Debug, Default)]
pub struct RevisionOptions {
pub since: Option<u64>,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum ShallowChange {
Shallow(ObjectId),
Unshallow(ObjectId),
}
pub struct RevisionState<'a> {
pub(super) states: &'a mut [u8],
pub(super) limits: RevisionLimits,
pub(super) count: usize,
}
impl<'a> RevisionState<'a> {
pub fn new(states: &'a mut [u8], limits: RevisionLimits) -> Self {
Self {
states,
limits,
count: 0,
}
}
pub fn max_exclusions(&self) -> usize {
self.limits.max_exclusions
}
pub fn changes<'b>(
&'b self,
objects: &'b [Option<ValidationMetadata>],
) -> impl Iterator<Item = ShallowChange> + 'b {
self.states
.iter()
.zip(objects)
.take(self.count)
.filter_map(|(&state, object)| revision_change(state, object.as_ref()?.id))
}
}
fn revision_change(state: u8, id: ObjectId) -> Option<ShallowChange> {
if state & (BORDER | CLIENT_SHALLOW) == BORDER {
Some(ShallowChange::Shallow(id))
} else if state & UNSHALLOW != 0 {
Some(ShallowChange::Unshallow(id))
} else {
None
}
}
pub(super) fn mark_unshallow(states: &mut [u8]) {
for state in states {
if *state & (CLIENT_SHALLOW | CANDIDATE | BORDER) == (CLIENT_SHALLOW | CANDIDATE) {
*state |= UNSHALLOW;
}
}
}