use std::path::PathBuf;
use crate::branch::SnapshotEntry;
use crate::tree::Hash;
use super::super::consult::{MetadataPass, RegistrySource};
use super::super::report::MarkTallies;
use super::{SnapshotCandidates, group_snapshot_roots};
fn entry(name: &str) -> SnapshotEntry {
SnapshotEntry {
name: name.to_owned(),
root_hash: Hash::from_bytes([0x77; 32]),
timestamp: 1,
}
}
fn pass_with(registries: Vec<RegistrySource>) -> MetadataPass {
MetadataPass {
manifest_report: None,
sources: Vec::new(),
refs_scans: Vec::new(),
registries,
supplied_missing: Vec::new(),
blockers: Vec::new(),
listed_paths: Vec::new(),
}
}
#[test]
fn candidate_storage_is_shared_not_per_root() -> Result<(), Box<dyn std::error::Error>> {
let metadata = pass_with(vec![
RegistrySource {
path: PathBuf::from("/unbound.hsr"),
entries: (0..50).map(|index| entry(&format!("u{index}"))).collect(),
declared_shards: None,
},
RegistrySource {
path: PathBuf::from("/bound.hsr"),
entries: (0..50).map(|index| entry(&format!("b{index}"))).collect(),
declared_shards: Some(vec![0, 2]),
},
]);
let mut tallies = MarkTallies::default();
let work = group_snapshot_roots(&metadata, 4096, &mut tallies)?;
assert_eq!(work.len(), 100);
assert_eq!(tallies.snapshot_roots, 100);
let mut shared: Option<&std::sync::Arc<[usize]>> = None;
for item in &work {
match &item.candidates {
SnapshotCandidates::AllShards => {}
SnapshotCandidates::Declared(ids) => match shared {
None => shared = Some(ids),
Some(first) => assert!(
std::sync::Arc::ptr_eq(first, ids),
"bound roots must SHARE one Arc, never clone the list"
),
},
}
}
let unbound = work
.iter()
.filter(|item| matches!(item.candidates, SnapshotCandidates::AllShards))
.count();
assert_eq!(unbound, 50, "unbound roots carry no list at all");
assert!(shared.is_some(), "bound roots present");
Ok(())
}