diff --git a/src/backup/archive_index.rs b/src/backup/archive_index.rs index 3bcac8d5..1368c71b 100644 --- a/src/backup/archive_index.rs +++ b/src/backup/archive_index.rs @@ -132,13 +132,15 @@ impl <'a> ArchiveIndexReader<'a> { pub fn dump_catar(&self, mut writer: Box) -> Result<(), Error> { + let mut buffer = Vec::with_capacity(1024*1024); + for pos in 0..self.index_entries { let offset = unsafe { *(self.index.add(pos*40) as *const u64) }; let digest = unsafe { std::slice::from_raw_parts(self.index.add(pos*40+8), 32) }; - let chunk = self.store.read_chunk(digest)?; - println!("Dump {:08x} {}", offset, chunk.len()); - writer.write_all(&chunk)?; + self.store.read_chunk(digest, &mut buffer)?; + println!("Dump {:08x} {}", offset, buffer.len(), ); + writer.write_all(&buffer)?; } diff --git a/src/backup/chunk_store.rs b/src/backup/chunk_store.rs index 9078c7fd..84223b6c 100644 --- a/src/backup/chunk_store.rs +++ b/src/backup/chunk_store.rs @@ -165,7 +165,7 @@ impl ChunkStore { Ok(()) } - pub fn read_chunk(&self, digest:&[u8]) -> Result, Error> { + pub fn read_chunk(&self, digest:&[u8], buffer: &mut Vec) -> Result<(), Error> { let mut chunk_path = self.chunk_dir.clone(); let prefix = digest_to_prefix(&digest); @@ -174,13 +174,22 @@ impl ChunkStore { chunk_path.push(&digest_str); let mut f = std::fs::File::open(&chunk_path)?; - let mut chunk = Vec::with_capacity(64*1024); + + let stat = nix::sys::stat::fstat(f.as_raw_fd())?; + let size = stat.st_size as usize; + + unsafe { buffer.set_len(buffer.capacity()); } + if buffer.len() < size { + let additional = size - buffer.len(); + buffer.reserve(additional); + } + unsafe { buffer.set_len(size); } use std::io::Read; - f.read_to_end(&mut chunk)?; + f.read_exact(buffer.as_mut_slice())?; - Ok(chunk) + Ok(()) } fn sweep_old_files(&self, handle: &mut nix::dir::Dir, status: &mut GarbageCollectionStatus) -> Result<(), Error> {