Skip to content

Commit eb64e43

Browse files
committed
quinn-proto: deduplicate before defragment if necessary
1 parent 2b3c67a commit eb64e43

File tree

1 file changed

+9
-3
lines changed

1 file changed

+9
-3
lines changed

quinn-proto/src/connection/assembler.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use std::{
2-
cmp::{max, Ordering},
2+
cmp::{max, min, Ordering},
33
collections::{binary_heap::PeekMut, BinaryHeap},
44
mem,
55
};
@@ -19,6 +19,7 @@ pub(crate) struct Assembler {
1919
/// length of the contiguous prefix of the stream which has been consumed by the application,
2020
/// aka the stream offset.
2121
bytes_read: u64,
22+
end: u64,
2223
}
2324

2425
impl Assembler {
@@ -175,6 +176,7 @@ impl Assembler {
175176
allocation_size,
176177
bytes.len()
177178
);
179+
self.end = max(self.end, offset + bytes.len() as u64);
178180
if let State::Unordered { ref mut recvd } = self.state {
179181
// Discard duplicate data
180182
for duplicate in recvd.replace(offset..offset + bytes.len() as u64) {
@@ -216,9 +218,13 @@ impl Assembler {
216218
// of memory allocated. This limits over-allocation in proportion to the
217219
// buffered data. The constants are chosen somewhat arbitrarily and try to
218220
// balance between defragmentation overhead and over-allocation.
219-
let over_allocation = self.allocated - self.buffered;
220-
let threshold = max(self.buffered * 3 / 2, 32 * 1024);
221+
let buffered = min(self.buffered, (self.end - self.bytes_read) as usize);
222+
let over_allocation = self.allocated - buffered;
223+
let threshold = max(buffered * 3 / 2, 32 * 1024);
221224
if over_allocation > threshold {
225+
if self.state.is_ordered() && self.buffered > buffered {
226+
self.deduplicate();
227+
}
222228
self.defragment()
223229
}
224230
}

0 commit comments

Comments
 (0)