Skip to content

Commit 60eccca

Browse files
committed
Added support for madvise
1 parent f479840 commit 60eccca

File tree

3 files changed

+66
-9
lines changed

3 files changed

+66
-9
lines changed

Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ base64 = "0.21.0"
1919
byteorder = "1.4.3"
2020
crc32fast = "1.3.2"
2121
once_cell = "1.10.0"
22+
madvise = { version="0.1", optional= true }
2223
regex = { version = "1.5.5", default-features = false, features = ["std", "unicode"] }
2324
aho-corasick = "1.0"
2425
tantivy-fst = "0.4.0"
@@ -100,6 +101,7 @@ overflow-checks = true
100101
default = ["mmap", "stopwords", "lz4-compression"]
101102
mmap = ["fs4", "tempfile", "memmap2"]
102103
stopwords = []
104+
madvise = ["dep:madvise"]
103105

104106
brotli-compression = ["brotli"]
105107
lz4-compression = ["lz4_flex"]

src/directory/mmap_directory.rs

+61-9
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ use std::{fmt, result};
88

99
use common::StableDeref;
1010
use fs4::FileExt;
11+
12+
#[cfg(feature="madvise")]
13+
use crate::AccessPattern;
14+
#[cfg(not(feature="madvise"))]
15+
type AccessPattern = ();
16+
1117
use memmap2::Mmap;
1218
use serde::{Deserialize, Serialize};
1319
use tempfile::TempDir;
@@ -32,7 +38,11 @@ pub(crate) fn make_io_err(msg: String) -> io::Error {
3238

3339
/// Returns `None` iff the file exists, can be read, but is empty (and hence
3440
/// cannot be mmapped)
35-
fn open_mmap(full_path: &Path) -> result::Result<Option<Mmap>, OpenReadError> {
41+
#[allow(unused_variables)]
42+
fn open_mmap(
43+
full_path: &Path,
44+
access_pattern_opt: Option<AccessPattern>,
45+
) -> result::Result<Option<Mmap>, OpenReadError> {
3646
let file = File::open(full_path).map_err(|io_err| {
3747
if io_err.kind() == io::ErrorKind::NotFound {
3848
OpenReadError::FileDoesNotExist(full_path.to_path_buf())
@@ -50,11 +60,20 @@ fn open_mmap(full_path: &Path) -> result::Result<Option<Mmap>, OpenReadError> {
5060
// instead.
5161
return Ok(None);
5262
}
53-
unsafe {
63+
let mmap_opt: Option<memmap2::Mmap> = unsafe {
5464
memmap2::Mmap::map(&file)
5565
.map(Some)
5666
.map_err(|io_err| OpenReadError::wrap_io_error(io_err, full_path.to_path_buf()))
67+
}?;
68+
#[cfg(feature="madvise")]
69+
match (&mmap_opt, access_pattern_opt) {
70+
(Some(mmap), Some(access_pattern)) => {
71+
use madvise::AdviseMemory;
72+
let _ = mmap.advise_memory_access(access_pattern);
73+
}
74+
_ => {}
5775
}
76+
Ok(mmap_opt)
5877
}
5978

6079
#[derive(Default, Clone, Debug, Serialize, Deserialize)]
@@ -72,13 +91,21 @@ pub struct CacheInfo {
7291
pub mmapped: Vec<PathBuf>,
7392
}
7493

75-
#[derive(Default)]
7694
struct MmapCache {
7795
counters: CacheCounters,
7896
cache: HashMap<PathBuf, WeakArcBytes>,
97+
access_pattern_opt: Option<AccessPattern>,
7998
}
8099

81100
impl MmapCache {
101+
fn new(access_pattern_opt: Option<AccessPattern>) -> MmapCache {
102+
MmapCache {
103+
counters: CacheCounters::default(),
104+
cache: HashMap::default(),
105+
access_pattern_opt,
106+
}
107+
}
108+
82109
fn get_info(&self) -> CacheInfo {
83110
let paths: Vec<PathBuf> = self.cache.keys().cloned().collect();
84111
CacheInfo {
@@ -109,7 +136,7 @@ impl MmapCache {
109136
}
110137
self.cache.remove(full_path);
111138
self.counters.miss += 1;
112-
let mmap_opt = open_mmap(full_path)?;
139+
let mmap_opt = open_mmap(full_path, self.access_pattern_opt)?;
113140
Ok(mmap_opt.map(|mmap| {
114141
let mmap_arc: ArcBytes = Arc::new(mmap);
115142
let mmap_weak = Arc::downgrade(&mmap_arc);
@@ -144,9 +171,13 @@ struct MmapDirectoryInner {
144171
}
145172

146173
impl MmapDirectoryInner {
147-
fn new(root_path: PathBuf, temp_directory: Option<TempDir>) -> MmapDirectoryInner {
174+
fn new(
175+
root_path: PathBuf,
176+
temp_directory: Option<TempDir>,
177+
access_pattern_opt: Option<AccessPattern>,
178+
) -> MmapDirectoryInner {
148179
MmapDirectoryInner {
149-
mmap_cache: Default::default(),
180+
mmap_cache: RwLock::new(MmapCache::new(access_pattern_opt)),
150181
_temp_directory: temp_directory,
151182
watcher: FileWatcher::new(&root_path.join(*META_FILEPATH)),
152183
root_path,
@@ -165,8 +196,12 @@ impl fmt::Debug for MmapDirectory {
165196
}
166197

167198
impl MmapDirectory {
168-
fn new(root_path: PathBuf, temp_directory: Option<TempDir>) -> MmapDirectory {
169-
let inner = MmapDirectoryInner::new(root_path, temp_directory);
199+
fn new(
200+
root_path: PathBuf,
201+
temp_directory: Option<TempDir>,
202+
access_pattern_opt: Option<AccessPattern>,
203+
) -> MmapDirectory {
204+
let inner = MmapDirectoryInner::new(root_path, temp_directory, access_pattern_opt);
170205
MmapDirectory {
171206
inner: Arc::new(inner),
172207
}
@@ -182,6 +217,7 @@ impl MmapDirectory {
182217
Ok(MmapDirectory::new(
183218
tempdir.path().to_path_buf(),
184219
Some(tempdir),
220+
None,
185221
))
186222
}
187223

@@ -190,6 +226,22 @@ impl MmapDirectory {
190226
/// Returns an error if the `directory_path` does not
191227
/// exist or if it is not a directory.
192228
pub fn open<P: AsRef<Path>>(directory_path: P) -> Result<MmapDirectory, OpenDirectoryError> {
229+
Self::open_with_access_pattern_impl(directory_path.as_ref(), None)
230+
}
231+
232+
/// Opens a MmapDirectory in a directory, with a given access pattern.
233+
#[cfg(feature="madvise")]
234+
pub fn open_with_access_pattern<P: AsRef<Path>>(
235+
directory_path: &Path,
236+
access_pattern: AccessPattern
237+
) -> Result<MmapDirectory, OpenDirectoryError> {
238+
Self::open_with_access_pattern_impl(directory_path.as_ref(), Some(access_pattern))
239+
}
240+
241+
fn open_with_access_pattern_impl(
242+
directory_path: &Path,
243+
access_pattern_opt: Option<AccessPattern>,
244+
) -> Result<MmapDirectory, OpenDirectoryError> {
193245
let directory_path: &Path = directory_path.as_ref();
194246
if !directory_path.exists() {
195247
return Err(OpenDirectoryError::DoesNotExist(PathBuf::from(
@@ -217,7 +269,7 @@ impl MmapDirectory {
217269
directory_path,
218270
)));
219271
}
220-
Ok(MmapDirectory::new(canonical_path, None))
272+
Ok(MmapDirectory::new(canonical_path, None, access_pattern_opt))
221273
}
222274

223275
/// Joins a relative_path to the directory `root_path`

src/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,9 @@ pub use crate::schema::{DateOptions, DatePrecision, Document, Term};
189189
/// Index format version.
190190
const INDEX_FORMAT_VERSION: u32 = 5;
191191

192+
#[cfg(feature="madvise")]
193+
pub use madvise::AccessPattern;
194+
192195
/// Structure version for the index.
193196
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)]
194197
pub struct Version {

0 commit comments

Comments
 (0)