From b1783ff6151d24344cb22cb39e5f2975424fb22f Mon Sep 17 00:00:00 2001 From: silvanshade Date: Tue, 18 Mar 2025 14:22:15 -0600 Subject: [PATCH] Implement memory-mapped IO for Sinks --- packaging/dependencies.nix | 1 + src/libutil/file-system.cc | 19 +++++++++++++++++-- src/libutil/include/nix/util/file-system.hh | 2 +- src/libutil/meson.build | 2 +- 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/packaging/dependencies.nix b/packaging/dependencies.nix index 16d1f1376..a90ef1b4a 100644 --- a/packaging/dependencies.nix +++ b/packaging/dependencies.nix @@ -61,6 +61,7 @@ scope: { "--with-container" "--with-context" "--with-coroutine" + "--with-iostreams" ]; }).overrideAttrs (old: { diff --git a/src/libutil/file-system.cc b/src/libutil/file-system.cc index ad17f837f..90ec5eda5 100644 --- a/src/libutil/file-system.cc +++ b/src/libutil/file-system.cc @@ -21,6 +21,8 @@ #include #include +#include + #ifdef _WIN32 # include #endif @@ -273,9 +275,22 @@ std::string readFile(const std::filesystem::path & path) return readFile(os_string_to_string(PathViewNG { path })); } - -void readFile(const Path & path, Sink & sink) +void readFile(const Path & path, Sink & sink, bool memory_map) { + // Memory-map the file for faster processing where possible. + if (memory_map) { + try { + boost::iostreams::mapped_file_source mmap(path); + if (mmap.is_open()) { + sink({mmap.data(), mmap.size()}); + return; + } + } catch (const boost::exception & e) { + } + debug("memory-mapping failed for path: %s", path); + } + + // Stream the file instead if memory-mapping fails or is disabled. AutoCloseFD fd = toDescriptor(open(path.c_str(), O_RDONLY // TODO #ifndef _WIN32 diff --git a/src/libutil/include/nix/util/file-system.hh b/src/libutil/include/nix/util/file-system.hh index 1d7b5e3aa..b8fa4cfa0 100644 --- a/src/libutil/include/nix/util/file-system.hh +++ b/src/libutil/include/nix/util/file-system.hh @@ -173,7 +173,7 @@ Descriptor openDirectory(const std::filesystem::path & path); */ std::string readFile(const Path & path); std::string readFile(const std::filesystem::path & path); -void readFile(const Path & path, Sink & sink); +void readFile(const Path & path, Sink & sink, bool memory_map = true); /** * Write a string to a file. diff --git a/src/libutil/meson.build b/src/libutil/meson.build index 782c361e0..944198970 100644 --- a/src/libutil/meson.build +++ b/src/libutil/meson.build @@ -56,7 +56,7 @@ deps_private += blake3 boost = dependency( 'boost', - modules : ['context', 'coroutine'], + modules : ['context', 'coroutine', 'iostreams'], include_type: 'system', ) # boost is a public dependency, but not a pkg-config dependency unfortunately, so we