Avoid defensive re-initialization of the BufReader buffer
This commit is contained in:
parent
0ca356586f
commit
95ae993bd8
3 changed files with 48 additions and 3 deletions
|
@ -20,13 +20,19 @@ pub struct Buffer {
|
|||
// Each call to `fill_buf` sets `filled` to indicate how many bytes at the start of `buf` are
|
||||
// initialized with bytes from a read.
|
||||
filled: usize,
|
||||
// This is the max number of bytes returned across all `fill_buf` calls. We track this so that we
|
||||
// can accurately tell `read_buf` how many bytes of buf are initialized, to bypass as much of its
|
||||
// defensive initialization as possible. Note that while this often the same as `filled`, it
|
||||
// doesn't need to be. Calls to `fill_buf` are not required to actually fill the buffer, and
|
||||
// omitting this is a huge perf regression for `Read` impls that do not.
|
||||
initialized: usize,
|
||||
}
|
||||
|
||||
impl Buffer {
|
||||
#[inline]
|
||||
pub fn with_capacity(capacity: usize) -> Self {
|
||||
let buf = Box::new_uninit_slice(capacity);
|
||||
Self { buf, pos: 0, filled: 0 }
|
||||
Self { buf, pos: 0, filled: 0, initialized: 0 }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -51,6 +57,12 @@ impl Buffer {
|
|||
self.pos
|
||||
}
|
||||
|
||||
// This is only used by a test which asserts that the initialization-tracking is correct.
|
||||
#[cfg(test)]
|
||||
pub fn initialized(&self) -> usize {
|
||||
self.initialized
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn discard_buffer(&mut self) {
|
||||
self.pos = 0;
|
||||
|
@ -96,13 +108,14 @@ impl Buffer {
|
|||
let mut buf = BorrowedBuf::from(&mut *self.buf);
|
||||
// SAFETY: `self.filled` bytes will always have been initialized.
|
||||
unsafe {
|
||||
buf.set_init(self.filled);
|
||||
buf.set_init(self.initialized);
|
||||
}
|
||||
|
||||
reader.read_buf(buf.unfilled())?;
|
||||
|
||||
self.filled = buf.len();
|
||||
self.pos = 0;
|
||||
self.filled = buf.len();
|
||||
self.initialized = buf.init_len();
|
||||
}
|
||||
Ok(self.buffer())
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue