about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2008-12-03T15·51+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2008-12-03T15·51+0000
commit1307b222239da8e503d22ad9316789e30b4e2431 (patch)
treeb2b84893aadf91122672e79244072c529239e39d
parent64519cfd657d024ae6e2bb74cb21ad21b886fd2a (diff)
* Made addToStore() a lot more efficient: it no longer reads the path
  being copied 3 times in the worst case.  It doesn't run in constant space,
  but it didn't do that anyway.

-rw-r--r--src/libexpr/primops.cc4
-rw-r--r--src/libstore/local-store.cc60
2 files changed, 29 insertions, 35 deletions
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index 27ce28b8f7..657c3bf71b 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -257,9 +257,7 @@ static Hash hashDerivationModulo(EvalState & state, Derivation drv)
     /* For other derivations, replace the inputs paths with recursive
        calls to this function.*/
     DerivationInputs inputs2;
-    for (DerivationInputs::iterator i = drv.inputDrvs.begin();
-         i != drv.inputDrvs.end(); ++i)
-    {
+    foreach (DerivationInputs::const_iterator, i, drv.inputDrvs) {
         Hash h = state.drvHashes[i->first];
         if (h.type == htUnknown) {
             Derivation drv2 = derivationFromPath(i->first);
diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc
index e015894b9f..fc62a99930 100644
--- a/src/libstore/local-store.cc
+++ b/src/libstore/local-store.cc
@@ -108,23 +108,6 @@ int LocalStore::getSchema()
 }
 
 
-void copyPath(const Path & src, const Path & dst, PathFilter & filter)
-{
-    debug(format("copying `%1%' to `%2%'") % src % dst);
-
-    /* Dump an archive of the path `src' into a string buffer, then
-       restore the archive to `dst'.  This is not a very good method
-       for very large paths, but `copyPath' is mainly used for small
-       files. */ 
-
-    StringSink sink;
-    dumpPath(src, sink, filter);
-
-    StringSource source(sink.s);
-    restorePath(dst, source);
-}
-
-
 void canonicalisePathMetaData(const Path & path, bool recurse)
 {
     checkInterrupt();
@@ -332,6 +315,8 @@ void LocalStore::registerValidPath(const ValidPathInfo & info, bool ignoreValidi
             appendReferrer(*i, info.path, false);
     }
 
+    assert(info.hash.type == htSHA256);
+
     string s = (format(
         "Hash: sha256:%1%\n"
         "References: %2%\n"
@@ -676,10 +661,18 @@ Path LocalStore::addToStore(const Path & _srcPath,
     Path srcPath(absPath(_srcPath));
     debug(format("adding `%1%' to the store") % srcPath);
 
-    std::pair<Path, Hash> pr =
-        computeStorePathForPath(srcPath, recursive, hashAlgo, filter);
-    Path & dstPath(pr.first);
-    Hash & h(pr.second);
+    /* Read the whole path into memory. This is not a very scalable
+       method for very large paths, but `copyPath' is mainly used for
+       small files. */
+    StringSink sink;
+    if (recursive) 
+        dumpPath(srcPath, sink, filter);
+    else
+        sink.s = readFile(srcPath);
+
+    Hash h = hashString(parseHashType(hashAlgo), sink.s);
+
+    Path dstPath = makeFixedOutputPath(recursive, hashAlgo, h, baseNameOf(srcPath));
 
     addTempRoot(dstPath);
 
@@ -694,19 +687,22 @@ Path LocalStore::addToStore(const Path & _srcPath,
 
             if (pathExists(dstPath)) deletePathWrapped(dstPath);
 
-            copyPath(srcPath, dstPath, filter);
-
-            /* !!! */
-#if 0            
-            Hash h2 = hashPath(htSHA256, dstPath, filter);
-            if (h != h2)
-                throw Error(format("contents of `%1%' changed while copying it to `%2%' (%3% -> %4%)")
-                    % srcPath % dstPath % printHash(h) % printHash(h2));
-#endif
+            if (recursive) {
+                StringSource source(sink.s);
+                restorePath(dstPath, source);
+            } else
+                writeStringToFile(dstPath, sink.s);
 
             canonicalisePathMetaData(dstPath);
-            
-            registerValidPath(dstPath, h, PathSet(), "");
+
+            /* Register the SHA-256 hash of the NAR serialisation of
+               the path in the database.  We may just have computed it
+               above (if called with recursive == true and hashAlgo ==
+               sha256); otherwise, compute it here. */
+            registerValidPath(dstPath,
+                (recursive && hashAlgo == "sha256") ? h :
+                (recursive ? hashString(htSHA256, sink.s) : hashPath(htSHA256, dstPath)),
+                PathSet(), "");
         }
 
         outputLock.setDeletion(true);