chore: minor refactor for weighted choose (#4917)

* chore: minor refactor for weighted choose

* chore: by comment, remove the fast path of choose_multiple
This commit is contained in:
jeremyhi
2024-11-05 10:55:11 +08:00
committed by GitHub
parent 3dcd6b8e51
commit f3509fa312
3 changed files with 35 additions and 19 deletions

View File

@@ -22,7 +22,7 @@ use crate::metasrv::SelectTarget;
use crate::selector::SelectorOptions;
/// According to the `opts`, choose peers from the `weight_array` through `weighted_choose`.
pub fn choose_peers<W>(opts: &SelectorOptions, weighted_choose: &mut W) -> Result<Vec<Peer>>
pub fn choose_items<W>(opts: &SelectorOptions, weighted_choose: &mut W) -> Result<Vec<Peer>>
where
W: WeightedChoose<Peer>,
{
@@ -36,20 +36,36 @@ where
}
);
if opts.allow_duplication {
(0..min_required_items)
.map(|_| weighted_choose.choose_one())
.collect::<Result<_>>()
} else {
let weight_array_len = weighted_choose.len();
if min_required_items == 1 {
// fast path
return Ok(vec![weighted_choose.choose_one()?]);
}
// When opts.allow_duplication is false, we need to check that the length of the weighted array is greater than
// or equal to min_required_items, otherwise it may cause an infinite loop.
let available_count = weighted_choose.len();
if opts.allow_duplication {
// Calculate how many complete rounds of `available_count` items to select,
// plus any additional items needed after complete rounds.
let complete_batches = min_required_items / available_count;
let leftover_items = min_required_items % available_count;
if complete_batches == 0 {
return weighted_choose.choose_multiple(leftover_items);
}
let mut result = Vec::with_capacity(min_required_items);
for _ in 0..complete_batches {
result.extend(weighted_choose.choose_multiple(available_count)?);
}
result.extend(weighted_choose.choose_multiple(leftover_items)?);
Ok(result)
} else {
// Ensure the available items are sufficient when duplication is not allowed.
ensure!(
weight_array_len >= min_required_items,
available_count >= min_required_items,
error::NoEnoughAvailableNodeSnafu {
required: min_required_items,
available: weight_array_len,
available: available_count,
select_target: SelectTarget::Datanode
}
);
@@ -64,7 +80,7 @@ mod tests {
use common_meta::peer::Peer;
use crate::selector::common::choose_peers;
use crate::selector::common::choose_items;
use crate::selector::weighted_choose::{RandomWeightedChoose, WeightedItem};
use crate::selector::SelectorOptions;
@@ -115,7 +131,7 @@ mod tests {
};
let selected_peers: HashSet<_> =
choose_peers(&opts, &mut RandomWeightedChoose::new(weight_array.clone()))
choose_items(&opts, &mut RandomWeightedChoose::new(weight_array.clone()))
.unwrap()
.into_iter()
.collect();
@@ -129,7 +145,7 @@ mod tests {
};
let selected_result =
choose_peers(&opts, &mut RandomWeightedChoose::new(weight_array.clone()));
choose_items(&opts, &mut RandomWeightedChoose::new(weight_array.clone()));
assert!(selected_result.is_err());
for i in 1..=50 {
@@ -139,7 +155,7 @@ mod tests {
};
let selected_peers =
choose_peers(&opts, &mut RandomWeightedChoose::new(weight_array.clone())).unwrap();
choose_items(&opts, &mut RandomWeightedChoose::new(weight_array.clone())).unwrap();
assert_eq!(i, selected_peers.len());
}

View File

@@ -17,7 +17,7 @@ use common_meta::peer::Peer;
use crate::error::Result;
use crate::lease;
use crate::metasrv::SelectorContext;
use crate::selector::common::choose_peers;
use crate::selector::common::choose_items;
use crate::selector::weighted_choose::{RandomWeightedChoose, WeightedItem};
use crate::selector::{Namespace, Selector, SelectorOptions};
@@ -53,7 +53,7 @@ impl Selector for LeaseBasedSelector {
// 3. choose peers by weight_array.
let mut weighted_choose = RandomWeightedChoose::new(weight_array);
let selected = choose_peers(&opts, &mut weighted_choose)?;
let selected = choose_items(&opts, &mut weighted_choose)?;
Ok(selected)
}

View File

@@ -26,7 +26,7 @@ use crate::error::{self, Result};
use crate::key::{DatanodeLeaseKey, LeaseValue};
use crate::lease;
use crate::metasrv::SelectorContext;
use crate::selector::common::choose_peers;
use crate::selector::common::choose_items;
use crate::selector::weight_compute::{RegionNumsBasedWeightCompute, WeightCompute};
use crate::selector::weighted_choose::RandomWeightedChoose;
use crate::selector::{Namespace, Selector, SelectorOptions};
@@ -94,7 +94,7 @@ where
// 5. choose peers by weight_array.
let mut weighted_choose = RandomWeightedChoose::new(weight_array);
let selected = choose_peers(&opts, &mut weighted_choose)?;
let selected = choose_items(&opts, &mut weighted_choose)?;
debug!(
"LoadBasedSelector select peers: {:?}, namespace: {}, opts: {:?}.",