]>
Commit | Line | Data |
---|---|---|
f4bf7dfc | 1 | use std::collections::HashMap; |
3c0facc7 WB |
2 | use std::sync::Arc; |
3 | ||
f7d4e4b5 | 4 | use anyhow::{Error}; |
7f99bf69 DM |
5 | |
6 | use super::BackupReader; | |
4ee8f53d | 7 | use crate::backup::{ReadChunk, DataBlob, CryptConfig}; |
d973aa82 | 8 | use crate::tools::runtime::block_on; |
7f99bf69 DM |
9 | |
10 | /// Read chunks from remote host using ``BackupReader`` | |
11 | pub struct RemoteChunkReader { | |
12 | client: Arc<BackupReader>, | |
13 | crypt_config: Option<Arc<CryptConfig>>, | |
f4bf7dfc DM |
14 | cache_hint: HashMap<[u8; 32], usize>, |
15 | cache: HashMap<[u8; 32], Vec<u8>>, | |
7f99bf69 DM |
16 | } |
17 | ||
18 | impl RemoteChunkReader { | |
19 | ||
f4bf7dfc DM |
20 | /// Create a new instance. |
21 | /// | |
22 | /// Chunks listed in ``cache_hint`` are cached and kept in RAM. | |
23 | pub fn new( | |
24 | client: Arc<BackupReader>, | |
25 | crypt_config: Option<Arc<CryptConfig>>, | |
26 | cache_hint: HashMap<[u8; 32], usize>, | |
27 | ) -> Self { | |
28 | ||
29 | Self { client, crypt_config, cache_hint, cache: HashMap::new() } | |
7f99bf69 DM |
30 | } |
31 | } | |
32 | ||
33 | impl ReadChunk for RemoteChunkReader { | |
34 | ||
3758b398 | 35 | fn read_raw_chunk(&mut self, digest:&[u8; 32]) -> Result<DataBlob, Error> { |
7f99bf69 | 36 | |
62e05bb3 | 37 | let mut chunk_data = Vec::with_capacity(4*1024*1024); |
7f99bf69 | 38 | |
d973aa82 WB |
39 | //tokio::task::block_in_place(|| futures::executor::block_on(self.client.download_chunk(&digest, &mut chunk_data)))?; |
40 | block_on(async { | |
41 | // download_chunk returns the writer back to us, but we need to return a 'static value | |
42 | self.client | |
43 | .download_chunk(&digest, &mut chunk_data) | |
44 | .await | |
45 | .map(drop) | |
46 | })?; | |
7f99bf69 | 47 | |
4ee8f53d | 48 | let chunk = DataBlob::from_raw(chunk_data)?; |
7f99bf69 DM |
49 | chunk.verify_crc()?; |
50 | ||
3758b398 DM |
51 | Ok(chunk) |
52 | } | |
53 | ||
54 | fn read_chunk(&mut self, digest:&[u8; 32]) -> Result<Vec<u8>, Error> { | |
55 | ||
56 | if let Some(raw_data) = self.cache.get(digest) { | |
57 | return Ok(raw_data.to_vec()); | |
58 | } | |
4ee8f53d | 59 | |
3758b398 | 60 | let chunk = self.read_raw_chunk(digest)?; |
7f99bf69 | 61 | |
3758b398 DM |
62 | let raw_data = chunk.decode(self.crypt_config.as_ref().map(Arc::as_ref))?; |
63 | ||
64 | // fixme: verify digest? | |
65 | ||
66 | let use_cache = self.cache_hint.contains_key(digest); | |
f4bf7dfc DM |
67 | if use_cache { |
68 | self.cache.insert(*digest, raw_data.to_vec()); | |
69 | } | |
70 | ||
7f99bf69 DM |
71 | Ok(raw_data) |
72 | } | |
3758b398 | 73 | |
7f99bf69 | 74 | } |