From ccc76dc71364d9b5e35e6b6d9d456993b3e7194b Mon Sep 17 00:00:00 2001 From: Dennis Schwerdel Date: Sat, 8 Apr 2017 15:10:02 +0200 Subject: [PATCH] Nice error when remote storage is not mounted fastcdc speedup --- TODO.md | 3 ++- src/chunker/fastcdc.rs | 27 +++++++++++++++++---------- src/repository/error.rs | 4 ++++ src/repository/layout.rs | 4 ++++ src/repository/mod.rs | 9 +++++---- 5 files changed, 32 insertions(+), 15 deletions(-) diff --git a/TODO.md b/TODO.md index b66ff07..da8ac6e 100644 --- a/TODO.md +++ b/TODO.md @@ -12,9 +12,10 @@ ## Usability * Verbosity control +* Error: Backup already exists +* Backup directories as a thing (list, remove) * Display backup name and path on backup integrity error * Better control over what is checked in `check` subcommand -* Nice error when remote storage is not mounted * Man pages for all minor subcommands ## Code quality diff --git a/src/chunker/fastcdc.rs b/src/chunker/fastcdc.rs index 9163b32..4055afc 100644 --- a/src/chunker/fastcdc.rs +++ b/src/chunker/fastcdc.rs @@ -81,39 +81,46 @@ impl IChunker for FastCdcChunker { } - #[allow(unknown_lints,explicit_counter_loop)] + #[allow(unknown_lints,explicit_counter_loop,needless_range_loop)] fn chunk(&mut self, r: &mut R, mut w: &mut W) -> Result { let mut max; let mut hash = 0u64; let mut pos = 0; + let gear = &self.gear; + let buffer = &mut self.buffer; + let min_size = self.min_size; + let mask_short = self.mask_short; + let mask_long = self.mask_long; + let avg_size = self.avg_size; + let max_size = self.max_size; loop { // Fill the buffer, there might be some bytes still in there from last chunk - max = try!(r.read(&mut self.buffer[self.buffered..]).map_err(ChunkerError::Read)) + self.buffered; + max = try!(r.read(&mut buffer[self.buffered..]).map_err(ChunkerError::Read)) + self.buffered; // If nothing to do, finish if max == 0 { return Ok(ChunkerStatus::Finished) } for i in 0..max { - if pos >= self.min_size { + if pos >= min_size { // Hash update - hash = (hash << 1).wrapping_add(self.gear[self.buffer[i] as usize]); + hash = (hash << 1).wrapping_add(gear[buffer[i] as usize]); // 3 options for break point // 1) mask_short matches and chunk is smaller than average // 2) mask_long matches and chunk is longer or equal to average // 3) chunk reached max_size - if pos < self.avg_size && hash & self.mask_short == 0 - || pos >= self.avg_size && hash & self.mask_long == 0 - || pos >= self.max_size { + if pos < avg_size && hash & mask_short == 0 + || pos >= avg_size && hash & mask_long == 0 + || pos >= max_size { // Write all bytes from this chunk out to sink and store rest for next chunk - try!(w.write_all(&self.buffer[..i+1]).map_err(ChunkerError::Write)); - unsafe { ptr::copy(self.buffer[i+1..].as_ptr(), self.buffer.as_mut_ptr(), max-i-1) }; + try!(w.write_all(&buffer[..i+1]).map_err(ChunkerError::Write)); + unsafe { ptr::copy(buffer[i+1..].as_ptr(), buffer.as_mut_ptr(), max-i-1) }; self.buffered = max-i-1; return Ok(ChunkerStatus::Continue); } } pos += 1; } - try!(w.write_all(&self.buffer[..max]).map_err(ChunkerError::Write)); + try!(w.write_all(&buffer[..max]).map_err(ChunkerError::Write)); self.buffered = 0; } } diff --git a/src/repository/error.rs b/src/repository/error.rs index 41e9aab..922d6d8 100644 --- a/src/repository/error.rs +++ b/src/repository/error.rs @@ -14,6 +14,10 @@ quick_error!{ #[derive(Debug)] #[allow(unknown_lints,large_enum_variant)] pub enum RepositoryError { + NoRemote { + description("Remote storage not found") + display("Repository error: The remote storage has not been found, may be it needs to be mounted?") + } Index(err: IndexError) { from() cause(err) diff --git a/src/repository/layout.rs b/src/repository/layout.rs index bd4432e..d827c86 100644 --- a/src/repository/layout.rs +++ b/src/repository/layout.rs @@ -46,6 +46,10 @@ impl RepositoryLayout { self.0.join("remote") } + pub fn remote_exists(&self) -> bool { + self.remote_bundles_path().exists() && self.backups_path().exists() && self.remote_locks_path().exists() + } + pub fn remote_readme_path(&self) -> PathBuf { self.0.join("remote/README.md") } diff --git a/src/repository/mod.rs b/src/repository/mod.rs index 11af174..f708390 100644 --- a/src/repository/mod.rs +++ b/src/repository/mod.rs @@ -54,8 +54,7 @@ pub struct Repository { impl Repository { pub fn create, R: AsRef>(path: P, config: Config, remote: R) -> Result { - let path = path.as_ref().to_owned(); - let layout = RepositoryLayout::new(path.clone()); + let layout = RepositoryLayout::new(path.as_ref().to_path_buf()); try!(fs::create_dir(layout.base_path())); try!(File::create(layout.excludes_path()).and_then(|mut f| f.write_all(DEFAULT_EXCLUDES))); try!(fs::create_dir(layout.keys_path())); @@ -71,8 +70,10 @@ impl Repository { } pub fn open>(path: P) -> Result { - let path = path.as_ref().to_owned(); - let layout = RepositoryLayout::new(path.clone()); + let layout = RepositoryLayout::new(path.as_ref().to_path_buf()); + if !layout.remote_exists() { + return Err(RepositoryError::NoRemote) + } let config = try!(Config::load(layout.config_path())); let locks = LockFolder::new(layout.remote_locks_path()); let crypto = Arc::new(Mutex::new(try!(Crypto::open(layout.keys_path()))));