* Refactoring: move all database manipulation into store.cc.

* Removed `--query --generators'.
This commit is contained in:
Eelco Dolstra 2003-10-15 12:42:39 +00:00
parent 5fc7127643
commit ebff82222c
10 changed files with 143 additions and 170 deletions

View File

@ -70,6 +70,14 @@ void Transaction::abort()
}
void Transaction::moveTo(Transaction & t)
{
if (t.txn) throw Error("target txn already exists");
t.txn = txn;
txn = 0;
}
void Database::requireEnv()
{
if (!env) throw Error("database environment not open");

View File

@ -29,6 +29,8 @@ public:
void abort();
void commit();
void moveTo(Transaction & t);
};

View File

@ -39,14 +39,11 @@ Path writeTerm(ATerm t, const string & suffix)
(string) h + suffix + ".nix");
if (!isValidPath(path)) {
if (!ATwriteToNamedTextFile(t, path.c_str()))
throw Error(format("cannot write aterm %1%") % path);
Transaction txn(nixDB);
registerValidPath(txn, path);
txn.commit();
char * s = ATwriteToString(t);
if (!s) throw Error(format("cannot write aterm to `%1%'") % path);
addTextToStore(path, string(s));
}
return path;
}

View File

@ -1,37 +1,8 @@
#include "globals.hh"
#include "db.hh"
Database nixDB;
TableId dbValidPaths;
TableId dbSuccessors;
TableId dbSuccessorsRev;
TableId dbSubstitutes;
TableId dbSubstitutesRev;
string nixStore = "/UNINIT";
string nixDataDir = "/UNINIT";
string nixLogDir = "/UNINIT";
string nixDBPath = "/UNINIT";
bool keepFailed = false;
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");
}
void initDB()
{
}

View File

@ -3,65 +3,8 @@
#include <string>
#include "db.hh"
using namespace std;
extern Database nixDB;
/* Database tables. */
/* dbValidPaths :: Path -> ()
The existence of a key $p$ indicates that path $p$ is valid (that
is, produced by a succesful build). */
extern TableId dbValidPaths;
/* dbSuccessors :: Path -> Path
Each pair $(p_1, p_2)$ in this mapping records the fact that the
Nix expression stored at path $p_1$ has a successor expression
stored at path $p_2$.
Note that a term $y$ is a successor of $x$ iff there exists a
sequence of rewrite steps that rewrites $x$ into $y$.
*/
extern TableId dbSuccessors;
/* dbSuccessorsRev :: Path -> [Path]
The reverse mapping of dbSuccessors (i.e., it stores the
predecessors of a Nix expression).
*/
extern TableId dbSuccessorsRev;
/* dbSubstitutes :: Path -> [Path]
Each pair $(p, [ps])$ tells Nix that it can realise any of the
Nix expressions stored at paths $ps$ to produce a path $p$.
The main purpose of this is for distributed caching of derivates.
One system can compute a derivate and put it on a website (as a Nix
archive), for instance, and then another system can register a
substitute for that derivate. The substitute in this case might be
a Nix expression that fetches the Nix archive.
*/
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
@ -83,11 +26,4 @@ extern string nixDBPath;
extern bool keepFailed;
/* Open the database environment. */
void openDB();
/* Create the required database tables. */
void initDB();
#endif /* !__GLOBALS_H */

View File

@ -23,7 +23,6 @@ Query flags:
--list / -l: query the output paths (roots) of a Nix expression (default)
--requisites / -r: print all paths necessary to realise expression
--generators / -g: find expressions producing a subset of given ids
--predecessors: print predecessors of a Nix expression
--graph: print a dot graph rooted at given ids

View File

@ -73,7 +73,7 @@ Path maybeNormalise(const Path & ne, bool normalise)
/* Perform various sorts of queries. */
static void opQuery(Strings opFlags, Strings opArgs)
{
enum { qList, qRequisites, qGenerators, qPredecessors, qGraph
enum { qList, qRequisites, qPredecessors, qGraph
} query = qList;
bool normalise = false;
bool includeExprs = true;
@ -83,7 +83,6 @@ static void opQuery(Strings opFlags, Strings opArgs)
i != opFlags.end(); i++)
if (*i == "--list" || *i == "-l") query = qList;
else if (*i == "--requisites" || *i == "-r") query = qRequisites;
else if (*i == "--generators" || *i == "-g") query = qGenerators;
else if (*i == "--predecessors") query = qPredecessors;
else if (*i == "--graph") query = qGraph;
else if (*i == "--normalise" || *i == "-n") normalise = true;
@ -124,22 +123,6 @@ static void opQuery(Strings opFlags, Strings opArgs)
break;
}
#if 0
case qGenerators: {
FSIds outIds;
for (Strings::iterator i = opArgs.begin();
i != opArgs.end(); i++)
outIds.push_back(checkPath(*i));
FSIds genIds = findGenerators(outIds);
for (FSIds::iterator i = genIds.begin();
i != genIds.end(); i++)
cout << format("%s\n") % expandId(*i);
break;
}
#endif
case qPredecessors: {
for (Strings::iterator i = opArgs.begin();
i != opArgs.end(); i++)
@ -172,7 +155,8 @@ static void opSuccessor(Strings opFlags, Strings opArgs)
if (!opFlags.empty()) throw UsageError("unknown flag");
if (opArgs.size() % 2) throw UsageError("expecting even number of arguments");
Transaction txn(nixDB); /* !!! this could be a big transaction */
Transaction txn;
createStoreTransaction(txn);
for (Strings::iterator i = opArgs.begin();
i != opArgs.end(); )
{

View File

@ -2,7 +2,6 @@
#include "normalise.hh"
#include "references.hh"
#include "db.hh"
#include "exec.hh"
#include "pathlocks.hh"
#include "globals.hh"
@ -11,7 +10,7 @@
static Path useSuccessor(const Path & path)
{
string pathSucc;
if (nixDB.queryString(noTxn, dbSuccessors, path, pathSucc)) {
if (querySuccessor(path, pathSucc)) {
debug(format("successor %1% -> %2%") % (string) path % pathSucc);
return pathSucc;
} else
@ -349,7 +348,8 @@ Path normaliseNixExpr(const Path & _nePath, PathSet pending)
for recoverability: unregistered paths in the store can be
deleted arbitrarily, while registered paths can only be deleted
by running the garbage collector. */
Transaction txn(nixDB);
Transaction txn;
createStoreTransaction(txn);
for (PathSet::iterator i = ne.derivation.outputs.begin();
i != ne.derivation.outputs.end(); i++)
registerValidPath(txn, *i);
@ -434,50 +434,3 @@ PathSet nixExprRequisites(const Path & nePath,
paths, doneSet);
return paths;
}
#if 0
PathSet findGenerators(const PathSet & outputs)
{
FSIdSet ids(_ids.begin(), _ids.end());
FSIds generators;
/* !!! hack; for performance, we just look at the rhs of successor
mappings, since we know that those are Nix expressions. */
Strings sucs;
nixDB.enumTable(noTxn, dbSuccessors, sucs);
for (Strings::iterator i = sucs.begin();
i != sucs.end(); i++)
{
string s;
if (!nixDB.queryString(noTxn, dbSuccessors, *i, s)) continue;
FSId id = parseHash(s);
NixExpr ne;
try {
/* !!! should substitutes be used? */
ne = parseNixExpr(termFromId(id));
} catch (...) { /* !!! only catch parse errors */
continue;
}
if (ne.type != NixExpr::neClosure) continue;
bool okay = true;
for (ClosureElems::const_iterator i = ne.closure.elems.begin();
i != ne.closure.elems.end(); i++)
if (ids.find(i->second.id) == ids.end()) {
okay = false;
break;
}
if (!okay) continue;
generators.push_back(id);
}
return generators;
}
#endif

View File

@ -1,7 +1,10 @@
#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <unistd.h>
#include "store.hh"
#include "globals.hh"
@ -10,6 +13,81 @@
#include "pathlocks.hh"
/* Nix database. */
static Database nixDB;
/* Database tables. */
/* dbValidPaths :: Path -> ()
The existence of a key $p$ indicates that path $p$ is valid (that
is, produced by a succesful build). */
static TableId dbValidPaths;
/* dbSuccessors :: Path -> Path
Each pair $(p_1, p_2)$ in this mapping records the fact that the
Nix expression stored at path $p_1$ has a successor expression
stored at path $p_2$.
Note that a term $y$ is a successor of $x$ iff there exists a
sequence of rewrite steps that rewrites $x$ into $y$.
*/
static TableId dbSuccessors;
/* dbSuccessorsRev :: Path -> [Path]
The reverse mapping of dbSuccessors (i.e., it stores the
predecessors of a Nix expression).
*/
static TableId dbSuccessorsRev;
/* dbSubstitutes :: Path -> [Path]
Each pair $(p, [ps])$ tells Nix that it can realise any of the
Nix expressions stored at paths $ps$ to produce a path $p$.
The main purpose of this is for distributed caching of derivates.
One system can compute a derivate and put it on a website (as a Nix
archive), for instance, and then another system can register a
substitute for that derivate. The substitute in this case might be
a Nix expression that fetches the Nix archive.
*/
static TableId dbSubstitutes;
/* dbSubstitutesRev :: Path -> [Path]
The reverse mapping of dbSubstitutes.
*/
static TableId dbSubstitutesRev;
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");
}
void initDB()
{
}
void createStoreTransaction(Transaction & txn)
{
Transaction txn2(nixDB);
txn2.moveTo(txn);
}
/* Path copying. */
struct CopySink : DumpSink
{
int fd;
@ -104,6 +182,12 @@ void registerSuccessor(const Transaction & txn,
}
bool querySuccessor(const Path & srcPath, Path & sucPath)
{
return nixDB.queryString(noTxn, dbSuccessors, srcPath, sucPath);
}
Paths queryPredecessors(const Path & sucPath)
{
Paths revs;
@ -204,6 +288,27 @@ Path addToStore(const Path & _srcPath)
}
void addTextToStore(const Path & dstPath, const string & s)
{
if (!isValidPath(dstPath)) {
/* !!! locking? -> parallel writes are probably idempotent */
int fd = open(dstPath.c_str(), O_CREAT | O_EXCL | O_WRONLY, 0666);
if (fd == -1) throw SysError(format("creating store file `%1%'") % dstPath);
if (write(fd, s.c_str(), s.size()) != (ssize_t) s.size())
throw SysError(format("writing store file `%1%'") % dstPath);
close(fd); /* !!! close on exception */
Transaction txn(nixDB);
registerValidPath(txn, dstPath);
txn.commit();
}
}
void deleteFromStore(const Path & _path)
{
Path path(canonPath(_path));

View File

@ -9,6 +9,15 @@
using namespace std;
/* Open the database environment. */
void openDB();
/* Create the required database tables. */
void initDB();
/* Get a transaction object. */
void createStoreTransaction(Transaction & txn);
/* Copy a path recursively. */
void copyPath(const Path & src, const Path & dst);
@ -22,6 +31,10 @@ void copyPath(const Path & src, const Path & dst);
void registerSuccessor(const Transaction & txn,
const Path & srcPath, const Path & sucPath);
/* Return the predecessors of the Nix expression stored at the given
path. */
bool querySuccessor(const Path & srcPath, Path & sucPath);
/* Return the predecessors of the Nix expression stored at the given
path. */
Paths queryPredecessors(const Path & sucPath);
@ -42,6 +55,11 @@ bool isValidPath(const Path & path);
the resulting path. The resulting path is returned. */
Path addToStore(const Path & srcPath);
/* Like addToStore, but the path of the output is given, and the
contents written to the output path is a regular file containing
the given string. */
void addTextToStore(const Path & dstPath, const string & s);
/* Delete a value from the nixStore directory. */
void deleteFromStore(const Path & path);