Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf: Optimize packet reception for the common case of adding to the end #1587

Merged
merged 5 commits into from
Feb 2, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 46 additions & 22 deletions neqo-transport/src/recv_stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,26 +200,49 @@ impl RxStreamOrderer {
false
};

// Now handle possible overlap with next entries
let mut to_remove = SmallVec::<[_; 8]>::new();
let mut to_add = new_data;

for (&next_start, next_data) in self.data_ranges.range_mut(new_start..) {
let next_end = next_start + u64::try_from(next_data.len()).unwrap();
let overlap = new_end.saturating_sub(next_start);
if overlap == 0 {
break;
} else if next_end >= new_end {
qtrace!(
"New frame {}-{} overlaps with next frame by {}, truncating",
new_start,
new_end,
overlap
);
let truncate_to = new_data.len() - usize::try_from(overlap).unwrap();
to_add = &new_data[..truncate_to];
break;
} else {
if self
.data_ranges
.last_entry()
.map_or(false, |e| *e.key() >= new_start)
{
// Is this at the end (common case)? If so, nothing to do in this block
// Common case:
// PPPPPP -> PPPPPP
// NNNNNNN NNNNNNN
// or
// PPPPPP -> PPPPPP
// NNNNNNN NNNNNNN
//
// Not the common case, handle possible overlap with next entries
// PPPPPP AAA -> PPPPPP
// NNNNNNN NNNNNNN
// or
// PPPPPP AAAA -> PPPPPP AAAA
// NNNNNNN NNNNN
// or (this is where to_remove is used)
// PPPPPP AA -> PPPPPP
// NNNNNNN NNNNNNN

let mut to_remove = SmallVec::<[_; 8]>::new();

for (&next_start, next_data) in self.data_ranges.range_mut(new_start..) {
let next_end = next_start + u64::try_from(next_data.len()).unwrap();
let overlap = new_end.saturating_sub(next_start);
if overlap == 0 {
// Fills in the hole, exactly (probably common)
break;
} else if next_end >= new_end {
qtrace!(
"New frame {}-{} overlaps with next frame by {}, truncating",
new_start,
new_end,
overlap
);
let truncate_to = new_data.len() - usize::try_from(overlap).unwrap();
to_add = &new_data[..truncate_to];
break;
}
qtrace!(
"New frame {}-{} spans entire next frame {}-{}, replacing",
new_start,
Expand All @@ -228,11 +251,12 @@ impl RxStreamOrderer {
next_end
);
to_remove.push(next_start);
// Continue, since we may have more overlaps
}
}

for start in to_remove {
self.data_ranges.remove(&start);
for start in to_remove {
self.data_ranges.remove(&start);
}
}

if !to_add.is_empty() {
Expand Down
Loading