Skip to content

Commit b140e97

Browse files
authored
Merge pull request #22 from carlsverre/faster_bytes
faster Slice::from_reader for bytes feature
2 parents 03d434f + d205d76 commit b140e97

File tree

2 files changed

+20
-2
lines changed

2 files changed

+20
-2
lines changed

src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,14 +91,15 @@
9191
9292
#![doc(html_logo_url = "https://raw.githubusercontent.com/fjall-rs/value-log/main/logo.png")]
9393
#![doc(html_favicon_url = "https://raw.githubusercontent.com/fjall-rs/value-log/main/logo.png")]
94-
#![forbid(unsafe_code)]
9594
#![deny(clippy::all, missing_docs, clippy::cargo)]
9695
#![deny(clippy::unwrap_used)]
9796
#![deny(clippy::indexing_slicing)]
9897
#![warn(clippy::pedantic, clippy::nursery)]
9998
#![warn(clippy::expect_used)]
10099
#![allow(clippy::missing_const_for_fn)]
101100
#![warn(clippy::multiple_crate_versions)]
101+
// the bytes feature uses unsafe to improve from_reader performance
102+
#![cfg_attr(not(feature = "bytes"), forbid(unsafe_code))]
102103

103104
mod blob_cache;
104105
mod coding;

src/slice/slice_bytes.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,27 @@ impl Slice {
3737
}
3838

3939
/// Constructs a [`Slice`] from an I/O reader by pulling in `len` bytes.
40+
///
41+
/// The reader may not read the existing buffer.
4042
#[doc(hidden)]
4143
pub fn from_reader<R: std::io::Read>(reader: &mut R, len: usize) -> std::io::Result<Self> {
42-
let mut builder = BytesMut::zeroed(len);
44+
// Use `with_capacity` & `set_len`` to avoid zeroing the buffer
45+
let mut builder = BytesMut::with_capacity(len);
46+
47+
// SAFETY: we just allocated `len` bytes, and `read_exact` will fail if
48+
// it doesn't fill the buffer, subsequently dropping the uninitialized
49+
// BytesMut object
50+
unsafe {
51+
builder.set_len(len);
52+
}
53+
54+
/// SAFETY: Normally, read_exact over an uninitialized buffer is UB,
55+
/// however we know that in lsm-tree etc. only I/O readers or cursors over Vecs are used
56+
/// so it's safe
57+
///
58+
/// The safe API is unstable: https://github.com/rust-lang/rust/issues/78485
4359
reader.read_exact(&mut builder)?;
60+
4461
Ok(Self(builder.freeze()))
4562
}
4663
}

0 commit comments

Comments
 (0)