aboutsummaryrefslogtreecommitdiff
path: root/src/libstore
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2008-12-03 15:51:17 +0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2008-12-03 15:51:17 +0000
commit1307b222239da8e503d22ad9316789e30b4e2431 (patch)
treeb2b84893aadf91122672e79244072c529239e39d /src/libstore
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')
-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 e015894b9..fc62a9993 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);