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