Buffer reads from the substituter

This greatly reduces the number of system calls.
This commit is contained in:
Eelco Dolstra 2013-06-07 14:00:23 +02:00
parent 75e12b8e66
commit c5f9d0d080
2 changed files with 27 additions and 10 deletions

View file

@ -1039,14 +1039,26 @@ void LocalStore::startSubstituter(const Path & substituter, RunningSubstituter &
/* Parent. */ /* Parent. */
run.to = toPipe.writeSide.borrow(); run.to = toPipe.writeSide.borrow();
run.from = fromPipe.readSide.borrow(); run.from = run.fromBuf.fd = fromPipe.readSide.borrow();
run.error = errorPipe.readSide.borrow(); run.error = errorPipe.readSide.borrow();
} }
template<class T> 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<class T> T LocalStore::getIntLineFromSubstituter(RunningSubstituter & run)
{
string s = getLineFromSubstituter(run);
T res; T res;
if (!string2Int(s, res)) throw Error("integer expected from stream"); if (!string2Int(s, res)) throw Error("integer expected from stream");
return res; return res;
@ -1070,7 +1082,7 @@ PathSet LocalStore::querySubstitutablePaths(const PathSet & paths)
stderr when they fail. I.e. they shouldn't write debug stderr when they fail. I.e. they shouldn't write debug
output. */ output. */
try { try {
Path path = readLine(run.from); Path path = getLineFromSubstituter(run);
if (path == "") break; if (path == "") break;
res.insert(path); res.insert(path);
} catch (EndOfFile e) { } catch (EndOfFile e) {
@ -1095,22 +1107,22 @@ void LocalStore::querySubstitutablePathInfos(const Path & substituter,
while (true) { while (true) {
try { try {
Path path = readLine(run.from); Path path = getLineFromSubstituter(run);
if (path == "") break; if (path == "") break;
if (paths.find(path) == paths.end()) if (paths.find(path) == paths.end())
throw Error(format("got unexpected path `%1%' from substituter") % path); throw Error(format("got unexpected path `%1%' from substituter") % path);
paths.erase(path); paths.erase(path);
SubstitutablePathInfo & info(infos[path]); SubstitutablePathInfo & info(infos[path]);
info.deriver = readLine(run.from); info.deriver = getLineFromSubstituter(run);
if (info.deriver != "") assertStorePath(info.deriver); if (info.deriver != "") assertStorePath(info.deriver);
int nrRefs = getIntLine<int>(run.from); int nrRefs = getIntLineFromSubstituter<int>(run);
while (nrRefs--) { while (nrRefs--) {
Path p = readLine(run.from); Path p = getLineFromSubstituter(run);
assertStorePath(p); assertStorePath(p);
info.references.insert(p); info.references.insert(p);
} }
info.downloadSize = getIntLine<long long>(run.from); info.downloadSize = getIntLineFromSubstituter<long long>(run);
info.narSize = getIntLine<long long>(run.from); info.narSize = getIntLineFromSubstituter<long long>(run);
} catch (EndOfFile e) { } catch (EndOfFile e) {
throw Error(format("substituter `%1%' failed: %2%") % substituter % chomp(drainFD(run.error))); throw Error(format("substituter `%1%' failed: %2%") % substituter % chomp(drainFD(run.error)));
} }

View file

@ -46,6 +46,7 @@ struct RunningSubstituter
{ {
Pid pid; Pid pid;
AutoCloseFD to, from, error; AutoCloseFD to, from, error;
FdSource fromBuf;
}; };
@ -289,6 +290,10 @@ private:
void startSubstituter(const Path & substituter, void startSubstituter(const Path & substituter,
RunningSubstituter & runningSubstituter); RunningSubstituter & runningSubstituter);
string getLineFromSubstituter(RunningSubstituter & run);
template<class T> T getIntLineFromSubstituter(RunningSubstituter & run);
Path createTempDirInStore(); Path createTempDirInStore();
Path importPath(bool requireSignature, Source & source); Path importPath(bool requireSignature, Source & source);