fix:reduce_write_quorum_errs

This commit is contained in:
weisd
2024-09-02 17:05:22 +08:00
parent 8c24e38ee1
commit da627f24a3
+35 -20
View File
@@ -1,7 +1,7 @@
use crate::{disk::error::DiskError, error::Error}; use crate::{disk::error::DiskError, error::Error};
use std::collections::HashMap; use std::collections::HashMap;
type CheckErrorFn = fn(e: &Error) -> bool; pub type CheckErrorFn = fn(e: &Error) -> bool;
#[derive(Debug, thiserror::Error)] #[derive(Debug, thiserror::Error)]
enum QuorumError { enum QuorumError {
@@ -11,7 +11,7 @@ enum QuorumError {
Write, Write,
} }
fn is_file_not_found(e: &Error) -> bool { pub fn is_file_not_found(e: &Error) -> bool {
DiskError::FileNotFound.is(e) DiskError::FileNotFound.is(e)
} }
@@ -21,13 +21,14 @@ fn is_err_ignored(err: &Error, ignored_errs: &[CheckErrorFn]) -> bool {
} }
// 减少错误数量并返回出现次数最多的错误 // 减少错误数量并返回出现次数最多的错误
fn reduce_errs(errs: &Vec<Option<Error>>, ignored_errs: &[CheckErrorFn]) -> (usize, Option<Error>) { fn reduce_errs(errs: &Vec<Option<Error>>, ignored_errs: &[CheckErrorFn]) -> (usize, Option<usize>) {
let mut error_counts: HashMap<String, usize> = HashMap::new(); let mut error_counts: HashMap<String, usize> = HashMap::new();
let mut error_map: HashMap<String, &Error> = HashMap::new(); let mut error_map: HashMap<String, usize> = HashMap::new(); // 存err位置
let nil = "nil".to_string(); let nil = "nil".to_string();
for operr in errs.iter() { for (i, operr) in errs.iter().enumerate() {
if operr.is_none() { if operr.is_none() {
*error_counts.entry(nil.clone()).or_insert(0) += 1; *error_counts.entry(nil.clone()).or_insert(0) += 1;
let _ = *error_map.entry(nil.clone()).or_insert(i);
continue; continue;
} }
@@ -39,7 +40,7 @@ fn reduce_errs(errs: &Vec<Option<Error>>, ignored_errs: &[CheckErrorFn]) -> (usi
let errstr = err.to_string(); 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; *error_counts.entry(errstr.clone()).or_insert(0) += 1;
} }
@@ -52,38 +53,52 @@ fn reduce_errs(errs: &Vec<Option<Error>>, 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) { 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) (0, None)
} }
// 根据quorum验证错误数量 // 根据quorum验证错误数量
fn reduce_quorum_errs<'a>( fn reduce_quorum_errs(errs: &Vec<Option<Error>>, ignored_errs: &[CheckErrorFn], quorum: usize) -> Option<usize> {
errs: &'a Vec<Option<Error>>,
ignored_errs: &[CheckErrorFn],
quorum: usize,
quorum_err: Error,
) -> Option<Error> {
let (max_count, max_err) = reduce_errs(errs, ignored_errs); let (max_count, max_err) = reduce_errs(errs, ignored_errs);
if max_count >= quorum { if max_count >= quorum {
max_err max_err
} else { } else {
Some(quorum_err) None
} }
} }
// 根据读quorum验证错误数量 // 根据读quorum验证错误数量
fn reduce_read_quorum_errs(errs: &Vec<Option<Error>>, ignored_errs: &[CheckErrorFn], read_quorum: usize) -> Option<Error> { pub fn reduce_read_quorum_errs(
reduce_quorum_errs(errs, ignored_errs, read_quorum, Error::new(QuorumError::Read)) errs: &Vec<Option<Error>>,
ignored_errs: &[CheckErrorFn],
read_quorum: usize,
) -> Result<usize, Error> {
let idx = reduce_quorum_errs(errs, ignored_errs, read_quorum);
if idx.is_none() {
return Err(Error::new(QuorumError::Read));
}
Ok(idx.unwrap())
} }
// 根据写quorum验证错误数量 // 根据写quorum验证错误数量
fn reduce_write_quorum_errs(errs: &Vec<Option<Error>>, ignored_errs: &[CheckErrorFn], write_quorum: usize) -> Option<Error> { pub fn reduce_write_quorum_errs(
reduce_quorum_errs(errs, ignored_errs, write_quorum, Error::new(QuorumError::Write)) errs: &Vec<Option<Error>>,
ignored_errs: &[CheckErrorFn],
write_quorum: usize,
) -> Result<usize, Error> {
let idx = reduce_quorum_errs(errs, ignored_errs, write_quorum);
if idx.is_none() {
return Err(Error::new(QuorumError::Write));
}
Ok(idx.unwrap())
} }