about summary refs log tree commit diff
path: root/src/libstore/local-store.cc
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 /src/libstore/local-store.cc
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.

Diffstat (limited to 'src/libstore/local-store.cc')
-rw-r--r--src/libstore/local-store.cc60
1 files changed, 28 insertions, 32 deletions
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);