aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/db.cc8
-rw-r--r--src/db.hh2
-rw-r--r--src/expr.cc11
-rw-r--r--src/globals.cc29
-rw-r--r--src/globals.hh64
-rw-r--r--src/nix-help.txt1
-rw-r--r--src/nix.cc22
-rw-r--r--src/normalise.cc53
-rw-r--r--src/store.cc105
-rw-r--r--src/store.hh18
10 files changed, 143 insertions, 170 deletions
diff --git a/src/db.cc b/src/db.cc
index f9d618b3b..75f97a1e4 100644
--- a/src/db.cc
+++ b/src/db.cc
@@ -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");
diff --git a/src/db.hh b/src/db.hh
index e3dc7ce7a..1c681b9b5 100644
--- a/src/db.hh
+++ b/src/db.hh
@@ -29,6 +29,8 @@ public:
void abort();
void commit();
+
+ void moveTo(Transaction & t);
};
diff --git a/src/expr.cc b/src/expr.cc
index 521dffc9c..cfc4af1f3 100644
--- a/src/expr.cc
+++ b/src/expr.cc
@@ -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;
}
diff --git a/src/globals.cc b/src/globals.cc
index 22d2758b6..a292b49ae 100644
--- a/src/globals.cc
+++ b/src/globals.cc
@@ -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()
-{
-}
diff --git a/src/globals.hh b/src/globals.hh
index 816cb4766..1b4d0bde3 100644
--- a/src/globals.hh
+++ b/src/globals.hh
@@ -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 */
diff --git a/src/nix-help.txt b/src/nix-help.txt
index ceff114ae..bf2afd061 100644
--- a/src/nix-help.txt
+++ b/src/nix-help.txt
@@ -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
diff --git a/src/nix.cc b/src/nix.cc
index 1012780af..a4d2898f1 100644
--- a/src/nix.cc
+++ b/src/nix.cc
@@ -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(); )
{
diff --git a/src/normalise.cc b/src/normalise.cc
index 0dfc9f8e4..160130d96 100644
--- a/src/normalise.cc
+++ b/src/normalise.cc
@@ -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
diff --git a/src/store.cc b/src/store.cc
index 3e755a0d1..7f10c6377 100644
--- a/src/store.cc
+++ b/src/store.cc
@@ -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));
diff --git a/src/store.hh b/src/store.hh
index 7851b1e3d..3d7575c3e 100644
--- a/src/store.hh
+++ b/src/store.hh
@@ -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);
@@ -24,6 +33,10 @@ void registerSuccessor(const Transaction & txn,
/* 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);
/* Register a substitute. */
@@ -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);