diff --git a/crates/core/src/backend/decrypt.rs b/crates/core/src/backend/decrypt.rs index 6634195b..c9ce8dc0 100644 --- a/crates/core/src/backend/decrypt.rs +++ b/crates/core/src/backend/decrypt.rs @@ -133,6 +133,8 @@ pub trait DecryptReadBackend: ReadBackend + Clone + 'static { /// Streams all files. /// + /// Note: The result comes in arbitrary order! + /// /// # Arguments /// /// * `p` - The progress bar. @@ -145,11 +147,13 @@ pub trait DecryptReadBackend: ReadBackend + Clone + 'static { p: &impl Progress, ) -> RusticResult>> { let list = self.list(F::TYPE).map_err(RusticErrorKind::Backend)?; - self.stream_list(list, p) + self.stream_list(&list, p) } /// Streams a list of files. /// + /// Note: The result comes in arbitrary order! + /// /// # Arguments /// /// * `list` - The list of files to stream. @@ -160,7 +164,7 @@ pub trait DecryptReadBackend: ReadBackend + Clone + 'static { /// If the files could not be read. fn stream_list( &self, - list: Vec, + list: &[Id], p: &impl Progress, ) -> RusticResult>> { p.set_length(list.len() as u64); @@ -168,7 +172,7 @@ pub trait DecryptReadBackend: ReadBackend + Clone + 'static { list.into_par_iter() .for_each_with((self, p, tx), |(be, p, tx), id| { - let file = be.get_file::(&id).map(|file| (id, file)); + let file = be.get_file::(id).map(|file| (*id, file)); p.inc(1); tx.send(file).unwrap(); }); diff --git a/crates/core/src/commands/prune.rs b/crates/core/src/commands/prune.rs index e670330b..0751a612 100644 --- a/crates/core/src/commands/prune.rs +++ b/crates/core/src/commands/prune.rs @@ -1460,14 +1460,14 @@ fn find_used_blobs( let ignore_snaps: BTreeSet<_> = ignore_snaps.iter().collect(); let p = pb.progress_counter("reading snapshots..."); - let list = be + let list: Vec<_> = be .list(FileType::Snapshot) .map_err(RusticErrorKind::Backend)? .into_iter() .filter(|id| !ignore_snaps.contains(id)) .collect(); let snap_trees: Vec<_> = be - .stream_list::(list, &p)? + .stream_list::(&list, &p)? .into_iter() .map_ok(|(_, snap)| snap.tree) .try_collect()?; diff --git a/crates/core/src/repofile/snapshotfile.rs b/crates/core/src/repofile/snapshotfile.rs index 808a32d7..403236af 100644 --- a/crates/core/src/repofile/snapshotfile.rs +++ b/crates/core/src/repofile/snapshotfile.rs @@ -1,5 +1,6 @@ use std::{ cmp::Ordering, + collections::BTreeMap, fmt::{self, Display}, path::{Path, PathBuf}, str::FromStr, @@ -550,10 +551,14 @@ impl SnapshotFile { p: &impl Progress, ) -> RusticResult> { let ids = be.find_ids(FileType::Snapshot, ids)?; - be.stream_list::(ids, p)? + let mut list: BTreeMap<_, _> = + be.stream_list::(&ids, p)?.into_iter().try_collect()?; + // sort back to original order + Ok(ids .into_iter() - .map_ok(Self::set_id) - .try_collect() + .filter_map(|id| list.remove_entry(&id)) + .map(Self::set_id) + .collect()) } /// Compare two [`SnapshotFile`]s by criteria from [`SnapshotGroupCriterion`]. diff --git a/crates/core/src/repository.rs b/crates/core/src/repository.rs index d9261b44..3bf878cc 100644 --- a/crates/core/src/repository.rs +++ b/crates/core/src/repository.rs @@ -947,6 +947,9 @@ impl Repository { /// /// # Errors /// + /// # Note + /// The result is not sorted and may come in random order! + /// // TODO: Document errors pub fn get_matching_snapshots( &self, @@ -1223,6 +1226,9 @@ impl Repository { /// /// # Returns /// + /// # Note + /// The result is not sorted and may come in random order! + /// /// An iterator over all files of the given type pub fn stream_files( &self, diff --git a/crates/core/tests/integration.rs b/crates/core/tests/integration.rs index f7707d64..a1e2c568 100644 --- a/crates/core/tests/integration.rs +++ b/crates/core/tests/integration.rs @@ -248,6 +248,18 @@ fn test_backup_with_tar_gz_passes( // pack files should be unchanged let packs2: Vec<_> = repo.list(rustic_core::FileType::Pack)?.collect(); assert_eq!(packs1, packs2); + + // Check if snapshots can be retrieved + let mut ids: Vec<_> = all_snapshots.iter().map(|sn| sn.id.to_string()).collect(); + let snaps = repo.get_snapshots(&ids)?; + assert_eq!(snaps, all_snapshots); + + // reverse order + all_snapshots.reverse(); + ids.reverse(); + let snaps = repo.get_snapshots(&ids)?; + assert_eq!(snaps, all_snapshots); + Ok(()) }