mirror of
https://github.com/n0-computer/noq.git
synced 2026-09-24 03:58:19 +00:00
Avoid reallocations in ReadToEnd helper future
This commit is contained in:
committed by
Dirkjan Ochtman
parent
e7d988cfef
commit
d038959f2d
+14
-12
@@ -1,5 +1,5 @@
|
||||
use std::io;
|
||||
use std::str;
|
||||
use std::{io, mem};
|
||||
|
||||
use bytes::Bytes;
|
||||
use err_derive::Error;
|
||||
@@ -251,7 +251,8 @@ impl RecvStream {
|
||||
ReadToEnd {
|
||||
stream: Some(self),
|
||||
size_limit,
|
||||
buffer: Vec::new(),
|
||||
read: Vec::new(),
|
||||
len: 0,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -278,7 +279,8 @@ impl RecvStream {
|
||||
/// Future produced by `read_to_end`
|
||||
pub struct ReadToEnd {
|
||||
stream: Option<RecvStream>,
|
||||
buffer: Vec<u8>,
|
||||
read: Vec<(Bytes, usize)>,
|
||||
len: usize,
|
||||
size_limit: usize,
|
||||
}
|
||||
|
||||
@@ -289,22 +291,22 @@ impl Future for ReadToEnd {
|
||||
loop {
|
||||
match self.stream.as_mut().unwrap().poll_read_unordered() {
|
||||
Ok(Async::Ready((data, offset))) => {
|
||||
let len = self.buffer.len().max(offset as usize + data.len());
|
||||
if len > self.size_limit {
|
||||
let end = data.len() as u64 + offset;
|
||||
if end > self.size_limit as u64 {
|
||||
return Err(ReadError::Finished);
|
||||
}
|
||||
self.buffer.resize(len, 0);
|
||||
self.buffer[offset as usize..offset as usize + data.len()]
|
||||
.copy_from_slice(&data);
|
||||
self.len = self.len.max(end as usize);
|
||||
self.read.push((data, offset as usize));
|
||||
}
|
||||
Ok(Async::NotReady) => {
|
||||
return Ok(Async::NotReady);
|
||||
}
|
||||
Err(ReadError::Finished) => {
|
||||
return Ok(Async::Ready((
|
||||
self.stream.take().unwrap(),
|
||||
mem::replace(&mut self.buffer, Vec::new()),
|
||||
)));
|
||||
let mut buffer = vec![0; self.len];
|
||||
for (data, offset) in self.read.drain(..) {
|
||||
buffer[offset..offset + data.len()].copy_from_slice(&data);
|
||||
}
|
||||
return Ok(Async::Ready((self.stream.take().unwrap(), buffer)));
|
||||
}
|
||||
Err(e) => {
|
||||
return Err(e);
|
||||
|
||||
Reference in New Issue
Block a user