From c4dc58a3b45ab56f09c7baef3c679c1a80ee4ee9 Mon Sep 17 00:00:00 2001 From: Seongmin Lee Date: Tue, 29 Sep 2026 04:53:46 +0900 Subject: [PATCH] slop: nix,gix-pack: welcome back mmap! Signed-off-by: Seongmin Lee --- Cargo.lock | 1 + knot2/third_party/gix-pack/Cargo.toml | 3 ++ knot2/third_party/gix-pack/src/data/mod.rs | 6 +++- knot2/third_party/gix-pack/src/lib.rs | 33 ++++++---------------- nix/Cargo.nix | 4 +++ 5 files changed, 21 insertions(+), 26 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b0b83d979..758c7d407 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3689,6 +3689,7 @@ dependencies = [ "gix-path", "gix-tempfile", "gix-traverse", + "memmap2", "parking_lot", "smallvec", "thiserror 2.0.18", diff --git a/knot2/third_party/gix-pack/Cargo.toml b/knot2/third_party/gix-pack/Cargo.toml index e482f053b..dd0ebff6b 100644 --- a/knot2/third_party/gix-pack/Cargo.toml +++ b/knot2/third_party/gix-pack/Cargo.toml @@ -121,6 +121,9 @@ version = "^0.12.1" version = "^0.58.0" optional = true +[dependencies.memmap2] +version = "0.9.10" + [dependencies.parking_lot] version = "0.12.4" optional = true diff --git a/knot2/third_party/gix-pack/src/data/mod.rs b/knot2/third_party/gix-pack/src/data/mod.rs index f2058ee75..3bbb37f0c 100644 --- a/knot2/third_party/gix-pack/src/data/mod.rs +++ b/knot2/third_party/gix-pack/src/data/mod.rs @@ -143,7 +143,11 @@ impl File { } pub(crate) fn materialized(&self) -> std::io::Result { - crate::MMap::map(&self.file) + // SAFETY: we have to take the risk of somebody changing the file underneath. Git never writes into the same file. + #[expect(unsafe_code)] + unsafe { + memmap2::MmapOptions::new().map_copy_read_only(&self.file) + } } /// Returns the pack data at the given slice if its range is contained in the pack data. diff --git a/knot2/third_party/gix-pack/src/lib.rs b/knot2/third_party/gix-pack/src/lib.rs index 478f85c8b..9b7f4a7c8 100755 --- a/knot2/third_party/gix-pack/src/lib.rs +++ b/knot2/third_party/gix-pack/src/lib.rs @@ -20,29 +20,7 @@ use std::{borrow::Cow, ops::Deref, path::Path}; -/// The default in-memory backing store for index and multi-index files. -#[allow(missing_docs)] -pub struct MMap(Vec); - -impl MMap { - #[allow(missing_docs)] - pub fn map(file: &std::fs::File) -> std::io::Result { - use std::os::unix::fs::FileExt; - let len = usize::try_from(file.metadata()?.len()) - .map_err(|_| std::io::Error::other("file too large to load into memory"))?; - let mut bytes = vec![0u8; len]; - file.read_exact_at(&mut bytes, 0)?; - Ok(MMap(bytes)) - } -} - -impl Deref for MMap { - type Target = [u8]; - - fn deref(&self) -> &[u8] { - &self.0 - } -} +pub use memmap2::Mmap as MMap; /// A byte-oriented backing store for pack data and indices. pub trait FileData: Deref {} @@ -81,8 +59,13 @@ pub mod verify; mod mmap { use std::path::Path; - pub fn read_only(path: &Path) -> std::io::Result { - Ok(super::MMap(std::fs::read(path)?)) + pub fn read_only(path: &Path) -> std::io::Result { + let file = std::fs::File::open(path)?; + // SAFETY: we have to take the risk of somebody changing the file underneath. Git never writes into the same file. + #[expect(unsafe_code)] + unsafe { + memmap2::MmapOptions::new().map_copy_read_only(&file) + } } } diff --git a/nix/Cargo.nix b/nix/Cargo.nix index 10cfcdef3..3b43cac70 100644 --- a/nix/Cargo.nix +++ b/nix/Cargo.nix @@ -13236,6 +13236,10 @@ rec { packageId = "gix-traverse"; optional = true; } + { + name = "memmap2"; + packageId = "memmap2"; + } { name = "parking_lot"; packageId = "parking_lot"; -- 2.51.2