Mercurial > hg
changeset 52169:84b5802ba7d3
rust: populate mmap by default if available
See 522b4d729e89edc76544fa549ed36de4aea0b7fb for more details.
Background population to follow in a later patch.
author | Raphaël Gomès <rgomes@octobus.net> |
---|---|
date | Thu, 26 Sep 2024 13:55:26 +0200 |
parents | 6b7ffa3f9199 |
children | 1a8466fd904a |
files | rust/hg-core/src/revlog/mod.rs rust/hg-core/src/revlog/options.rs |
diffstat | 2 files changed, 33 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/rust/hg-core/src/revlog/mod.rs Wed Jun 19 18:20:22 2024 +0200 +++ b/rust/hg-core/src/revlog/mod.rs Thu Sep 26 13:55:26 2024 +0200 @@ -503,6 +503,10 @@ { let size = store_vfs.file_size(&file)?; if size >= threshold { + // TODO madvise populate read in a background thread + let mut mmap_options = MmapOptions::new(); + // This does nothing on platforms where it's not defined + mmap_options.populate(); // Safety is "enforced" by locks and assuming other // processes are well-behaved. If any misbehaving or // malicious process does touch the index, it could lead @@ -510,7 +514,7 @@ // `mmap`, though some platforms have some ways of // mitigating. // TODO linux: set the immutable flag with `chattr(1)`? - let mmap = unsafe { MmapOptions::new().map(&file) } + let mmap = unsafe { mmap_options.map(&file) } .when_reading_file(index_path)?; Some(Box::new(mmap) as IndexData) } else {
--- a/rust/hg-core/src/revlog/options.rs Wed Jun 19 18:20:22 2024 +0200 +++ b/rust/hg-core/src/revlog/options.rs Thu Sep 26 13:55:26 2024 +0200 @@ -103,6 +103,20 @@ } } +/// Technically only Linux 2.5.46+ has `MAP_POPULATE` and only `2.6.23` on +/// private mappings, but if you're using such ancient Linux, you have other +/// problems. +#[cfg(target_os = "linux")] +const fn can_populate_mmap() -> bool { + true +} + +/// There is a of populating mmaps for Windows, but it would need testing. +#[cfg(not(target_os = "linux"))] +const fn can_populate_mmap() { + false +} + #[derive(Debug, Clone, Copy, PartialEq)] /// Holds configuration values about how the revlog data is read pub struct RevlogDataConfig { @@ -155,6 +169,20 @@ } } + // Use mmap if requested, or by default if we can fully populate it + let mmap_index = config + .get_option_no_default(b"storage", b"revlog.mmap.index")? + .unwrap_or(can_populate_mmap()); + if mmap_index { + if let Some(mmap_index_threshold) = config.get_byte_size( + b"storage", + b"revlog.mmap.index:size-threshold", + )? { + // Only mmap if above the requested size threshold + data_config.mmap_index_threshold = Some(mmap_index_threshold); + } + } + if let Some(mmap_index_threshold) = config .get_byte_size(b"storage", b"revlog.mmap.index:size-threshold")? {