Merge remote-tracking branch 'obsidian/fix-add-to-star-narhash' into from-dump-stream

This commit is contained in:
John Ericson 2020-07-15 21:05:29 +00:00
commit aff69e229c

View file

@ -1066,15 +1066,8 @@ StorePath LocalStore::addToStoreCommon(
const string & name, FileIngestionMethod method, HashType hashAlgo, RepairFlag repair, const string & name, FileIngestionMethod method, HashType hashAlgo, RepairFlag repair,
std::function<void(Sink &, size_t &)> demux) std::function<void(Sink &, size_t &)> demux)
{ {
/* For computing the NAR hash. */ /* For computing the store path. */
auto sha256Sink = std::make_unique<HashSink>(htSHA256); auto hashSink = std::make_unique<HashSink>(hashAlgo);
/* For computing the store path. In recursive SHA-256 mode, this
is the same as the NAR hash, so no need to do it again. */
std::unique_ptr<HashSink> hashSink =
method == FileIngestionMethod::Recursive && hashAlgo == htSHA256
? nullptr
: std::make_unique<HashSink>(hashAlgo);
/* Read the source path into memory, but only if it's up to /* Read the source path into memory, but only if it's up to
narBufferSize bytes. If it's larger, write it to a temporary narBufferSize bytes. If it's larger, write it to a temporary
@ -1083,21 +1076,20 @@ StorePath LocalStore::addToStoreCommon(
temporary path. Otherwise, we move it to the destination store temporary path. Otherwise, we move it to the destination store
path. */ path. */
bool inMemory = true; bool inMemory = true;
std::string nar; std::string dump;
auto source = sinkToSource([&](Sink & sink, size_t & wanted) { auto source = sinkToSource([&](Sink & sink, size_t & wanted) {
LambdaSink sink2([&](const unsigned char * buf, size_t len) { LambdaSink sink2([&](const unsigned char * buf, size_t len) {
(*sha256Sink)(buf, len); (*hashSink)(buf, len);
if (hashSink) (*hashSink)(buf, len);
if (inMemory) { if (inMemory) {
if (nar.size() + len > settings.narBufferSize) { if (dump.size() + len > settings.narBufferSize) {
inMemory = false; inMemory = false;
sink << 1; sink << 1;
sink((const unsigned char *) nar.data(), nar.size()); sink((const unsigned char *) dump.data(), dump.size());
nar.clear(); dump.clear();
} else { } else {
nar.append((const char *) buf, len); dump.append((const char *) buf, len);
} }
} }
@ -1129,9 +1121,7 @@ StorePath LocalStore::addToStoreCommon(
/* The NAR fits in memory, so we didn't do restorePath(). */ /* The NAR fits in memory, so we didn't do restorePath(). */
} }
auto sha256 = sha256Sink->finish(); auto [hash, size] = hashSink->finish();
Hash hash = hashSink ? hashSink->finish().first : sha256.first;
auto dstPath = makeFixedOutputPath(method, hash, name); auto dstPath = makeFixedOutputPath(method, hash, name);
@ -1154,7 +1144,7 @@ StorePath LocalStore::addToStoreCommon(
if (inMemory) { if (inMemory) {
/* Restore from the NAR in memory. */ /* Restore from the NAR in memory. */
StringSource source(nar); StringSource source(dump);
if (method == FileIngestionMethod::Recursive) if (method == FileIngestionMethod::Recursive)
restorePath(realPath, source); restorePath(realPath, source);
else else
@ -1165,13 +1155,22 @@ StorePath LocalStore::addToStoreCommon(
throw Error("renaming '%s' to '%s'", tempPath, realPath); throw Error("renaming '%s' to '%s'", tempPath, realPath);
} }
/* For computing the nar hash. In recursive SHA-256 mode, this
is the same as the store hash, so no need to do it again. */
auto narHash = std::pair { hash, size };
if (method != FileIngestionMethod::Recursive || hashAlgo != htSHA256) {
HashSink narSink { htSHA256 };
dumpPath(realPath, narSink);
narHash = narSink.finish();
}
canonicalisePathMetaData(realPath, -1); // FIXME: merge into restorePath canonicalisePathMetaData(realPath, -1); // FIXME: merge into restorePath
optimisePath(realPath); optimisePath(realPath);
ValidPathInfo info(dstPath); ValidPathInfo info(dstPath);
info.narHash = sha256.first; info.narHash = narHash.first;
info.narSize = sha256.second; info.narSize = narHash.second;
info.ca = FixedOutputHash { .method = method, .hash = hash }; info.ca = FixedOutputHash { .method = method, .hash = hash };
registerValidPath(info); registerValidPath(info);
} }