···5555 - [-] copy applicable ones from collectiondir
5656- [~] prefix-merge walker (limit by total collections to be merged?)
5757 - [x] add an all-collections index
5858+- [ ] back out the collections-list index (not doing prefix matching after all)
5859- [ ] swap in repo-stream for backfill
5960 - [ ] with memory limit
6061 - [ ] with a global concurrency limit for big repos
+12-5
src/storage/collection_index.rs
···280280/// Reads the current cbr entries synchronously, then queues the corresponding
281281/// rbc and cbr removes into `batch`. Use this when the index cleanup must be
282282/// atomic with other writes (e.g. a repo state update on tombstone).
283283+/// Returns the number of collections removed.
283284pub fn remove_all_into(
284285 batch: &mut fjall::OwnedWriteBatch,
285286 db: &DbRef,
286287 did: Did<'_>,
287287-) -> StorageResult<()> {
288288+) -> StorageResult<usize> {
288289 let prefix = cbr_prefix(did.clone());
289290 let collections: Vec<Vec<u8>> = db
290291 .ks
···298299 }
299300 batch.remove(&db.ks, cbr_key.as_slice());
300301 }
301301- Ok(())
302302+ Ok(collections.len())
302303}
303304304305pub fn remove_all(db: &DbRef, did: Did<'_>) -> StorageResult<()> {
305306 let mut batch = db.database.batch();
306306- remove_all_into(&mut batch, db, did)?;
307307+ remove_all_into(&mut batch, db, did.clone())?;
307308 batch.commit()?;
308309 Ok(())
309310}
···315316/// the index but absent from the snapshot are deleted; collections in the
316317/// snapshot but absent from the index are inserted. The whole diff is applied
317318/// in a single batch.
319319+///
320320+/// Returns `(n_inserted, n_removed)`.
318321///
319322/// Typically called as `sync_collections(db, did, &snapshot.collections)`.
320323pub fn sync_collections(
321324 db: &DbRef,
322325 did: Did<'_>,
323326 collections: &[Nsid<'static>],
324324-) -> StorageResult<()> {
327327+) -> StorageResult<(usize, usize)> {
325328 // Read the current set from the cbr index. Fjall iterates in key order, and
326329 // the cbr prefix puts the collection NSID last, so the suffix scan is already
327330 // sorted lexicographically.
···341344 .collect();
342345343346 let mut batch = db.database.batch();
347347+ let mut n_inserted: usize = 0;
348348+ let mut n_removed: usize = 0;
344349345350 // Merge-join two sorted sequences.
346351 // We separate the peek (to determine ordering) from the advance (next())
···359364 match ord {
360365 Ordering::Less => {
361366 remove_into(&mut batch, db, did.clone(), ei.next().unwrap());
367367+ n_removed += 1;
362368 }
363369 Ordering::Greater => {
364370 insert_into(&mut batch, db, did.clone(), si.next().unwrap());
371371+ n_inserted += 1;
365372 }
366373 Ordering::Equal => {
367374 ei.next();
···371378 }
372379373380 batch.commit()?;
374374- Ok(())
381381+ Ok((n_inserted, n_removed))
375382}
376383377384// ---------------------------------------------------------------------------