Pre-allocate buffers in File::open_buffered
and create_buffered
This commit is contained in:
parent
ee129b12ed
commit
1e9a50dde8
5 changed files with 38 additions and 3 deletions
|
@ -407,7 +407,10 @@ impl File {
|
||||||
/// ```
|
/// ```
|
||||||
#[unstable(feature = "file_buffered", issue = "none")]
|
#[unstable(feature = "file_buffered", issue = "none")]
|
||||||
pub fn open_buffered<P: AsRef<Path>>(path: P) -> io::Result<io::BufReader<File>> {
|
pub fn open_buffered<P: AsRef<Path>>(path: P) -> io::Result<io::BufReader<File>> {
|
||||||
File::open(path).map(io::BufReader::new)
|
// Allocate the buffer *first* so we don't affect the filesystem otherwise.
|
||||||
|
let buffer = io::BufReader::<Self>::try_new_buffer()?;
|
||||||
|
let file = File::open(path)?;
|
||||||
|
Ok(io::BufReader::with_buffer(file, buffer))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Opens a file in write-only mode.
|
/// Opens a file in write-only mode.
|
||||||
|
@ -472,7 +475,10 @@ impl File {
|
||||||
/// ```
|
/// ```
|
||||||
#[unstable(feature = "file_buffered", issue = "none")]
|
#[unstable(feature = "file_buffered", issue = "none")]
|
||||||
pub fn create_buffered<P: AsRef<Path>>(path: P) -> io::Result<io::BufWriter<File>> {
|
pub fn create_buffered<P: AsRef<Path>>(path: P) -> io::Result<io::BufWriter<File>> {
|
||||||
File::create(path).map(io::BufWriter::new)
|
// Allocate the buffer *first* so we don't affect the filesystem otherwise.
|
||||||
|
let buffer = io::BufWriter::<Self>::try_new_buffer()?;
|
||||||
|
let file = File::create(path)?;
|
||||||
|
Ok(io::BufWriter::with_buffer(file, buffer))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new file in read-write mode; error if the file exists.
|
/// Creates a new file in read-write mode; error if the file exists.
|
||||||
|
|
|
@ -74,6 +74,14 @@ impl<R: Read> BufReader<R> {
|
||||||
BufReader::with_capacity(DEFAULT_BUF_SIZE, inner)
|
BufReader::with_capacity(DEFAULT_BUF_SIZE, inner)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn try_new_buffer() -> io::Result<Buffer> {
|
||||||
|
Buffer::try_with_capacity(DEFAULT_BUF_SIZE)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn with_buffer(inner: R, buf: Buffer) -> Self {
|
||||||
|
Self { inner, buf }
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates a new `BufReader<R>` with the specified buffer capacity.
|
/// Creates a new `BufReader<R>` with the specified buffer capacity.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
//! without encountering any runtime bounds checks.
|
//! without encountering any runtime bounds checks.
|
||||||
|
|
||||||
use crate::cmp;
|
use crate::cmp;
|
||||||
use crate::io::{self, BorrowedBuf, Read};
|
use crate::io::{self, BorrowedBuf, ErrorKind, Read};
|
||||||
use crate::mem::MaybeUninit;
|
use crate::mem::MaybeUninit;
|
||||||
|
|
||||||
pub struct Buffer {
|
pub struct Buffer {
|
||||||
|
@ -36,6 +36,16 @@ impl Buffer {
|
||||||
Self { buf, pos: 0, filled: 0, initialized: 0 }
|
Self { buf, pos: 0, filled: 0, initialized: 0 }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn try_with_capacity(capacity: usize) -> io::Result<Self> {
|
||||||
|
match Box::try_new_uninit_slice(capacity) {
|
||||||
|
Ok(buf) => Ok(Self { buf, pos: 0, filled: 0, initialized: 0 }),
|
||||||
|
Err(_) => {
|
||||||
|
Err(io::const_io_error!(ErrorKind::OutOfMemory, "failed to allocate read buffer"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn buffer(&self) -> &[u8] {
|
pub fn buffer(&self) -> &[u8] {
|
||||||
// SAFETY: self.pos and self.cap are valid, and self.cap => self.pos, and
|
// SAFETY: self.pos and self.cap are valid, and self.cap => self.pos, and
|
||||||
|
|
|
@ -94,6 +94,16 @@ impl<W: Write> BufWriter<W> {
|
||||||
BufWriter::with_capacity(DEFAULT_BUF_SIZE, inner)
|
BufWriter::with_capacity(DEFAULT_BUF_SIZE, inner)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn try_new_buffer() -> io::Result<Vec<u8>> {
|
||||||
|
Vec::try_with_capacity(DEFAULT_BUF_SIZE).map_err(|_| {
|
||||||
|
io::const_io_error!(ErrorKind::OutOfMemory, "failed to allocate write buffer")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn with_buffer(inner: W, buf: Vec<u8>) -> Self {
|
||||||
|
Self { inner, buf, panicked: false }
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates a new `BufWriter<W>` with at least the specified buffer capacity.
|
/// Creates a new `BufWriter<W>` with at least the specified buffer capacity.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
|
|
|
@ -374,6 +374,7 @@
|
||||||
#![feature(slice_concat_trait)]
|
#![feature(slice_concat_trait)]
|
||||||
#![feature(thin_box)]
|
#![feature(thin_box)]
|
||||||
#![feature(try_reserve_kind)]
|
#![feature(try_reserve_kind)]
|
||||||
|
#![feature(try_with_capacity)]
|
||||||
#![feature(vec_into_raw_parts)]
|
#![feature(vec_into_raw_parts)]
|
||||||
// tidy-alphabetical-end
|
// tidy-alphabetical-end
|
||||||
//
|
//
|
||||||
|
|
Loading…
Add table
Reference in a new issue