Skip to content

Commit af40ae5

Browse files
authored
Merge branch 'main' into search
Signed-off-by: Oskar Mansfeld <git@omansfeld.net>
2 parents 0e0109a + 3287939 commit af40ae5

1 file changed

Lines changed: 110 additions & 0 deletions

File tree

neqo-transport/src/cc/mod.rs

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,116 @@ impl CongestionController for CongestionControlImplementation {
231231
}
232232
}
233233

234+
/// A concrete congestion controller, dispatching across all combinations of
235+
/// algorithm and slow-start strategy.
236+
///
237+
/// This enum avoids the heap allocation and vtable indirection of `Box<dyn CongestionController>`
238+
/// on the per-packet hot path.
239+
#[derive(Debug, strum::Display)]
240+
pub enum CongestionControlImplementation {
241+
#[strum(to_string = "{0}")]
242+
ClassicNewReno(ClassicCongestionController<ClassicSlowStart, NewReno>),
243+
#[strum(to_string = "{0}")]
244+
HyStartNewReno(ClassicCongestionController<HyStart, NewReno>),
245+
#[strum(to_string = "{0}")]
246+
ClassicCubic(ClassicCongestionController<ClassicSlowStart, Cubic>),
247+
#[strum(to_string = "{0}")]
248+
HyStartCubic(ClassicCongestionController<HyStart, Cubic>),
249+
}
250+
251+
macro_rules! dispatch {
252+
($self:ident . $method:ident $args:tt) => {
253+
neqo_common::dispatch!(
254+
[ClassicNewReno, HyStartNewReno, ClassicCubic, HyStartCubic]
255+
$self . $method $args
256+
)
257+
};
258+
}
259+
260+
impl CongestionController for CongestionControlImplementation {
261+
fn set_qlog(&mut self, qlog: Qlog) {
262+
dispatch!(self.set_qlog(qlog));
263+
}
264+
265+
fn cwnd(&self) -> usize {
266+
dispatch!(self.cwnd())
267+
}
268+
269+
fn bytes_in_flight(&self) -> usize {
270+
dispatch!(self.bytes_in_flight())
271+
}
272+
273+
fn cwnd_avail(&self) -> usize {
274+
dispatch!(self.cwnd_avail())
275+
}
276+
277+
fn cwnd_min(&self) -> usize {
278+
dispatch!(self.cwnd_min())
279+
}
280+
281+
fn pmtud(&self) -> &Pmtud {
282+
dispatch!(self.pmtud())
283+
}
284+
285+
fn pmtud_mut(&mut self) -> &mut Pmtud {
286+
dispatch!(self.pmtud_mut())
287+
}
288+
289+
fn on_packets_acked(
290+
&mut self,
291+
acked_pkts: &[sent::Packet],
292+
rtt_est: &RttEstimate,
293+
now: Instant,
294+
cc_stats: &mut CongestionControlStats,
295+
) {
296+
dispatch!(self.on_packets_acked(acked_pkts, rtt_est, now, cc_stats));
297+
}
298+
299+
fn on_packets_lost(
300+
&mut self,
301+
first_rtt_sample_time: Option<Instant>,
302+
prev_largest_acked_sent: Option<Instant>,
303+
pto: Duration,
304+
lost_packets: &[sent::Packet],
305+
now: Instant,
306+
cc_stats: &mut CongestionControlStats,
307+
) -> bool {
308+
dispatch!(self.on_packets_lost(
309+
first_rtt_sample_time,
310+
prev_largest_acked_sent,
311+
pto,
312+
lost_packets,
313+
now,
314+
cc_stats,
315+
))
316+
}
317+
318+
fn on_ecn_ce_received(
319+
&mut self,
320+
largest_acked_pkt: &sent::Packet,
321+
now: Instant,
322+
cc_stats: &mut CongestionControlStats,
323+
) -> bool {
324+
dispatch!(self.on_ecn_ce_received(largest_acked_pkt, now, cc_stats))
325+
}
326+
327+
fn recovery_packet(&self) -> bool {
328+
dispatch!(self.recovery_packet())
329+
}
330+
331+
fn discard(&mut self, pkt: &sent::Packet, now: Instant) {
332+
dispatch!(self.discard(pkt, now));
333+
}
334+
335+
fn on_packet_sent(&mut self, pkt: &sent::Packet, now: Instant) {
336+
dispatch!(self.on_packet_sent(pkt, now));
337+
}
338+
339+
fn discard_in_flight(&mut self, now: Instant) {
340+
dispatch!(self.discard_in_flight(now));
341+
}
342+
}
343+
234344
#[cfg(test)]
235345
#[cfg_attr(coverage_nightly, coverage(off))]
236346
mod tests;

0 commit comments

Comments
 (0)