From c4d388add4942f6f99a8df12f4e49149005047e2 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 22 Feb 2010 12:44:36 +0000 Subject: [PATCH] * Get derivation outputs from the database instead of the .drv file, which requires more I/O. --- src/libstore/gc.cc | 8 ++++---- src/libstore/local-store.cc | 24 ++++++++++++++++++++++++ src/libstore/local-store.hh | 3 +++ src/libstore/misc.cc | 8 ++++---- src/libstore/remote-store.cc | 6 ++++++ src/libstore/remote-store.hh | 2 ++ src/libstore/store-api.hh | 3 +++ 7 files changed, 46 insertions(+), 8 deletions(-) diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc index 659c636e3d..cf073c5d9a 100644 --- a/src/libstore/gc.cc +++ b/src/libstore/gc.cc @@ -467,10 +467,10 @@ bool LocalStore::tryToDelete(GCState & state, const Path & path) then don't delete the derivation if any of the outputs are live. */ if (state.gcKeepDerivations && isDerivation(path)) { - Derivation drv = derivationFromPath(path); - foreach (DerivationOutputs::iterator, i, drv.outputs) - if (!tryToDelete(state, i->second.path)) { - printMsg(lvlDebug, format("cannot delete derivation `%1%' because its output is alive") % path); + PathSet outputs = queryDerivationOutputs(path); + foreach (PathSet::iterator, i, outputs) + if (!tryToDelete(state, *i)) { + printMsg(lvlDebug, format("cannot delete derivation `%1%' because its output `%2%' is alive") % path % *i); goto isLive; } } diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index 0590b294ba..0823e785bd 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -299,6 +299,8 @@ void LocalStore::prepareStatements() "insert or replace into DerivationOutputs (drv, id, path) values (?, ?, ?);"); stmtQueryValidDerivers.create(db, "select v.id, v.path from DerivationOutputs d join ValidPaths v on d.drv = v.id where d.path = ?;"); + stmtQueryDerivationOutputs.create(db, + "select id, path from DerivationOutputs where drv = ?;"); } @@ -623,6 +625,28 @@ PathSet LocalStore::queryValidDerivers(const Path & path) } +PathSet LocalStore::queryDerivationOutputs(const Path & path) +{ + SQLiteTxn txn(db); + + SQLiteStmtUse use(stmtQueryDerivationOutputs); + stmtQueryDerivationOutputs.bind(queryPathInfo(path).id); + + PathSet outputs; + int r; + while ((r = sqlite3_step(stmtQueryDerivationOutputs)) == SQLITE_ROW) { + const char * s = (const char *) sqlite3_column_text(stmtQueryDerivationOutputs, 1); + assert(s); + outputs.insert(s); + } + + if (r != SQLITE_DONE) + throw SQLiteError(db, format("error getting outputs of `%1%'") % path); + + return outputs; +} + + void LocalStore::startSubstituter(const Path & substituter, RunningSubstituter & run) { if (run.pid != -1) return; diff --git a/src/libstore/local-store.hh b/src/libstore/local-store.hh index 6bd47b3055..1a4acbe0e4 100644 --- a/src/libstore/local-store.hh +++ b/src/libstore/local-store.hh @@ -109,6 +109,8 @@ public: derivation that was actually used to produce `path', which may not exist anymore.) */ PathSet queryValidDerivers(const Path & path); + + PathSet queryDerivationOutputs(const Path & path); PathSet querySubstitutablePaths(); @@ -206,6 +208,7 @@ private: SQLiteStmt stmtHasPathFailed; SQLiteStmt stmtAddDerivationOutput; SQLiteStmt stmtQueryValidDerivers; + SQLiteStmt stmtQueryDerivationOutputs; int getSchema(); diff --git a/src/libstore/misc.cc b/src/libstore/misc.cc index 2d7d13a0e7..f79cb11cc2 100644 --- a/src/libstore/misc.cc +++ b/src/libstore/misc.cc @@ -31,10 +31,10 @@ void computeFSClosure(const Path & storePath, store->queryReferences(storePath, references); if (includeOutputs && isDerivation(storePath)) { - Derivation drv = derivationFromPath(storePath); - foreach (DerivationOutputs::iterator, i, drv.outputs) - if (store->isValidPath(i->second.path)) - computeFSClosure(i->second.path, paths, flipDirection, true); + PathSet outputs = store->queryDerivationOutputs(storePath); + foreach (PathSet::iterator, i, outputs) + if (store->isValidPath(*i)) + computeFSClosure(*i, paths, flipDirection, true); } foreach (PathSet::iterator, i, references) diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc index 5143143f57..07cb62dc80 100644 --- a/src/libstore/remote-store.cc +++ b/src/libstore/remote-store.cc @@ -294,6 +294,12 @@ Path RemoteStore::queryDeriver(const Path & path) } +PathSet RemoteStore::queryDerivationOutputs(const Path & path) +{ + throw Error("not yet implemented"); +} + + Path RemoteStore::addToStore(const Path & _srcPath, bool recursive, HashType hashAlgo, PathFilter & filter) { diff --git a/src/libstore/remote-store.hh b/src/libstore/remote-store.hh index 3d55d23d95..8bab1d8c48 100644 --- a/src/libstore/remote-store.hh +++ b/src/libstore/remote-store.hh @@ -37,6 +37,8 @@ public: Path queryDeriver(const Path & path); + PathSet queryDerivationOutputs(const Path & path); + bool hasSubstitutes(const Path & path); bool querySubstitutablePathInfo(const Path & path, diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh index d85ae0c9a1..b6a8ff40e5 100644 --- a/src/libstore/store-api.hh +++ b/src/libstore/store-api.hh @@ -139,6 +139,9 @@ public: no deriver has been set. */ virtual Path queryDeriver(const Path & path) = 0; + /* Query the outputs of the derivation denoted by `path'. */ + virtual PathSet queryDerivationOutputs(const Path & path) = 0; + /* Query whether a path has substitutes. */ virtual bool hasSubstitutes(const Path & path) = 0;