diff --git a/ecstore/src/quorum.rs b/ecstore/src/quorum.rs index 0ab57be71..e50f0c82a 100644 --- a/ecstore/src/quorum.rs +++ b/ecstore/src/quorum.rs @@ -1,7 +1,7 @@ use crate::{disk::error::DiskError, error::Error}; use std::collections::HashMap; -type CheckErrorFn = fn(e: &Error) -> bool; +pub type CheckErrorFn = fn(e: &Error) -> bool; #[derive(Debug, thiserror::Error)] enum QuorumError { @@ -11,7 +11,7 @@ enum QuorumError { Write, } -fn is_file_not_found(e: &Error) -> bool { +pub fn is_file_not_found(e: &Error) -> bool { DiskError::FileNotFound.is(e) } @@ -21,13 +21,14 @@ fn is_err_ignored(err: &Error, ignored_errs: &[CheckErrorFn]) -> bool { } // 减少错误数量并返回出现次数最多的错误 -fn reduce_errs(errs: &Vec>, ignored_errs: &[CheckErrorFn]) -> (usize, Option) { +fn reduce_errs(errs: &Vec>, ignored_errs: &[CheckErrorFn]) -> (usize, Option) { let mut error_counts: HashMap = HashMap::new(); - let mut error_map: HashMap = HashMap::new(); + let mut error_map: HashMap = HashMap::new(); // 存err位置 let nil = "nil".to_string(); - for operr in errs.iter() { + for (i, operr) in errs.iter().enumerate() { if operr.is_none() { *error_counts.entry(nil.clone()).or_insert(0) += 1; + let _ = *error_map.entry(nil.clone()).or_insert(i); continue; } @@ -39,7 +40,7 @@ fn reduce_errs(errs: &Vec>, ignored_errs: &[CheckErrorFn]) -> (usi let errstr = err.to_string(); - *error_map.entry(errstr.clone()).or_insert(err); + let _ = *error_map.entry(errstr.clone()).or_insert(i); *error_counts.entry(errstr.clone()).or_insert(0) += 1; } @@ -52,38 +53,52 @@ fn reduce_errs(errs: &Vec>, ignored_errs: &[CheckErrorFn]) -> (usi } } - if let Some(c) = error_counts.get(&max_err) { + if let Some(&c) = error_counts.get(&max_err) { if let Some(&err) = error_map.get(&max_err) { - return (*c, Some(err.clone())); + return (c, Some(err)); } - return (*c, None); + return (c, None); } (0, None) } // 根据quorum验证错误数量 -fn reduce_quorum_errs<'a>( - errs: &'a Vec>, - ignored_errs: &[CheckErrorFn], - quorum: usize, - quorum_err: Error, -) -> Option { +fn reduce_quorum_errs(errs: &Vec>, ignored_errs: &[CheckErrorFn], quorum: usize) -> Option { let (max_count, max_err) = reduce_errs(errs, ignored_errs); if max_count >= quorum { max_err } else { - Some(quorum_err) + None } } // 根据读quorum验证错误数量 -fn reduce_read_quorum_errs(errs: &Vec>, ignored_errs: &[CheckErrorFn], read_quorum: usize) -> Option { - reduce_quorum_errs(errs, ignored_errs, read_quorum, Error::new(QuorumError::Read)) +pub fn reduce_read_quorum_errs( + errs: &Vec>, + ignored_errs: &[CheckErrorFn], + read_quorum: usize, +) -> Result { + let idx = reduce_quorum_errs(errs, ignored_errs, read_quorum); + if idx.is_none() { + return Err(Error::new(QuorumError::Read)); + } + + Ok(idx.unwrap()) } // 根据写quorum验证错误数量 -fn reduce_write_quorum_errs(errs: &Vec>, ignored_errs: &[CheckErrorFn], write_quorum: usize) -> Option { - reduce_quorum_errs(errs, ignored_errs, write_quorum, Error::new(QuorumError::Write)) +pub fn reduce_write_quorum_errs( + errs: &Vec>, + ignored_errs: &[CheckErrorFn], + write_quorum: usize, +) -> Result { + let idx = reduce_quorum_errs(errs, ignored_errs, write_quorum); + + if idx.is_none() { + return Err(Error::new(QuorumError::Write)); + } + + Ok(idx.unwrap()) }