diff options
author | Alex Auvolat <alex@adnab.me> | 2022-06-06 16:29:02 +0200 |
---|---|---|
committer | Alex Auvolat <alex@adnab.me> | 2022-06-06 16:29:02 +0200 |
commit | 1dabd98330cedd108c42b7613a1f29fc4e4123ad (patch) | |
tree | ee2620290c92f8e1a974f341c80f26dc356d2139 /src/block | |
parent | 9238fda9b245beb3ff535a16eda7859aed277bc6 (diff) | |
download | garage-1dabd98330cedd108c42b7613a1f29fc4e4123ad.tar.gz garage-1dabd98330cedd108c42b7613a1f29fc4e4123ad.zip |
Improve things in block manager & correctly propagate .len() errors
Diffstat (limited to 'src/block')
-rw-r--r-- | src/block/manager.rs | 54 |
1 files changed, 36 insertions, 18 deletions
diff --git a/src/block/manager.rs b/src/block/manager.rs index b7dcaf8a..ea984646 100644 --- a/src/block/manager.rs +++ b/src/block/manager.rs @@ -1,3 +1,5 @@ +use core::ops::Bound; + use std::convert::TryInto; use std::path::{Path, PathBuf}; use std::sync::Arc; @@ -218,19 +220,35 @@ impl BlockManager { /// to fix any mismatch between the two. pub async fn repair_data_store(&self, must_exit: &watch::Receiver<bool>) -> Result<(), Error> { // 1. Repair blocks from RC table. - // TODO don't do this like this - let mut hashes = vec![]; - for (i, entry) in self.rc.rc.iter()?.enumerate() { - let (hash, _) = entry?; - let hash = Hash::try_from(&hash[..]).unwrap(); - hashes.push(hash); - if i & 0xFF == 0 && *must_exit.borrow() { - return Ok(()); + let mut next_start: Option<Hash> = None; + loop { + let mut batch_of_hashes = vec![]; + let start_bound = match next_start.as_ref() { + None => Bound::Unbounded, + Some(x) => Bound::Excluded(x.as_slice()), + }; + for entry in self + .rc + .rc + .range::<&[u8], _>((start_bound, Bound::Unbounded))? + { + let (hash, _) = entry?; + let hash = Hash::try_from(&hash[..]).unwrap(); + batch_of_hashes.push(hash); + if batch_of_hashes.len() >= 1000 { + break; + } } - } - for (i, hash) in hashes.into_iter().enumerate() { - self.put_to_resync(&hash, Duration::from_secs(0))?; - if i & 0xFF == 0 && *must_exit.borrow() { + if batch_of_hashes.is_empty() { + break; + } + + for hash in batch_of_hashes.into_iter() { + self.put_to_resync(&hash, Duration::from_secs(0))?; + next_start = Some(hash) + } + + if *must_exit.borrow() { return Ok(()); } } @@ -271,18 +289,18 @@ impl BlockManager { } /// Get lenght of resync queue - pub fn resync_queue_len(&self) -> usize { - self.resync_queue.len().unwrap() // TODO fix unwrap + pub fn resync_queue_len(&self) -> Result<usize, Error> { + Ok(self.resync_queue.len()?) } /// Get number of blocks that have an error - pub fn resync_errors_len(&self) -> usize { - self.resync_errors.len().unwrap() // TODO fix unwrap + pub fn resync_errors_len(&self) -> Result<usize, Error> { + Ok(self.resync_errors.len()?) } /// Get number of items in the refcount table - pub fn rc_len(&self) -> usize { - self.rc.rc.len().unwrap() // TODO fix unwrap + pub fn rc_len(&self) -> Result<usize, Error> { + Ok(self.rc.rc.len()?) } //// ----- Managing the reference counter ---- |