aboutsummaryrefslogtreecommitdiff
path: root/src/libstore/store-api.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstore/store-api.cc')
-rw-r--r--src/libstore/store-api.cc117
1 files changed, 72 insertions, 45 deletions
diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc
index 8fc3ed46a..5bee1af9f 100644
--- a/src/libstore/store-api.cc
+++ b/src/libstore/store-api.cc
@@ -7,6 +7,7 @@
#include "nar-info-disk-cache.hh"
#include "thread-pool.hh"
#include "url.hh"
+#include "references.hh"
#include "archive.hh"
#include "callback.hh"
#include "remote-store.hh"
@@ -98,10 +99,12 @@ StorePath Store::followLinksToStorePath(std::string_view path) const
silly, but it's done that way for compatibility). <id> is the
name of the output (usually, "out").
- <h2> = base-16 representation of a SHA-256 hash of:
+ <h2> = base-16 representation of a SHA-256 hash of <s2>
+
+ <s2> =
if <type> = "text:...":
the string written to the resulting store path
- if <type> = "source":
+ if <type> = "source:...":
the serialisation of the path from which this store path is
copied, as returned by hashPath()
if <type> = "output:<id>":
@@ -162,63 +165,63 @@ StorePath Store::makeOutputPath(std::string_view id,
}
+/* Stuff the references (if any) into the type. This is a bit
+ hacky, but we can't put them in, say, <s2> (per the grammar above)
+ since that would be ambiguous. */
static std::string makeType(
const Store & store,
std::string && type,
- const StorePathSet & references,
- bool hasSelfReference = false)
+ const StoreReferences & references)
{
- for (auto & i : references) {
+ for (auto & i : references.others) {
type += ":";
type += store.printStorePath(i);
}
- if (hasSelfReference) type += ":self";
+ if (references.self) type += ":self";
return std::move(type);
}
-StorePath Store::makeFixedOutputPath(
- FileIngestionMethod method,
- const Hash & hash,
- std::string_view name,
- const StorePathSet & references,
- bool hasSelfReference) const
+StorePath Store::makeFixedOutputPath(std::string_view name, const FixedOutputInfo & info) const
{
- if (hash.type == htSHA256 && method == FileIngestionMethod::Recursive) {
- return makeStorePath(makeType(*this, "source", references, hasSelfReference), hash, name);
+ if (info.hash.hash.type == htSHA256 && info.hash.method == FileIngestionMethod::Recursive) {
+ return makeStorePath(makeType(*this, "source", info.references), info.hash.hash, name);
} else {
- assert(references.empty());
+ assert(info.references.size() == 0);
return makeStorePath("output:out",
hashString(htSHA256,
"fixed:out:"
- + makeFileIngestionPrefix(method)
- + hash.to_string(Base16, true) + ":"),
+ + makeFileIngestionPrefix(info.hash.method)
+ + info.hash.hash.to_string(Base16, true) + ":"),
name);
}
}
-StorePath Store::makeFixedOutputPathFromCA(std::string_view name, ContentAddress ca,
- const StorePathSet & references, bool hasSelfReference) const
+
+StorePath Store::makeTextPath(std::string_view name, const TextInfo & info) const
+{
+ assert(info.hash.hash.type == htSHA256);
+ return makeStorePath(
+ makeType(*this, "text", StoreReferences {
+ .others = info.references,
+ .self = false,
+ }),
+ info.hash.hash,
+ name);
+}
+
+
+StorePath Store::makeFixedOutputPathFromCA(std::string_view name, const ContentAddressWithReferences & ca) const
{
// New template
return std::visit(overloaded {
- [&](const TextHash & th) {
- return makeTextPath(name, th.hash, references);
+ [&](const TextInfo & ti) {
+ return makeTextPath(name, ti);
},
- [&](const FixedOutputHash & fsh) {
- return makeFixedOutputPath(fsh.method, fsh.hash, name, references, hasSelfReference);
+ [&](const FixedOutputInfo & foi) {
+ return makeFixedOutputPath(name, foi);
}
- }, ca);
-}
-
-StorePath Store::makeTextPath(std::string_view name, const Hash & hash,
- const StorePathSet & references) const
-{
- assert(hash.type == htSHA256);
- /* Stuff the references (if any) into the type. This is a bit
- hacky, but we can't put them in `s' since that would be
- ambiguous. */
- return makeStorePath(makeType(*this, "text", references), hash, name);
+ }, ca.raw);
}
@@ -228,7 +231,14 @@ std::pair<StorePath, Hash> Store::computeStorePathForPath(std::string_view name,
Hash h = method == FileIngestionMethod::Recursive
? hashPath(hashAlgo, srcPath, filter).first
: hashFile(hashAlgo, srcPath);
- return std::make_pair(makeFixedOutputPath(method, h, name), h);
+ FixedOutputInfo caInfo {
+ .hash = {
+ .method = method,
+ .hash = h,
+ },
+ .references = {},
+ };
+ return std::make_pair(makeFixedOutputPath(name, caInfo), h);
}
@@ -237,7 +247,10 @@ StorePath Store::computeStorePathForText(
std::string_view s,
const StorePathSet & references) const
{
- return makeTextPath(name, hashString(htSHA256, s), references);
+ return makeTextPath(name, TextInfo {
+ { .hash = hashString(htSHA256, s) },
+ references,
+ });
}
@@ -425,11 +438,18 @@ ValidPathInfo Store::addToStoreSlow(std::string_view name, const Path & srcPath,
throw Error("hash mismatch for '%s'", srcPath);
ValidPathInfo info {
- makeFixedOutputPath(method, hash, name),
+ *this,
+ name,
+ FixedOutputInfo {
+ .hash = {
+ .method = method,
+ .hash = hash,
+ },
+ .references = {},
+ },
narHash,
};
info.narSize = narSize;
- info.ca = FixedOutputHash { .method = method, .hash = hash };
if (!isValidPath(info.path)) {
auto source = sinkToSource([&](Sink & scratchpadSink) {
@@ -521,7 +541,9 @@ void Store::querySubstitutablePathInfos(const StorePathCAMap & paths, Substituta
// Recompute store path so that we can use a different store root.
if (path.second) {
- subPath = makeFixedOutputPathFromCA(path.first.name(), *path.second);
+ subPath = makeFixedOutputPathFromCA(
+ path.first.name(),
+ ContentAddressWithReferences::withoutRefs(*path.second));
if (sub->storeDir == storeDir)
assert(subPath == path.first);
if (subPath != path.first)
@@ -538,10 +560,11 @@ void Store::querySubstitutablePathInfos(const StorePathCAMap & paths, Substituta
auto narInfo = std::dynamic_pointer_cast<const NarInfo>(
std::shared_ptr<const ValidPathInfo>(info));
infos.insert_or_assign(path.first, SubstitutablePathInfo{
- info->deriver,
- info->references,
- narInfo ? narInfo->fileSize : 0,
- info->narSize});
+ .deriver = info->deriver,
+ .references = info->references,
+ .downloadSize = narInfo ? narInfo->fileSize : 0,
+ .narSize = info->narSize,
+ });
} catch (InvalidPath &) {
} catch (SubstituterDisabled &) {
} catch (Error & e) {
@@ -1025,7 +1048,9 @@ void copyStorePath(
// recompute store path on the chance dstStore does it differently
if (info->ca && info->references.empty()) {
auto info2 = make_ref<ValidPathInfo>(*info);
- info2->path = dstStore.makeFixedOutputPathFromCA(info->path.name(), *info->ca);
+ info2->path = dstStore.makeFixedOutputPathFromCA(
+ info->path.name(),
+ info->contentAddressWithReferences().value());
if (dstStore.storeDir == srcStore.storeDir)
assert(info->path == info2->path);
info = info2;
@@ -1137,7 +1162,9 @@ std::map<StorePath, StorePath> copyPaths(
auto storePathForSrc = currentPathInfo.path;
auto storePathForDst = storePathForSrc;
if (currentPathInfo.ca && currentPathInfo.references.empty()) {
- storePathForDst = dstStore.makeFixedOutputPathFromCA(storePathForSrc.name(), *currentPathInfo.ca);
+ storePathForDst = dstStore.makeFixedOutputPathFromCA(
+ currentPathInfo.path.name(),
+ currentPathInfo.contentAddressWithReferences().value());
if (dstStore.storeDir == srcStore.storeDir)
assert(storePathForDst == storePathForSrc);
if (storePathForDst != storePathForSrc)