From 1307b222239da8e503d22ad9316789e30b4e2431 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 3 Dec 2008 15:51:17 +0000 Subject: [PATCH] * 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. --- src/libexpr/primops.cc | 4 +-- src/libstore/local-store.cc | 60 +++++++++++++++++-------------------- 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 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);