diff --git a/src/libstore/build/local-derivation-goal.cc b/src/libstore/build/local-derivation-goal.cc index b2a301b00..6a298e6eb 100644 --- a/src/libstore/build/local-derivation-goal.cc +++ b/src/libstore/build/local-derivation-goal.cc @@ -2216,23 +2216,21 @@ SingleDrvOutputs LocalDerivationGoal::registerOutputs() rewriteOutput(outputRewrites); /* FIXME optimize and deduplicate with addToStore */ std::string oldHashPart { scratchPath->hashPart() }; - HashModuloSink caSink { outputHash.hashType, oldHashPart }; - std::visit(overloaded { - [&](const TextIngestionMethod &) { - caSink << readFileSource(actualPath); + auto input = std::visit(overloaded { + [&](const TextIngestionMethod &) -> GeneratorSource { + return GeneratorSource(readFileSource(actualPath)); }, - [&](const FileIngestionMethod & m2) { + [&](const FileIngestionMethod & m2) -> GeneratorSource { switch (m2) { case FileIngestionMethod::Recursive: - caSink << dumpPath(actualPath); - break; + return GeneratorSource(dumpPath(actualPath)); case FileIngestionMethod::Flat: - caSink << readFileSource(actualPath); - break; + return GeneratorSource(readFileSource(actualPath)); } + assert(false); }, }, outputHash.method.raw); - auto got = caSink.finish().first; + auto got = computeHashModulo(outputHash.hashType, oldHashPart, input).first; auto optCA = ContentAddressWithReferences::fromPartsOpt( outputHash.method, diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index 98e4d7efe..757aa21e3 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -1887,25 +1887,23 @@ ContentAddress LocalStore::hashCAPath( const std::string_view pathHash ) { - HashModuloSink caSink ( hashType, std::string(pathHash) ); - std::visit(overloaded { - [&](const TextIngestionMethod &) { - caSink << readFileSource(path); + auto data = std::visit(overloaded { + [&](const TextIngestionMethod &) -> GeneratorSource { + return GeneratorSource(readFileSource(path)); }, - [&](const FileIngestionMethod & m2) { + [&](const FileIngestionMethod & m2) -> GeneratorSource { switch (m2) { case FileIngestionMethod::Recursive: - caSink << dumpPath(path); - break; + return GeneratorSource(dumpPath(path)); case FileIngestionMethod::Flat: - caSink << readFileSource(path); - break; + return GeneratorSource(readFileSource(path)); } + assert(false); }, }, method.raw); return ContentAddress { .method = method, - .hash = caSink.finish().first, + .hash = computeHashModulo(hashType, std::string(pathHash), data).first, }; } diff --git a/src/libstore/make-content-addressed.cc b/src/libstore/make-content-addressed.cc index 253609ed2..b5397541c 100644 --- a/src/libstore/make-content-addressed.cc +++ b/src/libstore/make-content-addressed.cc @@ -43,10 +43,10 @@ std::map makeContentAddressed( sink.s = rewriteStrings(sink.s, rewrites); - HashModuloSink hashModuloSink(htSHA256, oldHashPart); - hashModuloSink(sink.s); - - auto narModuloHash = hashModuloSink.finish().first; + auto narModuloHash = [&] { + StringSource source{sink.s}; + return computeHashModulo(htSHA256, oldHashPart, source).first; + }(); ValidPathInfo info { dstStore, diff --git a/src/libutil/hash.hh b/src/libutil/hash.hh index bb2a5e2a7..1c2f8493b 100644 --- a/src/libutil/hash.hh +++ b/src/libutil/hash.hh @@ -203,5 +203,12 @@ public: HashResult currentHash(); }; +inline HashResult hashSource(HashType ht, Source & source) +{ + HashSink h(ht); + source.drainInto(h); + return h.finish(); +} + } diff --git a/src/libutil/references.cc b/src/libutil/references.cc index 6189f69b9..249c78bf7 100644 --- a/src/libutil/references.cc +++ b/src/libutil/references.cc @@ -109,19 +109,12 @@ void RewritingSink::flush() prev.clear(); } -HashModuloSink::HashModuloSink(HashType ht, const std::string & modulus) - : hashSink(ht) - , rewritingSink(modulus, std::string(modulus.size(), 0), hashSink) +HashResult computeHashModulo(HashType ht, const std::string & modulus, Source & source) { -} + HashSink hashSink(ht); + RewritingSink rewritingSink(modulus, std::string(modulus.size(), 0), hashSink); -void HashModuloSink::operator () (std::string_view data) -{ - rewritingSink(data); -} - -HashResult HashModuloSink::finish() -{ + source.drainInto(rewritingSink); rewritingSink.flush(); /* Hash the positions of the self-references. This ensures that a diff --git a/src/libutil/references.hh b/src/libutil/references.hh index f0baeffe1..970d2d235 100644 --- a/src/libutil/references.hh +++ b/src/libutil/references.hh @@ -41,16 +41,6 @@ struct RewritingSink : Sink void flush(); }; -struct HashModuloSink : AbstractHashSink -{ - HashSink hashSink; - RewritingSink rewritingSink; - - HashModuloSink(HashType ht, const std::string & modulus); - - void operator () (std::string_view data) override; - - HashResult finish() override; -}; +HashResult computeHashModulo(HashType ht, const std::string & modulus, Source & source); } diff --git a/src/nix/hash.cc b/src/nix/hash.cc index d9079d551..12b66a83c 100644 --- a/src/nix/hash.cc +++ b/src/nix/hash.cc @@ -76,23 +76,19 @@ struct CmdHashBase : Command void run() override { for (auto path : paths) { + auto source = [&] () -> GeneratorSource { + switch (mode) { + case FileIngestionMethod::Flat: + return GeneratorSource(readFileSource(path)); + case FileIngestionMethod::Recursive: + return GeneratorSource(dumpPath(path)); + } + assert(false); + }(); - std::unique_ptr hashSink; - if (modulus) - hashSink = std::make_unique(ht, *modulus); - else - hashSink = std::make_unique(ht); - - switch (mode) { - case FileIngestionMethod::Flat: - *hashSink << readFileSource(path); - break; - case FileIngestionMethod::Recursive: - *hashSink << dumpPath(path); - break; - } - - Hash h = hashSink->finish().first; + Hash h = modulus + ? computeHashModulo(ht, *modulus, source).first + : hashSource(ht, source).first; if (truncate && h.hashSize > 20) h = compressHash(h, 20); logger->cout(h.to_string(base, base == SRI)); }