From d3d5e77810cca11cca95bbb6f0f5e15d23f31eea Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 10 Oct 2003 14:46:28 +0000 Subject: [PATCH] * Reverse mappings for the successor and substitute mappings. --- src/globals.cc | 4 ++++ src/globals.hh | 14 ++++++++++++ src/normalise.cc | 7 ------ src/normalise.hh | 4 ---- src/store.cc | 56 ++++++++++++++++++++++++++++++++++-------------- src/store.hh | 10 +++++++++ 6 files changed, 68 insertions(+), 27 deletions(-) diff --git a/src/globals.cc b/src/globals.cc index f34f8f1029..22d2758b61 100644 --- a/src/globals.cc +++ b/src/globals.cc @@ -7,7 +7,9 @@ Database nixDB; TableId dbValidPaths; TableId dbSuccessors; +TableId dbSuccessorsRev; TableId dbSubstitutes; +TableId dbSubstitutesRev; string nixStore = "/UNINIT"; @@ -24,7 +26,9 @@ void openDB() nixDB.open(nixDBPath); dbValidPaths = nixDB.openTable("validpaths"); dbSuccessors = nixDB.openTable("successors"); + dbSuccessorsRev = nixDB.openTable("successors-rev"); dbSubstitutes = nixDB.openTable("substitutes"); + dbSubstitutesRev = nixDB.openTable("substitutes-rev"); } diff --git a/src/globals.hh b/src/globals.hh index 0ea2fca092..910e47e01c 100644 --- a/src/globals.hh +++ b/src/globals.hh @@ -33,6 +33,13 @@ extern TableId dbValidPaths; extern TableId dbSuccessors; +/* dbSuccessorsRev :: Path -> [Path] + + The reverse mapping of dbSuccessors. +*/ +extern TableId dbSuccessorsRev; + + /* dbSubstitutes :: Path -> [Path] Each pair $(p, [ps])$ tells Nix that it can realise any of the @@ -47,6 +54,13 @@ extern TableId dbSuccessors; extern TableId dbSubstitutes; +/* dbSubstitutesRev :: Path -> [Path] + + The reverse mapping of dbSubstitutes. +*/ +extern TableId dbSubstitutesRev; + + /* Path names. */ /* nixStore is the directory where we generally store atomic and diff --git a/src/normalise.cc b/src/normalise.cc index 834276f1be..0dfc9f8e4d 100644 --- a/src/normalise.cc +++ b/src/normalise.cc @@ -8,13 +8,6 @@ #include "globals.hh" -void registerSuccessor(const Transaction & txn, - const Path & path1, const Path & path2) -{ - nixDB.setString(txn, dbSuccessors, path1, path2); -} - - static Path useSuccessor(const Path & path) { string pathSucc; diff --git a/src/normalise.hh b/src/normalise.hh index 4b4db4ee2a..e8e72f5bc8 100644 --- a/src/normalise.hh +++ b/src/normalise.hh @@ -34,9 +34,5 @@ PathSet nixExprRequisites(const Path & nePath, output paths are completely contained in the set `outputs'. */ PathSet findGenerators(const PathSet & outputs); -/* Register a successor. */ -void registerSuccessor(const Transaction & txn, - const Path & path1, const Path & path2); - #endif /* !__NORMALISE_H */ diff --git a/src/store.cc b/src/store.cc index b2b479e0dd..de1dcca708 100644 --- a/src/store.cc +++ b/src/store.cc @@ -81,26 +81,50 @@ void copyPath(const Path & src, const Path & dst) } +void registerSuccessor(const Transaction & txn, + const Path & path1, const Path & path2) +{ + Path known; + if (nixDB.queryString(txn, dbSuccessors, path1, known) && + known != path2) + { + throw Error(format( + "the `impossible' happened: expression in path " + "`%1%' appears to have multiple successors " + "(known `%2%', new `%3%'") + % path1 % known % path2); + } + + Paths revs; + nixDB.queryStrings(txn, dbSuccessorsRev, path2, revs); + revs.push_back(path1); + + nixDB.setString(txn, dbSuccessors, path1, path2); + nixDB.setStrings(txn, dbSuccessorsRev, path2, revs); +} + + void registerSubstitute(const Path & srcPath, const Path & subPath) { -#if 0 - Strings subs; - queryListDB(nixDB, dbSubstitutes, srcId, subs); /* non-existence = ok */ - - for (Strings::iterator it = subs.begin(); it != subs.end(); it++) - if (parseHash(*it) == subId) return; - - subs.push_back(subId); - - setListDB(nixDB, dbSubstitutes, srcId, subs); -#endif - - /* For now, accept only one substitute per id. */ - Strings subs; - subs.push_back(subPath); - Transaction txn(nixDB); + + Paths subs; + nixDB.queryStrings(txn, dbSubstitutes, srcPath, subs); + + if (find(subs.begin(), subs.end(), subPath) != subs.end()) { + /* Nothing to do if the substitute is already known. */ + txn.abort(); + return; + } + subs.push_front(subPath); /* new substitutes take precedence */ + + Paths revs; + nixDB.queryStrings(txn, dbSubstitutesRev, subPath, revs); + revs.push_back(srcPath); + nixDB.setStrings(txn, dbSubstitutes, srcPath, subs); + nixDB.setStrings(txn, dbSubstitutesRev, subPath, revs); + txn.commit(); } diff --git a/src/store.hh b/src/store.hh index 69de824786..7b32a1a731 100644 --- a/src/store.hh +++ b/src/store.hh @@ -12,6 +12,16 @@ using namespace std; /* Copy a path recursively. */ void copyPath(const Path & src, const Path & dst); +/* Register a successor. This function accepts a transaction handle + so that it can be enclosed in an atomic operation with calls to + registerValidPath(). This must be atomic, since if we register a + successor for a derivation without registering the paths built in + the derivation, we have a successor with dangling pointers, and if + we do it in reverse order, we can get an obstructed build (since to + rebuild the successor, the outputs paths must not exist). */ +void registerSuccessor(const Transaction & txn, + const Path & path1, const Path & path2); + /* Register a substitute. */ void registerSubstitute(const Path & srcPath, const Path & subPath);