1 use std
::collections
::HashMap
;
6 use super::BackupReader
;
7 use crate::backup
::{ReadChunk, DataBlob, CryptConfig}
;
9 /// Read chunks from remote host using ``BackupReader``
10 pub struct RemoteChunkReader
{
11 client
: Arc
<BackupReader
>,
12 crypt_config
: Option
<Arc
<CryptConfig
>>,
13 cache_hint
: HashMap
<[u8; 32], usize>,
14 cache
: HashMap
<[u8; 32], Vec
<u8>>,
17 impl RemoteChunkReader
{
19 /// Create a new instance.
21 /// Chunks listed in ``cache_hint`` are cached and kept in RAM.
23 client
: Arc
<BackupReader
>,
24 crypt_config
: Option
<Arc
<CryptConfig
>>,
25 cache_hint
: HashMap
<[u8; 32], usize>,
28 Self { client, crypt_config, cache_hint, cache: HashMap::new() }
32 impl ReadChunk
for RemoteChunkReader
{
34 fn read_raw_chunk(&mut self, digest
:&[u8; 32]) -> Result
<DataBlob
, Error
> {
36 let mut chunk_data
= Vec
::with_capacity(4*1024*1024);
38 tokio
::task
::block_in_place(|| futures
::executor
::block_on(self.client
.download_chunk(&digest
, &mut chunk_data
)))?
;
40 let chunk
= DataBlob
::from_raw(chunk_data
)?
;
46 fn read_chunk(&mut self, digest
:&[u8; 32]) -> Result
<Vec
<u8>, Error
> {
48 if let Some(raw_data
) = self.cache
.get(digest
) {
49 return Ok(raw_data
.to_vec());
52 let chunk
= self.read_raw_chunk(digest
)?
;
54 let raw_data
= chunk
.decode(self.crypt_config
.as_ref().map(Arc
::as_ref
))?
;
56 // fixme: verify digest?
58 let use_cache
= self.cache_hint
.contains_key(digest
);
60 self.cache
.insert(*digest
, raw_data
.to_vec());