Skip to content

Commit 58de0b2

Browse files
authored
feat(mmap): new feature for mmap-based optimization (#49)
Ref: #48
1 parent 81bc84b commit 58de0b2

File tree

2 files changed

+44
-38
lines changed

2 files changed

+44
-38
lines changed

Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ digest = "0.10.6"
1616
either = "1.6.1"
1717
futures = "0.3.17"
1818
hex = "0.4.3"
19-
memmap2 = "0.5.8"
19+
memmap2 = { version = "0.5.8", optional = true }
2020
miette = "5.7.0"
2121
reflink = "0.1.3"
2222
serde = "1.0.130"
@@ -53,6 +53,7 @@ name = "benchmarks"
5353
harness = false
5454

5555
[features]
56-
default = ["async-std"]
56+
default = ["async-std", "mmap"]
57+
mmap = ["memmap2"]
5758
link_to = []
5859
tokio-runtime = ["tokio", "tokio-stream"]

src/content/write.rs

Lines changed: 41 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use std::sync::Mutex;
66
use std::task::{Context, Poll};
77

88
use futures::prelude::*;
9+
#[cfg(feature = "mmap")]
910
use memmap2::MmapMut;
1011
use ssri::{Algorithm, Integrity, IntegrityOpts};
1112
use tempfile::NamedTempFile;
@@ -14,8 +15,23 @@ use crate::async_lib::{AsyncWrite, JoinHandle};
1415
use crate::content::path;
1516
use crate::errors::{IoErrorExt, Result};
1617

18+
#[cfg(feature = "mmap")]
1719
pub const MAX_MMAP_SIZE: usize = 1024 * 1024;
1820

21+
#[cfg(not(feature = "mmap"))]
22+
struct MmapMut;
23+
24+
#[cfg(not(feature = "mmap"))]
25+
impl MmapMut {
26+
fn flush_async(&self) -> std::io::Result<()> {
27+
panic!()
28+
}
29+
30+
fn copy_from_slice(&self, _: &[u8]) {
31+
panic!()
32+
}
33+
}
34+
1935
pub struct Writer {
2036
cache: PathBuf,
2137
builder: IntegrityOpts,
@@ -44,24 +60,7 @@ impl Writer {
4460
tmp_path_clone.display()
4561
)
4662
})?;
47-
let mmap = if let Some(size) = size {
48-
if size <= MAX_MMAP_SIZE {
49-
tmpfile
50-
.as_file_mut()
51-
.set_len(size as u64)
52-
.with_context(|| {
53-
format!(
54-
"Failed to configure file length for temp file at {}",
55-
tmpfile.path().display()
56-
)
57-
})?;
58-
unsafe { MmapMut::map_mut(tmpfile.as_file()).ok() }
59-
} else {
60-
None
61-
}
62-
} else {
63-
None
64-
};
63+
let mmap = make_mmap(&mut tmpfile, size)?;
6564
Ok(Writer {
6665
cache: cache_path,
6766
builder: IntegrityOpts::new().algorithm(algo),
@@ -162,24 +161,7 @@ impl AsyncWriter {
162161
)
163162
})?;
164163
let mut tmpfile = crate::async_lib::create_named_tempfile(tmp_path).await?;
165-
let mmap = if let Some(size) = size {
166-
if size <= MAX_MMAP_SIZE {
167-
tmpfile
168-
.as_file_mut()
169-
.set_len(size as u64)
170-
.with_context(|| {
171-
format!(
172-
"Failed to configure file length for temp file at {}",
173-
tmpfile.path().display()
174-
)
175-
})?;
176-
unsafe { MmapMut::map_mut(tmpfile.as_file()).ok() }
177-
} else {
178-
None
179-
}
180-
} else {
181-
None
182-
};
164+
let mmap = make_mmap(&mut tmpfile, size)?;
183165
Ok(AsyncWriter(Mutex::new(State::Idle(Some(Inner {
184166
cache: cache_path,
185167
builder: IntegrityOpts::new().algorithm(algo),
@@ -428,6 +410,29 @@ impl AsyncWriter {
428410
}
429411
}
430412

413+
#[cfg(feature = "mmap")]
414+
fn make_mmap(tmpfile: &mut NamedTempFile, size: Option<usize>) -> Result<Option<MmapMut>> {
415+
if let Some(size @ 0..=MAX_MMAP_SIZE) = size {
416+
tmpfile
417+
.as_file_mut()
418+
.set_len(size as u64)
419+
.with_context(|| {
420+
format!(
421+
"Failed to configure file length for temp file at {}",
422+
tmpfile.path().display()
423+
)
424+
})?;
425+
Ok(unsafe { MmapMut::map_mut(tmpfile.as_file()).ok() })
426+
} else {
427+
Ok(None)
428+
}
429+
}
430+
431+
#[cfg(not(feature = "mmap"))]
432+
fn make_mmap(_: &mut NamedTempFile, _: Option<usize>) -> Result<Option<MmapMut>> {
433+
Ok(None)
434+
}
435+
431436
#[cfg(test)]
432437
mod tests {
433438
use super::*;

0 commit comments

Comments
 (0)