aboutsummaryrefslogtreecommitdiff
path: root/src/libstore/store-api.cc
diff options
context:
space:
mode:
authorJohn Ericson <John.Ericson@Obsidian.Systems>2020-07-16 05:09:41 +0000
committerJohn Ericson <John.Ericson@Obsidian.Systems>2020-07-16 05:09:41 +0000
commit68dfb8c6aef7afebf0312c48bb5010653fc464b3 (patch)
tree771075c2311abaae41f0e17ecc8f09082755d7b0 /src/libstore/store-api.cc
parent36a124260361ba8dfa43bf43a067dcc48064c93f (diff)
Optimize `addToStoreSlow` and remove `TeeParseSink`
Diffstat (limited to 'src/libstore/store-api.cc')
-rw-r--r--src/libstore/store-api.cc35
1 files changed, 28 insertions, 7 deletions
diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc
index 5b9f79049..5c8dddba5 100644
--- a/src/libstore/store-api.cc
+++ b/src/libstore/store-api.cc
@@ -226,16 +226,37 @@ ValidPathInfo Store::addToStoreSlow(std::string_view name, const Path & srcPath,
FileIngestionMethod method, HashType hashAlgo,
std::optional<Hash> expectedCAHash)
{
- /* FIXME: inefficient: we're reading/hashing 'tmpFile' three
+ /* FIXME: inefficient: we're reading/hashing 'tmpFile' two
times. */
+ HashSink narHashSink { htSHA256 };
+ HashSink caHashSink { hashAlgo };
+ RetrieveRegularNARSink fileSink { caHashSink };
- auto [narHash, narSize] = hashPath(htSHA256, srcPath);
+ TeeSink sinkIfNar { narHashSink, caHashSink };
- auto hash = method == FileIngestionMethod::Recursive
- ? hashAlgo == htSHA256
- ? narHash
- : hashPath(hashAlgo, srcPath).first
- : hashFile(hashAlgo, srcPath);
+ /* We use the tee sink if we need to hash he nar twice */
+ auto & sink = method == FileIngestionMethod::Recursive && hashAlgo != htSHA256
+ ? static_cast<Sink &>(sinkIfNar)
+ : narHashSink;
+
+ auto fileSource = sinkToSource([&](Sink & sink) {
+ dumpPath(srcPath, sink);
+ });
+
+ TeeSource tapped { *fileSource, sink };
+
+ ParseSink blank;
+ auto & parseSink = method == FileIngestionMethod::Flat
+ ? fileSink
+ : blank;
+
+ parseDump(parseSink, tapped);
+
+ auto [narHash, narSize] = narHashSink.finish();
+
+ auto hash = method == FileIngestionMethod::Recursive && hashAlgo == htSHA256
+ ? narHash
+ : caHashSink.finish().first;
if (expectedCAHash && expectedCAHash != hash)
throw Error("hash mismatch for '%s'", srcPath);