mod admission;
pub(crate) mod budget;
pub mod client;
pub(crate) mod diff;
pub mod error;
pub(crate) mod filtered_car;
pub mod manager;
pub mod sparse;
pub(crate) mod spill;
#[cfg(test)]
pub(crate) mod test_util;
pub mod worker;
pub use worker::BackfillWorker;
use crate::types::{RepoState, RepoStatus};
/// the repo state a backfill writes. `after` is `before` plus the doc resolved before the
/// fetch and the fetched root, put onto `current`, the row as the persist read it on the repo's
/// shard, so a change made during the fetch survives
pub(crate) fn backfilled_state(
before: &RepoState<'static>,
mut after: RepoState<'static>,
current: RepoState<'static>,
) -> RepoState<'static> {
// the doc and the pds both answered when the fetch started, so an identity or account
// written during it is newer and stays
if !current.same_identity(before) {
after.set_identity(current.identity());
}
if current.account_written_since(before) {
after.active = current.active;
after.status = current.status.clone();
} else if !after.active {
// a pds only hands over an active account's repo, so one marked inactive before the
// fetch came back
after.active = true;
after.status = RepoStatus::Desynchronized;
}
let fetched = after.root.clone();
let behind = matches!(
(&fetched, &before.root),
(Some(fetched), Some(had)) if fetched.rev < had.rev
);
let mut state = after.rebased(before, current);
// the pds is the authority on the repo, so a car older than what we had still replaces the
// records. the root goes back with them, so the next commit shows the gap and backfills
// again, instead of landing on records it doesn't follow
if behind {
state.root = fetched;
}
state
}