]> git.proxmox.com Git - proxmox-backup.git/blame - src/backup/index.rs
add and implement chunk_from_offset for IndexFile
[proxmox-backup.git] / src / backup / index.rs
CommitLineData
fa17b1ce 1use std::collections::HashMap;
c443f58b 2use std::ops::Range;
ee53955f 3
c443f58b
WB
4pub struct ChunkReadInfo {
5 pub range: Range<u64>,
6 pub digest: [u8; 32],
7}
8
9impl ChunkReadInfo {
10 #[inline]
11 pub fn size(&self) -> u64 {
12 self.range.end - self.range.start
13 }
14}
15
a660978c
DM
16/// Trait to get digest list from index files
17///
18/// To allow easy iteration over all used chunks.
5c1130df 19pub trait IndexFile {
7bc1d727
WB
20 fn index_count(&self) -> usize;
21 fn index_digest(&self, pos: usize) -> Option<&[u8; 32]>;
a660978c 22 fn index_bytes(&self) -> u64;
fdaab0df 23 fn chunk_info(&self, pos: usize) -> Option<ChunkReadInfo>;
f4bf7dfc 24
d0463b67
SR
25 /// Get the chunk index and the relative offset within it for a byte offset
26 fn chunk_from_offset(&self, offset: u64) -> Option<(usize, u64)>;
27
1f82f9b7 28 /// Compute index checksum and size
2e079b8b 29 fn compute_csum(&self) -> ([u8; 32], u64);
1f82f9b7 30
f4bf7dfc
DM
31 /// Returns most often used chunks
32 fn find_most_used_chunks(&self, max: usize) -> HashMap<[u8; 32], usize> {
33 let mut map = HashMap::new();
34
35 for pos in 0..self.index_count() {
36 let digest = self.index_digest(pos).unwrap();
37
38 let count = map.entry(*digest).or_insert(0);
39 *count += 1;
40 }
41
42 let mut most_used = Vec::new();
43
44 for (digest, count) in map {
45 if count <= 1 { continue; }
46 match most_used.binary_search_by_key(&count, |&(_digest, count)| count) {
47 Ok(p) => most_used.insert(p, (digest, count)),
48 Err(p) => most_used.insert(p, (digest, count)),
49 }
50
51 if most_used.len() > max { let _ = most_used.pop(); }
52 }
53
54 let mut map = HashMap::new();
55
56 for data in most_used {
57 map.insert(data.0, data.1);
58 }
59
60 map
61 }
7bc1d727 62}