about summary refs log tree commit diff
path: root/src/libstore/store.cc
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2005-01-19T11·16+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2005-01-19T11·16+0000
commit863dcff6c5ffc163010ec1f9e6819bb9aaaadc29 (patch)
tree4747222c7f8c471e6cbfa07c49023853d2f6b957 /src/libstore/store.cc
parente9762e2d10c4a837e3d75d53e3a24452f07f47ec (diff)
* Started removing closure store expressions, i.e., the explicit
  representation of closures as ATerms in the Nix store.  Instead, the
  file system pointer graph is now stored in the Nix database.  This
  has many advantages:

  - It greatly simplifies the implementation (we can drop the notion
    of `successors', and so on).

  - It makes registering roots for the garbage collector much easier.
    Instead of specifying the closure expression as a root, you can
    simply specify the store path that must be retained as a root.
    This could not be done previously, since there was no way to find
    the closure store expression containing a given store path.
    
  - Better traceability: it is now possible to query what paths are
    referenced by a path, and what paths refer to a path.

Diffstat (limited to 'src/libstore/store.cc')
-rw-r--r--src/libstore/store.cc163
1 files changed, 28 insertions, 135 deletions
diff --git a/src/libstore/store.cc b/src/libstore/store.cc
index 0d89f7a5d7..51e2e7e7d2 100644
--- a/src/libstore/store.cc
+++ b/src/libstore/store.cc
@@ -23,23 +23,18 @@ static Database nixDB;
    is, produced by a succesful build). */
 static TableId dbValidPaths = 0;
 
-/* dbSuccessors :: Path -> Path
+/* dbReferences :: 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$.
+   This table lists the outgoing file system references for each
+   output path that has been built by a Nix derivation.  These are
+   found by scanning the path for the hash components of input
+   paths. */
+static TableId dbReferences = 0;
 
-   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 = 0;
-
-/* dbSuccessorsRev :: Path -> [Path]
+/* dbReferers :: Path -> [Path]
 
-   The reverse mapping of dbSuccessors (i.e., it stores the
-   predecessors of a Nix expression).
-*/
-static TableId dbSuccessorsRev = 0;
+   This table is just the reverse mapping of dbReferences. */
+static TableId dbReferers = 0;
 
 /* dbSubstitutes :: Path -> [[Path]]
 
@@ -76,8 +71,8 @@ void openDB()
         return;
     }
     dbValidPaths = nixDB.openTable("validpaths");
-    dbSuccessors = nixDB.openTable("successors");
-    dbSuccessorsRev = nixDB.openTable("successors-rev");
+    dbReferences = nixDB.openTable("references");
+    dbReferers = nixDB.openTable("referers");
     dbSubstitutes = nixDB.openTable("substitutes");
 }
 
@@ -199,81 +194,31 @@ bool isValidPath(const Path & path)
 }
 
 
-static bool isUsablePathTxn(const Path & path, const Transaction & txn)
-{
-    if (isValidPathTxn(path, txn)) return true;
-    Paths subs;
-    nixDB.queryStrings(txn, dbSubstitutes, path, subs);
-    return subs.size() > 0;
-}
-
-
-void registerSuccessor(const Transaction & txn,
-    const Path & srcPath, const Path & sucPath)
+void setReferences(const Transaction & txn, const Path & storePath,
+    const PathSet & references)
 {
-    assertStorePath(srcPath);
-    assertStorePath(sucPath);
-    
-    if (!isUsablePathTxn(sucPath, txn))	throw Error(
-	format("path `%1%' cannot be a successor, since it is not usable")
-	% sucPath);
+    nixDB.setStrings(txn, dbReferences, storePath,
+        Paths(references.begin(), references.end()));
 
-    Path known;
-    if (nixDB.queryString(txn, dbSuccessors, srcPath, known) &&
-        known != sucPath)
+    /* Update the referers mappings of all referenced paths. */
+    for (PathSet::const_iterator i = references.begin();
+         i != references.end(); ++i)
     {
-        throw Error(format(
-            "the `impossible' happened: expression in path "
-            "`%1%' appears to have multiple successors "
-            "(known `%2%', new `%3%'")
-            % srcPath % known % sucPath);
-    }
-
-    Paths revs;
-    nixDB.queryStrings(txn, dbSuccessorsRev, sucPath, revs);
-    if (find(revs.begin(), revs.end(), srcPath) == revs.end())
-        revs.push_back(srcPath);
-
-    nixDB.setString(txn, dbSuccessors, srcPath, sucPath);
-    nixDB.setStrings(txn, dbSuccessorsRev, sucPath, revs);
-}
-
-
-void unregisterSuccessor(const Path & srcPath)
-{
-    assertStorePath(srcPath);
-
-    Transaction txn(nixDB);
-
-    Path sucPath;
-    if (!nixDB.queryString(txn, dbSuccessors, srcPath, sucPath)) {
-        txn.abort();
-        return;
+        Paths referers;
+        nixDB.queryStrings(txn, dbReferers, *i, referers);
+        PathSet referers2(referers.begin(), referers.end());
+        referers2.insert(storePath);
+        nixDB.setStrings(txn, dbReferers, *i,
+            Paths(referers2.begin(), referers2.end()));
     }
-    nixDB.delPair(txn, dbSuccessors, srcPath);
-
-    Paths revs;
-    nixDB.queryStrings(txn, dbSuccessorsRev, sucPath, revs);
-    Paths::iterator i = find(revs.begin(), revs.end(), srcPath);
-    assert(i != revs.end());
-    revs.erase(i);
-    nixDB.setStrings(txn, dbSuccessorsRev, sucPath, revs);
-
-    txn.commit();
-}
-
-
-bool querySuccessor(const Path & srcPath, Path & sucPath)
-{
-    return nixDB.queryString(noTxn, dbSuccessors, srcPath, sucPath);
 }
 
 
-Paths queryPredecessors(const Path & sucPath)
+void queryReferences(const Path & storePath, PathSet & references)
 {
-    Paths revs;
-    nixDB.queryStrings(noTxn, dbSuccessorsRev, sucPath, revs);
-    return revs;
+    Paths references2;
+    nixDB.queryStrings(noTxn, dbReferences, storePath, references2);
+    references.insert(references2.begin(), references2.end());
 }
 
 
@@ -355,18 +300,6 @@ Substitutes querySubstitutes(const Path & srcPath)
 }
 
 
-static void unregisterPredecessors(const Path & path, Transaction & txn)
-{
-    /* Remove any successor mappings to this path (but not *from*
-       it). */
-    Paths revs;
-    nixDB.queryStrings(txn, dbSuccessorsRev, path, revs);
-    for (Paths::iterator i = revs.begin(); i != revs.end(); ++i)
-        nixDB.delPair(txn, dbSuccessors, *i);
-    nixDB.delPair(txn, dbSuccessorsRev, path);
-}
- 
-
 void clearSubstitutes()
 {
     Transaction txn(nixDB);
@@ -375,16 +308,6 @@ void clearSubstitutes()
     Paths subKeys;
     nixDB.enumTable(txn, dbSubstitutes, subKeys);
     for (Paths::iterator i = subKeys.begin(); i != subKeys.end(); ++i) {
-
-        /* If this path has not become valid in the mean-while, delete
-           any successor mappings *to* it.  This is to preserve the
-           invariant the all successors are `usable' as opposed to
-           `valid' (i.e., the successor must be valid *or* have at
-           least one substitute). */
-        if (!isValidPath(*i)) {
-            unregisterPredecessors(*i, txn);
-        }
-        
         /* Delete all substitutes for path *i. */
         nixDB.delPair(txn, dbSubstitutes, *i);
     }
@@ -407,7 +330,6 @@ static void invalidatePath(const Path & path, Transaction & txn)
     debug(format("unregistering path `%1%'") % path);
 
     nixDB.delPair(txn, dbValidPaths, path);
-    unregisterPredecessors(path, txn);
 }
 
 
@@ -562,34 +484,5 @@ void verifyStore()
             nixDB.delPair(txn, dbSubstitutes, *i);
     }
 
-    /* Check that the values of the successor mappings are usable
-       paths. */ 
-    Paths sucKeys;
-    nixDB.enumTable(txn, dbSuccessors, sucKeys);
-    for (Paths::iterator i = sucKeys.begin(); i != sucKeys.end(); ++i) {
-        /* Note that *i itself does not have to be valid, just its
-           successor. */
-        Path sucPath;
-        if (nixDB.queryString(txn, dbSuccessors, *i, sucPath) &&
-            usablePaths.find(sucPath) == usablePaths.end())
-        {
-            printMsg(lvlError,
-                format("found successor mapping to non-existent path `%1%'") % sucPath);
-            nixDB.delPair(txn, dbSuccessors, *i);
-        }
-    }
-
-    /* Check that the keys of the reverse successor mappings are valid
-       paths. */ 
-    Paths rsucKeys;
-    nixDB.enumTable(txn, dbSuccessorsRev, rsucKeys);
-    for (Paths::iterator i = rsucKeys.begin(); i != rsucKeys.end(); ++i) {
-        if (usablePaths.find(*i) == usablePaths.end()) {
-            printMsg(lvlError,
-                format("found reverse successor mapping for non-existent path `%1%'") % *i);
-            nixDB.delPair(txn, dbSuccessorsRev, *i);
-        }
-    }
-
     txn.commit();
 }