Skip to content

Commit 7220df8

Browse files
Fix building on windows with mmap (#2070)
* Fix windows build * Make pub * Update docs * Re arrange * Fix compilation error on unix * Fix unix borrows * Revert "Fix unix borrows" This reverts commit c1d94fd. * Fix unix borrows and revert original change * Fix warning * Cleaner code. --------- Co-authored-by: Paul Masurel <[email protected]>
1 parent e3eacb4 commit 7220df8

File tree

2 files changed

+49
-39
lines changed

2 files changed

+49
-39
lines changed

src/directory/mmap_directory.rs

+48-39
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
use std::collections::HashMap;
2+
use std::fmt;
23
use std::fs::{self, File, OpenOptions};
34
use std::io::{self, BufWriter, Read, Seek, Write};
45
use std::ops::Deref;
56
use std::path::{Path, PathBuf};
67
use std::sync::{Arc, RwLock, Weak};
7-
use std::{fmt, result};
88

99
use common::StableDeref;
1010
use fs4::FileExt;
@@ -21,6 +21,7 @@ use crate::directory::{
2121
AntiCallToken, Directory, DirectoryLock, FileHandle, Lock, OwnedBytes, TerminatingWrite,
2222
WatchCallback, WatchHandle, WritePtr,
2323
};
24+
#[cfg(unix)]
2425
use crate::Advice;
2526

2627
pub type ArcBytes = Arc<dyn Deref<Target = [u8]> + Send + Sync + 'static>;
@@ -33,10 +34,7 @@ pub(crate) fn make_io_err(msg: String) -> io::Error {
3334

3435
/// Returns `None` iff the file exists, can be read, but is empty (and hence
3536
/// cannot be mmapped)
36-
fn open_mmap(
37-
full_path: &Path,
38-
madvice_opt: Option<Advice>,
39-
) -> result::Result<Option<Mmap>, OpenReadError> {
37+
fn open_mmap(full_path: &Path) -> Result<Option<Mmap>, OpenReadError> {
4038
let file = File::open(full_path).map_err(|io_err| {
4139
if io_err.kind() == io::ErrorKind::NotFound {
4240
OpenReadError::FileDoesNotExist(full_path.to_path_buf())
@@ -59,9 +57,7 @@ fn open_mmap(
5957
.map(Some)
6058
.map_err(|io_err| OpenReadError::wrap_io_error(io_err, full_path.to_path_buf()))
6159
}?;
62-
if let (Some(mmap), Some(madvice)) = (&mmap_opt, madvice_opt) {
63-
let _ = mmap.advise(madvice);
64-
}
60+
6561
Ok(mmap_opt)
6662
}
6763

@@ -83,18 +79,25 @@ pub struct CacheInfo {
8379
struct MmapCache {
8480
counters: CacheCounters,
8581
cache: HashMap<PathBuf, WeakArcBytes>,
82+
#[cfg(unix)]
8683
madvice_opt: Option<Advice>,
8784
}
8885

8986
impl MmapCache {
90-
fn new(madvice_opt: Option<Advice>) -> MmapCache {
87+
fn new() -> MmapCache {
9188
MmapCache {
9289
counters: CacheCounters::default(),
9390
cache: HashMap::default(),
94-
madvice_opt,
91+
#[cfg(unix)]
92+
madvice_opt: None,
9593
}
9694
}
9795

96+
#[cfg(unix)]
97+
fn set_advice(&mut self, madvice: Advice) {
98+
self.madvice_opt = Some(madvice);
99+
}
100+
98101
fn get_info(&self) -> CacheInfo {
99102
let paths: Vec<PathBuf> = self.cache.keys().cloned().collect();
100103
CacheInfo {
@@ -115,6 +118,16 @@ impl MmapCache {
115118
}
116119
}
117120

121+
fn open_mmap_impl(&self, full_path: &Path) -> Result<Option<Mmap>, OpenReadError> {
122+
let mmap_opt = open_mmap(full_path)?;
123+
#[cfg(unix)]
124+
if let (Some(mmap), Some(madvice)) = (mmap_opt.as_ref(), self.madvice_opt) {
125+
// We ignore madvise errors.
126+
let _ = mmap.advise(madvice);
127+
}
128+
Ok(mmap_opt)
129+
}
130+
118131
// Returns None if the file exists but as a len of 0 (and hence is not mmappable).
119132
fn get_mmap(&mut self, full_path: &Path) -> Result<Option<ArcBytes>, OpenReadError> {
120133
if let Some(mmap_weak) = self.cache.get(full_path) {
@@ -125,7 +138,7 @@ impl MmapCache {
125138
}
126139
self.cache.remove(full_path);
127140
self.counters.miss += 1;
128-
let mmap_opt = open_mmap(full_path, self.madvice_opt)?;
141+
let mmap_opt = self.open_mmap_impl(full_path)?;
129142
Ok(mmap_opt.map(|mmap| {
130143
let mmap_arc: ArcBytes = Arc::new(mmap);
131144
let mmap_weak = Arc::downgrade(&mmap_arc);
@@ -160,13 +173,9 @@ struct MmapDirectoryInner {
160173
}
161174

162175
impl MmapDirectoryInner {
163-
fn new(
164-
root_path: PathBuf,
165-
temp_directory: Option<TempDir>,
166-
madvice_opt: Option<Advice>,
167-
) -> MmapDirectoryInner {
176+
fn new(root_path: PathBuf, temp_directory: Option<TempDir>) -> MmapDirectoryInner {
168177
MmapDirectoryInner {
169-
mmap_cache: RwLock::new(MmapCache::new(madvice_opt)),
178+
mmap_cache: RwLock::new(MmapCache::new()),
170179
_temp_directory: temp_directory,
171180
watcher: FileWatcher::new(&root_path.join(*META_FILEPATH)),
172181
root_path,
@@ -185,12 +194,8 @@ impl fmt::Debug for MmapDirectory {
185194
}
186195

187196
impl MmapDirectory {
188-
fn new(
189-
root_path: PathBuf,
190-
temp_directory: Option<TempDir>,
191-
madvice_opt: Option<Advice>,
192-
) -> MmapDirectory {
193-
let inner = MmapDirectoryInner::new(root_path, temp_directory, madvice_opt);
197+
fn new(root_path: PathBuf, temp_directory: Option<TempDir>) -> MmapDirectory {
198+
let inner = MmapDirectoryInner::new(root_path, temp_directory);
194199
MmapDirectory {
195200
inner: Arc::new(inner),
196201
}
@@ -206,29 +211,33 @@ impl MmapDirectory {
206211
Ok(MmapDirectory::new(
207212
tempdir.path().to_path_buf(),
208213
Some(tempdir),
209-
None,
210214
))
211215
}
212216

217+
/// Opens a MmapDirectory in a directory, with a given access pattern.
218+
///
219+
/// This is only supported on unix platforms.
220+
#[cfg(unix)]
221+
pub fn open_with_madvice(
222+
directory_path: impl AsRef<Path>,
223+
madvice: Advice,
224+
) -> Result<MmapDirectory, OpenDirectoryError> {
225+
let dir = Self::open_impl_to_avoid_monomorphization(directory_path.as_ref())?;
226+
dir.inner.mmap_cache.write().unwrap().set_advice(madvice);
227+
Ok(dir)
228+
}
229+
213230
/// Opens a MmapDirectory in a directory.
214231
///
215232
/// Returns an error if the `directory_path` does not
216233
/// exist or if it is not a directory.
217-
pub fn open<P: AsRef<Path>>(directory_path: P) -> Result<MmapDirectory, OpenDirectoryError> {
218-
Self::open_with_access_pattern_impl(directory_path.as_ref(), None)
219-
}
220-
221-
/// Opens a MmapDirectory in a directory, with a given access pattern.
222-
pub fn open_with_madvice<P: AsRef<Path>>(
223-
directory_path: P,
224-
madvice: Advice,
225-
) -> Result<MmapDirectory, OpenDirectoryError> {
226-
Self::open_with_access_pattern_impl(directory_path.as_ref(), Some(madvice))
234+
pub fn open(directory_path: impl AsRef<Path>) -> Result<MmapDirectory, OpenDirectoryError> {
235+
Self::open_impl_to_avoid_monomorphization(directory_path.as_ref())
227236
}
228237

229-
fn open_with_access_pattern_impl(
238+
#[inline(never)]
239+
fn open_impl_to_avoid_monomorphization(
230240
directory_path: &Path,
231-
madvice_opt: Option<Advice>,
232241
) -> Result<MmapDirectory, OpenDirectoryError> {
233242
if !directory_path.exists() {
234243
return Err(OpenDirectoryError::DoesNotExist(PathBuf::from(
@@ -256,7 +265,7 @@ impl MmapDirectory {
256265
directory_path,
257266
)));
258267
}
259-
Ok(MmapDirectory::new(canonical_path, None, madvice_opt))
268+
Ok(MmapDirectory::new(canonical_path, None))
260269
}
261270

262271
/// Joins a relative_path to the directory `root_path`
@@ -365,7 +374,7 @@ pub(crate) fn atomic_write(path: &Path, content: &[u8]) -> io::Result<()> {
365374
}
366375

367376
impl Directory for MmapDirectory {
368-
fn get_file_handle(&self, path: &Path) -> result::Result<Arc<dyn FileHandle>, OpenReadError> {
377+
fn get_file_handle(&self, path: &Path) -> Result<Arc<dyn FileHandle>, OpenReadError> {
369378
debug!("Open Read {:?}", path);
370379
let full_path = self.resolve_path(path);
371380

@@ -388,7 +397,7 @@ impl Directory for MmapDirectory {
388397

389398
/// Any entry associated with the path in the mmap will be
390399
/// removed before the file is deleted.
391-
fn delete(&self, path: &Path) -> result::Result<(), DeleteError> {
400+
fn delete(&self, path: &Path) -> Result<(), DeleteError> {
392401
let full_path = self.resolve_path(path);
393402
fs::remove_file(full_path).map_err(|e| {
394403
if e.kind() == io::ErrorKind::NotFound {

src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ pub use crate::schema::{DateOptions, DateTimePrecision, Document, Term};
191191
/// Index format version.
192192
const INDEX_FORMAT_VERSION: u32 = 5;
193193

194+
#[cfg(unix)]
194195
pub use memmap2::Advice;
195196

196197
/// Structure version for the index.

0 commit comments

Comments
 (0)