···5566use crate::error::Result;
77use crate::storage::{DbRef, keys};
88+use crate::sync::resync::RepoSnapshot;
89910/// Insert a `(collection, did)` pair into both the rbc and cbr indexes.
1011pub fn insert(db: &DbRef, did: Did<'_>, collection: Nsid<'_>) -> Result<()> {
···2425 Ok(())
2526}
26272727-/// Remove all index entries for `did` (account deletion / full resync).
2828+/// Remove all index entries for `did` (account deletion).
2829///
2930/// Reads all collections from the cbr index, then deletes both sides in a batch.
3031pub fn remove_all(db: &DbRef, did: Did<'_>) -> Result<()> {
···5455/// Iterate over DIDs in the rbc index for `collection`, starting after `cursor`.
5556///
5657/// Returns at most `limit` DIDs.
5858+///
5959+/// TODO: we can fjall range to the collection's next-after-max (might even be
6060+/// exposed now?) or maybe use prefix + seek for the start?
5761pub fn scan_rbc(
5862 db: &DbRef,
5963 collection: Nsid<'_>,
···9094 }
9195 Ok(dids)
9296}
9797+9898+/// Iterate over DIDs in the rbc index for `collection`, starting after `cursor`.
9999+///
100100+/// Returns at most `limit` DIDs.
101101+///
102102+/// TODO: we can fjall range to the collection's next-after-max (might even be
103103+/// exposed now?) or maybe use prefix + seek for the start?
104104+pub fn scan_cbr(
105105+ db: &DbRef,
106106+ did: Did<'_>,
107107+ cursor: Option<Nsid<'_>>,
108108+ limit: usize,
109109+) -> Result<Vec<Nsid<'static>>> {
110110+ let prefix = keys::cbr_prefix(did.clone());
111111+ let prefix_len = prefix.len();
112112+113113+ let start_key: Vec<u8> = match cursor {
114114+ None => prefix.clone(),
115115+ Some(ref col) => keys::cbr(did.clone(), col.clone()),
116116+ };
117117+118118+ let mut cols = Vec::with_capacity(limit);
119119+ for guard in db.cbr.range(start_key..) {
120120+ let (k, _v) = guard.into_inner()?;
121121+ if !k.starts_with(&prefix) {
122122+ break;
123123+ }
124124+ if cols.len() >= limit {
125125+ break;
126126+ }
127127+ // Skip the cursor key itself.
128128+ if cursor
129129+ .clone()
130130+ .is_some_and(|c| k.as_ref() == keys::cbr(did.clone(), c).as_slice())
131131+ {
132132+ continue;
133133+ }
134134+ if let Some(col) = keys::cbr_parse_collection(&k, prefix_len) {
135135+ cols.push(col);
136136+ }
137137+ }
138138+ Ok(cols)
139139+}
140140+141141+pub fn sync_repo(db: &DbRef, did: Did<'_>, snapshot: RepoSnapshot) -> Result<()> {
142142+ // TODO
143143+ Ok(())
144144+}
+43-17
src/storage/repo.rs
···55use crate::error::Result;
66use crate::storage::{DbRef, keys};
7788-/// High-level lifecycle state of a repo.
88+/// tap's "RepoState" type
99#[derive(Debug, Clone, PartialEq, Eq)]
1010pub enum RepoState {
1111- /// Repo is being indexed for the first time.
1212- Indexing,
1313- /// Repo is fully indexed and up to date.
1111+ Pending,
1212+ Desynchronized,
1313+ Resyncing,
1414 Active,
1515- /// Repo has been tombstoned / deactivated.
1616- Tombstoned,
1515+ Takendown,
1616+ Suspended,
1717+ Deactivated,
1818+ Error,
1719}
18201919-/// Processing status used to drive backfill / resync decisions.
2121+impl RepoState {
2222+ pub fn as_str(&self) -> &str {
2323+ match self {
2424+ RepoState::Pending => "pending",
2525+ RepoState::Desynchronized => "desynchronized",
2626+ RepoState::Resyncing => "resyncing",
2727+ RepoState::Active => "active",
2828+ RepoState::Takendown => "takendown",
2929+ RepoState::Suspended => "suspended",
3030+ RepoState::Deactivated => "deactivated",
3131+ RepoState::Error => "error",
3232+ }
3333+ }
3434+}
3535+3636+/// tap's "AccountStatus" type
2037#[derive(Debug, Clone, PartialEq, Eq)]
2121-pub enum RepoStatus {
2222- /// No record yet.
2323- Unknown,
2424- /// Queued for backfill probing.
2525- Pending,
2626- /// Backfill complete.
2727- Complete,
2828- /// An error occurred; `error` field has details.
2929- Error,
3838+pub enum AccountStatus {
3939+ Active,
4040+ Takendown,
4141+ Suspended,
4242+ Deactivated,
4343+ Deleted,
4444+}
4545+4646+impl AccountStatus {
4747+ pub fn as_str(&self) -> &str {
4848+ match self {
4949+ AccountStatus::Active => "active",
5050+ AccountStatus::Takendown => "takendown",
5151+ AccountStatus::Suspended => "suspended",
5252+ AccountStatus::Deactivated => "deactivated",
5353+ AccountStatus::Deleted => "deleted",
5454+ }
5555+ }
3056}
31573258/// Stored record for a repository.
3359#[derive(Debug, Clone)]
3460pub struct RepoRecord {
3561 pub state: RepoState,
3636- pub status: RepoStatus,
6262+ pub status: AccountStatus,
3763 pub error: Option<String>,
3864}
3965