From 7d21863bb3f3d4c42b273a8648a65bec83fe0b60 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 28 Mar 2018 13:32:44 +0200 Subject: Make run in constant memory E.g. nix-build --store ~/my-nix/ -E 'import { url = https://cache.nixos.org/nar/0nwi996rgq4b914qyx0mv2wq4k80hjac7xilikavagw7kxmn2iiv.nar.xz; sha256 = "0nwi996rgq4b914qyx0mv2wq4k80hjac7xilikavagw7kxmn2iiv"; }' now runs in 17 MiB (was 70 MiB), while nix-build --store ~/my-nix/ -E 'import { url = https://cache.nixos.org/nar/0nwi996rgq4b914qyx0mv2wq4k80hjac7xilikavagw7kxmn2iiv.nar.xz; sha256 = "0d2fxljdih3nc5dqx41hjzic3141ajil94m8kdbpryq569dpsbvb"; unpack = true; }' runs in 17 MiB (was 346 MiB). --- src/libutil/util.cc | 17 +++++++++++++++++ src/libutil/util.hh | 2 ++ 2 files changed, 19 insertions(+) (limited to 'src/libutil') diff --git a/src/libutil/util.cc b/src/libutil/util.cc index 22753f4b7e..6bc64ae75a 100644 --- a/src/libutil/util.cc +++ b/src/libutil/util.cc @@ -328,6 +328,23 @@ void writeFile(const Path & path, const string & s, mode_t mode) } +void writeFile(const Path & path, Source & source, mode_t mode) +{ + AutoCloseFD fd = open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, mode); + if (!fd) + throw SysError(format("opening file '%1%'") % path); + + std::vector buf(64 * 1024); + + while (true) { + try { + auto n = source.read(buf.data(), buf.size()); + writeFull(fd.get(), (unsigned char *) buf.data(), n); + } catch (EndOfFile &) { break; } + } +} + + string readLine(int fd) { string s; diff --git a/src/libutil/util.hh b/src/libutil/util.hh index af97b76d90..fc25d27758 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -103,6 +103,8 @@ void readFile(const Path & path, Sink & sink); /* Write a string to a file. */ void writeFile(const Path & path, const string & s, mode_t mode = 0666); +void writeFile(const Path & path, Source & source, mode_t mode = 0666); + /* Read a line from a file descriptor. */ string readLine(int fd); -- cgit 1.4.1