Skip to content

Commit 976e66f

Browse files
committed
select: Remove the mode setting in Multiplex
Since the default mode is the best, remove the mode checking makes it faster. (46.723 Melem/s -> 50.793 Melem/s)
1 parent 280e680 commit 976e66f

File tree

2 files changed

+8
-97
lines changed

2 files changed

+8
-97
lines changed

src/select/multiplex.rs

Lines changed: 7 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use super::SelectMode;
21
use crate::backoff::*;
32
use crate::flavor::{Flavor, FlavorBounded, FlavorImpl, FlavorNew, FlavorWrap};
43
use crate::shared::{check_timeout, ChannelShared};
@@ -21,10 +20,7 @@ pub type Mux<F> = FlavorWrap<F, <F as Flavor>::Send, SelectWakerWrapper>;
2120

2221
/// A multiplexer that owns multi channel receivers of the same Flavor type.
2322
///
24-
/// ## selection modes
25-
/// - Round-robin (RR): Fair distribution by cycling through channels
26-
/// - Random (Rand): Random selection from available channels
27-
/// - Bias: Priority based on the order channels were added
23+
/// Unlike select, it focus on round-robin mode
2824
///
2925
/// ## Capability and limitation:
3026
/// - New channel may be added on the fly
@@ -71,7 +67,6 @@ pub type Mux<F> = FlavorWrap<F, <F as Flavor>::Send, SelectWakerWrapper>;
7167
/// h2.join().unwrap();
7268
/// ```
7369
pub struct Multiplex<F: Flavor> {
74-
mode: SelectMode,
7570
waker: Arc<SelectWaker>,
7671
inner: UnsafeCell<MultiplexInner<F>>,
7772
}
@@ -82,70 +77,20 @@ struct MultiplexInner<F: Flavor> {
8277
handlers: Vec<Option<Arc<ChannelShared<Mux<F>>>>>,
8378
next_index: usize,
8479
opened_count: usize,
85-
rng: usize,
8680
}
8781

8882
impl<F: Flavor> MultiplexInner<F> {
8983
#[inline(always)]
9084
fn new() -> Self {
91-
Self { handlers: Vec::with_capacity(10), next_index: 0, rng: 0, opened_count: 0 }
85+
Self { handlers: Vec::with_capacity(10), next_index: 0, opened_count: 0 }
9286
}
9387
}
9488

9589
impl<F: Flavor> Multiplex<F> {
9690
/// Initialize Select with fair, round-robin strategy
9791
pub fn new() -> Self {
98-
Self::new_with(SelectMode::RR)
99-
}
100-
101-
/// Initialize Select with fair strategy (check start from random channel)
102-
///
103-
/// # Example
104-
///
105-
/// ```
106-
/// use crossfire::{mpsc::Array, select::{Multiplex, SelectMode}};
107-
///
108-
/// let mut mp = Multiplex::<Array<i32>>::new_random();
109-
/// // The selection will start from a random channel each time
110-
/// ```
111-
#[inline]
112-
pub fn new_random() -> Self {
113-
Self::new_with(SelectMode::Rand)
114-
}
115-
116-
/// Initialize Select with bias strategy (check according to the order of `add()`)
117-
///
118-
/// # Example
119-
///
120-
/// ```
121-
/// use crossfire::{mpsc::Array, select::{Multiplex, SelectMode}};
122-
///
123-
/// let mut mp = Multiplex::<Array<i32>>::new_bias();
124-
/// // The selection will prioritize channels in the order they were added
125-
/// ```
126-
#[inline]
127-
pub fn new_bias() -> Self {
128-
Self::new_with(SelectMode::Bias)
129-
}
130-
131-
/// Initialize Select with a custom selection mode
132-
///
133-
/// # Arguments
134-
///
135-
/// * `mode` - The selection mode to use (Round-robin, Random, or Bias)
136-
///
137-
/// # Example
138-
///
139-
/// ```
140-
/// use crossfire::{mpsc::Array, select::{Multiplex, SelectMode}};
141-
///
142-
/// let mut mp = Multiplex::<Array<i32>>::new_with(SelectMode::RR);
143-
/// ```
144-
#[inline(always)]
145-
pub fn new_with(mode: SelectMode) -> Self {
14692
Self {
14793
waker: Arc::new(SelectWaker::new()),
148-
mode,
14994
inner: UnsafeCell::new(MultiplexInner::<F>::new()),
15095
}
15196
}
@@ -266,23 +211,10 @@ impl<F: Flavor> Multiplex<F> {
266211
let inner = self.get_inner();
267212
let len = inner.handlers.len();
268213
debug_assert!(len > 0);
269-
match self.mode {
270-
SelectMode::Bias => 0,
271-
SelectMode::RR => {
272-
if inner.next_index >= inner.handlers.len() {
273-
0
274-
} else {
275-
inner.next_index
276-
}
277-
}
278-
SelectMode::Rand => {
279-
let mut x = inner.rng;
280-
x ^= x << 13;
281-
x ^= x >> 7;
282-
x ^= x << 17;
283-
inner.rng = x;
284-
(x as usize) % len
285-
}
214+
if inner.next_index >= inner.handlers.len() {
215+
0
216+
} else {
217+
inner.next_index
286218
}
287219
}
288220

@@ -377,9 +309,7 @@ impl<F: Flavor> Multiplex<F> {
377309
let r = if FINAL { shared.inner.try_recv_final() } else { shared.inner.try_recv() };
378310
if let Some(item) = r {
379311
shared.on_recv();
380-
if SelectMode::RR == self.mode {
381-
inner.next_index = idx + 1;
382-
}
312+
inner.next_index = idx + 1;
383313
return Some(item); // Message available
384314
}
385315
if should_check_close {

test-suite/src/test_select_blocking.rs

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::*;
22
use captains_log::logfn;
3-
use crossfire::select::{Multiplex, Mux, Select, SelectMode};
3+
use crossfire::select::{Multiplex, Mux, Select};
44
use crossfire::*;
55
use rstest::*;
66
use std::sync::atomic::{AtomicUsize, Ordering};
@@ -602,25 +602,6 @@ fn test_multiplex_basic(setup_log: ()) {
602602
assert_eq!(received.len(), 2);
603603
}
604604

605-
#[logfn]
606-
#[rstest]
607-
fn test_multiplex_modes(setup_log: ()) {
608-
let mut mp_rr = Multiplex::<mpsc::Array<i32>>::new_with(SelectMode::RR);
609-
let tx: MTx<_> = mp_rr.bounded_tx(10);
610-
tx.send(42).unwrap();
611-
assert_eq!(mp_rr.recv().unwrap(), 42);
612-
613-
let mut mp_rand = Multiplex::<mpmc::Array<i32>>::new_random();
614-
let tx: MTx<_> = mp_rand.bounded_tx(10);
615-
tx.send(100).unwrap();
616-
assert_eq!(mp_rand.recv().unwrap(), 100);
617-
618-
let mut mp_bias = Multiplex::<spsc::Array<i32>>::new_bias();
619-
let tx: Tx<_> = mp_bias.bounded_tx(10);
620-
tx.send(200).unwrap();
621-
assert_eq!(mp_bias.recv().unwrap(), 200);
622-
}
623-
624605
#[logfn]
625606
#[rstest]
626607
fn test_multiplex_timeout(setup_log: ()) {

0 commit comments

Comments
 (0)