From 94e3e4c69d353ca84047710ff1bdbf7edd603d47 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 30 May 2005 13:14:26 +0000 Subject: [PATCH] * Before consolidating/building, consider all trusted paths in the equivalence classes of the input derivations. * Set the equivalence class for paths produced through rewriting. --- src/libstore/build.cc | 18 ++++++++++-------- src/libstore/misc.cc | 31 +++++++++++++++++++++++++++---- src/libstore/misc.hh | 11 ++++++++--- 3 files changed, 45 insertions(+), 15 deletions(-) diff --git a/src/libstore/build.cc b/src/libstore/build.cc index bbd212c0a..e2cfb38eb 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -969,13 +969,16 @@ bool DerivationGoal::prepareBuild() j != i->second.end(); ++j) { OutputEqClass eqClass = findOutputEqClass(inDrv, *j); - Path input = findTrustedEqClassMember(eqClass, currentTrustId); - if (input == "") + PathSet inputs = findTrustedEqClassMembers(eqClass, currentTrustId); + if (inputs.size() == 0) + /* !!! shouldn't happen, except for garbage + collection? */ throw Error(format("output `%1%' of derivation `%2%' is missing!") % *j % i->first); - rewrites[hashPartOf(eqClass)] = hashPartOf(input); - - computeFSClosure(input, inputPaths); + for (PathSet::iterator k = inputs.begin(); k != inputs.end(); ++k) { + rewrites[hashPartOf(eqClass)] = hashPartOf(*k); + computeFSClosure(*k, inputPaths); + } } } @@ -1333,9 +1336,8 @@ DerivationGoal::OutputEqClasses DerivationGoal::checkOutputValidity(bool returnV for (DerivationOutputs::iterator i = drv.outputs.begin(); i != drv.outputs.end(); ++i) { - Path path = findTrustedEqClassMember(i->second.eqClass, currentTrustId); - if (path != "") { - assert(isValidPath(path)); + PathSet paths = findTrustedEqClassMembers(i->second.eqClass, currentTrustId); + if (paths.size() > 0) { if (returnValid) result.insert(i->second.eqClass); } else { if (!returnValid) result.insert(i->second.eqClass); diff --git a/src/libstore/misc.cc b/src/libstore/misc.cc index b8cd6a8fb..415c19dfd 100644 --- a/src/libstore/misc.cc +++ b/src/libstore/misc.cc @@ -1,5 +1,6 @@ #include "build.hh" #include "misc.hh" +#include "globals.hh" Derivation derivationFromPath(const Path & drvPath) @@ -39,16 +40,27 @@ OutputEqClass findOutputEqClass(const Derivation & drv, const string & id) } -Path findTrustedEqClassMember(const OutputEqClass & eqClass, +PathSet findTrustedEqClassMembers(const OutputEqClass & eqClass, const TrustId & trustId) { OutputEqMembers members; queryOutputEqMembers(noTxn, eqClass, members); + PathSet result; for (OutputEqMembers::iterator j = members.begin(); j != members.end(); ++j) - if (j->trustId == trustId || j->trustId == "root") return j->path; + if (j->trustId == trustId || j->trustId == "root") result.insert(j->path); - return ""; + return result; +} + + +Path findTrustedEqClassMember(const OutputEqClass & eqClass, + const TrustId & trustId) +{ + PathSet paths = findTrustedEqClassMembers(eqClass, trustId); + if (paths.size() == 0) + throw Error(format("no output path in equivalence class `%1%' is known") % eqClass); + return *(paths.begin()); } @@ -152,6 +164,17 @@ static Path maybeRewrite(const Path & path, const PathSet & selection, hashPartOf(path), namePartOf(path), references, rewrites); + /* !!! we don't know which eqClass `path' is in! That is to say, + we don't know which one is intended here. */ + OutputEqClasses classes; + queryOutputEqClasses(noTxn, path, classes); + for (PathSet::iterator i = classes.begin(); i != classes.end(); ++i) { + Transaction txn; + createStoreTransaction(txn); + addOutputEqMember(txn, *i, currentTrustId, newPath); + txn.commit(); + } + nrRewrites++; printMsg(lvlError, format("rewrote `%1%' to `%2%'") % path % newPath); @@ -181,7 +204,7 @@ PathSet consolidatePaths(const PathSet & paths, bool checkOnly, classMap[*j].insert(*i); } - printMsg(lvlError, format("found %1% sources") % sources.size()); + printMsg(lvlError, format("found %1% sources %2%") % sources.size() % showPaths(sources)); bool conflict = false; for (ClassMap::iterator i = classMap.begin(); i != classMap.end(); ++i) diff --git a/src/libstore/misc.hh b/src/libstore/misc.hh index 449b087af..d765fa842 100644 --- a/src/libstore/misc.hh +++ b/src/libstore/misc.hh @@ -26,9 +26,14 @@ OutputEqClass findOutputEqClass(const Derivation & drv, const string & id); -/* Return any trusted path (wrt to the given trust ID) in the given - output path equivalence class, or "" if no such path currently - exists. */ +/* Return anll trusted path (wrt to the given trust ID) in the given + output path equivalence class, or an empty set if no such paths + currently exist. */ +PathSet findTrustedEqClassMembers(const OutputEqClass & eqClass, + const TrustId & trustId); + +/* Like `findTrustedEqClassMembers', but returns an arbitrary trusted + path, or throws an exception if no such path currently exists. */ Path findTrustedEqClassMember(const OutputEqClass & eqClass, const TrustId & trustId);