From c5f9d0d08058bca4af0d22e8d46a7d84627c0aae Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 7 Jun 2013 14:00:23 +0200 Subject: [PATCH] Buffer reads from the substituter This greatly reduces the number of system calls. --- src/libstore/local-store.cc | 32 ++++++++++++++++++++++---------- src/libstore/local-store.hh | 5 +++++ 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index dce57f751..cfb853205 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -1039,14 +1039,26 @@ void LocalStore::startSubstituter(const Path & substituter, RunningSubstituter & /* Parent. */ run.to = toPipe.writeSide.borrow(); - run.from = fromPipe.readSide.borrow(); + run.from = run.fromBuf.fd = fromPipe.readSide.borrow(); run.error = errorPipe.readSide.borrow(); } -template T getIntLine(int fd) +string LocalStore::getLineFromSubstituter(RunningSubstituter & run) { - string s = readLine(fd); + string s; + while (1) { + unsigned char c; + run.fromBuf(&c, 1); + if (c == '\n') return s; + s += c; + } +} + + +template T LocalStore::getIntLineFromSubstituter(RunningSubstituter & run) +{ + string s = getLineFromSubstituter(run); T res; if (!string2Int(s, res)) throw Error("integer expected from stream"); return res; @@ -1070,7 +1082,7 @@ PathSet LocalStore::querySubstitutablePaths(const PathSet & paths) stderr when they fail. I.e. they shouldn't write debug output. */ try { - Path path = readLine(run.from); + Path path = getLineFromSubstituter(run); if (path == "") break; res.insert(path); } catch (EndOfFile e) { @@ -1095,22 +1107,22 @@ void LocalStore::querySubstitutablePathInfos(const Path & substituter, while (true) { try { - Path path = readLine(run.from); + Path path = getLineFromSubstituter(run); if (path == "") break; if (paths.find(path) == paths.end()) throw Error(format("got unexpected path `%1%' from substituter") % path); paths.erase(path); SubstitutablePathInfo & info(infos[path]); - info.deriver = readLine(run.from); + info.deriver = getLineFromSubstituter(run); if (info.deriver != "") assertStorePath(info.deriver); - int nrRefs = getIntLine(run.from); + int nrRefs = getIntLineFromSubstituter(run); while (nrRefs--) { - Path p = readLine(run.from); + Path p = getLineFromSubstituter(run); assertStorePath(p); info.references.insert(p); } - info.downloadSize = getIntLine(run.from); - info.narSize = getIntLine(run.from); + info.downloadSize = getIntLineFromSubstituter(run); + info.narSize = getIntLineFromSubstituter(run); } catch (EndOfFile e) { throw Error(format("substituter `%1%' failed: %2%") % substituter % chomp(drainFD(run.error))); } diff --git a/src/libstore/local-store.hh b/src/libstore/local-store.hh index 14a826b3a..424515667 100644 --- a/src/libstore/local-store.hh +++ b/src/libstore/local-store.hh @@ -46,6 +46,7 @@ struct RunningSubstituter { Pid pid; AutoCloseFD to, from, error; + FdSource fromBuf; }; @@ -289,6 +290,10 @@ private: void startSubstituter(const Path & substituter, RunningSubstituter & runningSubstituter); + string getLineFromSubstituter(RunningSubstituter & run); + + template T getIntLineFromSubstituter(RunningSubstituter & run); + Path createTempDirInStore(); Path importPath(bool requireSignature, Source & source);