about summary refs log tree commit diff
path: root/src/normalise.cc
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2003-08-01T15·41+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2003-08-01T15·41+0000
commitc95b4ad2906ce4076f04e0969b7080c0589a8cea (patch)
treece3d6690834645117d2d6dfa714161fe97e09ca6 /src/normalise.cc
parentd99d04e6442dcc39a24cebac01af117ce00a5006 (diff)
* In normaliseFState(), wrap registration of the output paths and the
  normal form in a single transaction to ensure that if we crash,
  either everything is registered or nothing is.  This is for
  recoverability: unregistered paths in the store can be deleted
  arbitrarily, while registered paths can only be deleted by running
  the garbage collector.

Diffstat (limited to 'src/normalise.cc')
-rw-r--r--src/normalise.cc39
1 files changed, 23 insertions, 16 deletions
diff --git a/src/normalise.cc b/src/normalise.cc
index 2eb34d4ee2..074eda2960 100644
--- a/src/normalise.cc
+++ b/src/normalise.cc
@@ -8,19 +8,10 @@
 #include "globals.hh"
 
 
-void registerSuccessor(const FSId & id1, const FSId & id2)
+void registerSuccessor(const Transaction & txn,
+    const FSId & id1, const FSId & id2)
 {
-    Transaction txn(nixDB);
     nixDB.setString(txn, dbSuccessors, id1, id2);
-    txn.commit();
-}
-
-
-static FSId storeSuccessor(const FSId & id1, ATerm sc)
-{
-    FSId id2 = writeTerm(sc, "-s-" + (string) id1);
-    registerSuccessor(id1, id2);
-    return id2;
 }
 
 
@@ -153,7 +144,7 @@ FSId normaliseFState(FSId id, FSIdSet pending)
             expandId(i->second, i->first, "/", pending);
         } catch (Error & e) {
             debug(format("fast build failed for `%1%': %2%")
-		  % i->first % e.what());
+                % i->first % e.what());
             fastBuild = false;
             break;
         }
@@ -175,8 +166,8 @@ FSId normaliseFState(FSId id, FSIdSet pending)
     } else
         msg(lvlChatty, format("fast build succesful"));
 
-    /* Check whether the output paths were created, and register each
-       one. */
+    /* Check whether the output paths were created, and grep each
+       output path to determine what other paths it references. */
     FSIdSet used;
     for (OutPaths::iterator i = outPaths.begin(); 
          i != outPaths.end(); i++)
@@ -184,7 +175,6 @@ FSId normaliseFState(FSId id, FSIdSet pending)
         string path = i->first;
         if (!pathExists(path))
             throw Error(format("path `%1%' does not exist") % path);
-        registerPath(path, i->second);
         fs.slice.roots.push_back(i->second);
 
         Strings refs = filterReferences(path, refPaths);
@@ -224,10 +214,27 @@ FSId normaliseFState(FSId id, FSIdSet pending)
         }
     }
 
+    /* Write the normal form.  This does not have to occur in the
+       transaction below because writing terms is idem-potent. */
     fs.type = FState::fsSlice;
     ATerm nf = unparseFState(fs);
     msg(lvlVomit, format("normal form: %1%") % printTerm(nf));
-    return storeSuccessor(id, nf);
+    FSId idNF = writeTerm(nf, "-s-" + (string) id);
+
+    /* Register each outpat path, and register the normal form.  This
+       is wrapped in one database transaction to ensure that if we
+       crash, either everything is registered or nothing is.  This is
+       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);
+    for (OutPaths::iterator i = outPaths.begin(); 
+         i != outPaths.end(); i++)
+        registerPath(txn, i->first, i->second);
+    registerSuccessor(txn, id, idNF);
+    txn.commit();
+
+    return idNF;
 }