aboutsummaryrefslogtreecommitdiff
path: root/src/libstore
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstore')
-rw-r--r--src/libstore/binary-cache-store.cc43
-rw-r--r--src/libstore/build.cc30
-rw-r--r--src/libstore/content-address.cc24
-rw-r--r--src/libstore/content-address.hh102
-rw-r--r--src/libstore/derivations.cc4
-rw-r--r--src/libstore/derivations.hh4
-rw-r--r--src/libstore/local-store.cc30
-rw-r--r--src/libstore/nar-info.hh3
-rw-r--r--src/libstore/path-info.hh47
-rw-r--r--src/libstore/path.hh5
-rw-r--r--src/libstore/store-api.cc171
-rw-r--r--src/libstore/store-api.hh14
12 files changed, 323 insertions, 154 deletions
diff --git a/src/libstore/binary-cache-store.cc b/src/libstore/binary-cache-store.cc
index d592f16dd..2d92e1c50 100644
--- a/src/libstore/binary-cache-store.cc
+++ b/src/libstore/binary-cache-store.cc
@@ -322,7 +322,17 @@ StorePath BinaryCacheStore::addToStoreFromDump(Source & dump, const string & nam
unsupported("addToStoreFromDump");
return addToStoreCommon(dump, repair, CheckSigs, [&](HashResult nar) {
ValidPathInfo info {
- makeFixedOutputPath(method, nar.first, name),
+ *this,
+ {
+ .name = name,
+ .info = FixedOutputInfo {
+ {
+ .method = method,
+ .hash = nar.first,
+ },
+ {},
+ },
+ },
nar.first,
};
info.narSize = nar.second;
@@ -412,14 +422,20 @@ StorePath BinaryCacheStore::addToStore(const string & name, const Path & srcPath
});
return addToStoreCommon(*source, repair, CheckSigs, [&](HashResult nar) {
ValidPathInfo info {
- makeFixedOutputPath(method, h, name),
+ *this,
+ {
+ .name = name,
+ .info = FixedOutputInfo {
+ {
+ .method = method,
+ .hash = h,
+ },
+ {},
+ },
+ },
nar.first,
};
info.narSize = nar.second;
- info.ca = FixedOutputHash {
- .method = method,
- .hash = h,
- };
return info;
})->path;
}
@@ -428,17 +444,26 @@ StorePath BinaryCacheStore::addTextToStore(const string & name, const string & s
const StorePathSet & references, RepairFlag repair)
{
auto textHash = hashString(htSHA256, s);
- auto path = makeTextPath(name, textHash, references);
+ auto path = makeTextPath(name, TextInfo { textHash, references });
if (!repair && isValidPath(path))
return path;
auto source = StringSource { s };
return addToStoreCommon(source, repair, CheckSigs, [&](HashResult nar) {
- ValidPathInfo info { path, nar.first };
+ ValidPathInfo info {
+ *this,
+ {
+ .name = name,
+ .info = TextInfo {
+ { .hash = textHash },
+ references,
+ },
+ },
+ nar.first,
+ };
info.narSize = nar.second;
info.ca = TextHash { textHash };
- info.references = references;
return info;
})->path;
}
diff --git a/src/libstore/build.cc b/src/libstore/build.cc
index 97a832c6b..12ce6f2ec 100644
--- a/src/libstore/build.cc
+++ b/src/libstore/build.cc
@@ -4056,25 +4056,24 @@ void DerivationGoal::registerOutputs()
break;
}
auto got = caSink.finish().first;
- auto refs = rewriteRefs();
HashModuloSink narSink { htSHA256, oldHashPart };
dumpPath(actualPath, narSink);
auto narHashAndSize = narSink.finish();
ValidPathInfo newInfo0 {
- worker.store.makeFixedOutputPath(
- outputHash.method,
- got,
- outputPathName(drv->name, outputName),
- refs.references,
- refs.hasSelfReference),
+ worker.store,
+ {
+ .name = outputPathName(drv->name, outputName),
+ .info = FixedOutputInfo {
+ {
+ .method = outputHash.method,
+ .hash = got,
+ },
+ rewriteRefs(),
+ },
+ },
narHashAndSize.first,
};
newInfo0.narSize = narHashAndSize.second;
- newInfo0.ca = FixedOutputHash {
- .method = outputHash.method,
- .hash = got,
- };
- static_cast<PathReferences<StorePath> &>(newInfo0) = refs;
assert(newInfo0.ca);
return newInfo0;
@@ -4861,7 +4860,10 @@ void SubstitutionGoal::tryNext()
subs.pop_front();
if (ca) {
- subPath = sub->makeFixedOutputPathFromCA(storePath.name(), *ca);
+ subPath = sub->makeFixedOutputPathFromCA({
+ .name = std::string { storePath.name() },
+ .info = caWithoutRefs(*ca),
+ });
if (sub->storeDir == worker.store.storeDir)
assert(subPath == storePath);
} else if (sub->storeDir != worker.store.storeDir) {
@@ -4891,7 +4893,7 @@ void SubstitutionGoal::tryNext()
}
if (info->path != storePath) {
- if (info->isContentAddressed(*sub) && info->references.empty()) {
+ if (info->isContentAddressed(*sub) && info->references.empty() && !info->hasSelfReference) {
auto info2 = std::make_shared<ValidPathInfo>(*info);
info2->path = storePath;
info = info2;
diff --git a/src/libstore/content-address.cc b/src/libstore/content-address.cc
index 90a3ad1f5..d68c60f4f 100644
--- a/src/libstore/content-address.cc
+++ b/src/libstore/content-address.cc
@@ -9,6 +9,7 @@ std::string FixedOutputHash::printMethodAlgo() const
return makeFileIngestionPrefix(method) + printHashType(hash.type);
}
+
std::string makeFileIngestionPrefix(const FileIngestionMethod m)
{
switch (m) {
@@ -16,9 +17,8 @@ std::string makeFileIngestionPrefix(const FileIngestionMethod m)
return "";
case FileIngestionMethod::Recursive:
return "r:";
- default:
- throw Error("impossible, caught both cases");
}
+ assert(false);
}
std::string makeFixedOutputCA(FileIngestionMethod method, const Hash & hash)
@@ -32,10 +32,13 @@ std::string renderContentAddress(ContentAddress ca)
{
return std::visit(overloaded {
[](TextHash th) {
- return "text:" + th.hash.to_string(Base32, true);
+ return "text:"
+ + th.hash.to_string(Base32, true);
},
[](FixedOutputHash fsh) {
- return makeFixedOutputCA(fsh.method, fsh.hash);
+ return "fixed:"
+ + makeFileIngestionPrefix(fsh.method)
+ + fsh.hash.to_string(Base32, true);
}
}, ca);
}
@@ -142,7 +145,18 @@ Hash getContentAddressHash(const ContentAddress & ca)
},
[](FixedOutputHash fsh) {
return fsh.hash;
- }
+ },
+ }, ca);
+}
+
+ContentAddressWithReferences caWithoutRefs(const ContentAddress & ca) {
+ return std::visit(overloaded {
+ [&](TextHash h) -> ContentAddressWithReferences {
+ return TextInfo { h, {}};
+ },
+ [&](FixedOutputHash h) -> ContentAddressWithReferences {
+ return FixedOutputInfo { h, {}};
+ },
}, ca);
}
diff --git a/src/libstore/content-address.hh b/src/libstore/content-address.hh
index f6a6f5140..e15d76bd7 100644
--- a/src/libstore/content-address.hh
+++ b/src/libstore/content-address.hh
@@ -2,14 +2,20 @@
#include <variant>
#include "hash.hh"
+#include "path.hh"
namespace nix {
+/*
+ * Mini content address
+ */
+
enum struct FileIngestionMethod : uint8_t {
Flat = false,
Recursive = true
};
+
struct TextHash {
Hash hash;
};
@@ -41,10 +47,6 @@ typedef std::variant<
ingested. */
std::string makeFileIngestionPrefix(const FileIngestionMethod m);
-/* Compute the content-addressability assertion (ValidPathInfo::ca)
- for paths created by makeFixedOutputPath() / addToStore(). */
-std::string makeFixedOutputCA(FileIngestionMethod method, const Hash & hash);
-
std::string renderContentAddress(ContentAddress ca);
std::string renderContentAddress(std::optional<ContentAddress> ca);
@@ -74,4 +76,96 @@ ContentAddressMethod parseContentAddressMethod(std::string_view rawCaMethod);
std::string renderContentAddressMethod(ContentAddressMethod caMethod);
+/*
+ * References set
+ */
+
+template<typename Ref>
+struct PathReferences
+{
+ std::set<Ref> references;
+ bool hasSelfReference = false;
+
+ bool operator == (const PathReferences<Ref> & other) const
+ {
+ return references == other.references
+ && hasSelfReference == other.hasSelfReference;
+ }
+
+ /* Functions to view references + hasSelfReference as one set, mainly for
+ compatibility's sake. */
+ StorePathSet referencesPossiblyToSelf(const Ref & self) const;
+ void insertReferencePossiblyToSelf(const Ref & self, Ref && ref);
+ void setReferencesPossiblyToSelf(const Ref & self, std::set<Ref> && refs);
+};
+
+template<typename Ref>
+StorePathSet PathReferences<Ref>::referencesPossiblyToSelf(const Ref & self) const
+{
+ StorePathSet refs { references };
+ if (hasSelfReference)
+ refs.insert(self);
+ return refs;
+}
+
+template<typename Ref>
+void PathReferences<Ref>::insertReferencePossiblyToSelf(const Ref & self, Ref && ref)
+{
+ if (ref == self)
+ hasSelfReference = true;
+ else
+ references.insert(std::move(ref));
+}
+
+template<typename Ref>
+void PathReferences<Ref>::setReferencesPossiblyToSelf(const Ref & self, std::set<Ref> && refs)
+{
+ if (refs.count(self))
+ hasSelfReference = true;
+ refs.erase(self);
+
+ references = refs;
+}
+
+/*
+ * Full content address
+ *
+ * See the schema for store paths in store-api.cc
+ */
+
+// This matches the additional info that we need for makeTextPath
+struct TextInfo : TextHash {
+ // References for the paths, self references disallowed
+ StorePathSet references;
+};
+
+struct FixedOutputInfo : FixedOutputHash {
+ // References for the paths
+ PathReferences<StorePath> references;
+};
+
+typedef std::variant<
+ TextInfo,
+ FixedOutputInfo
+> ContentAddressWithReferences;
+
+ContentAddressWithReferences caWithoutRefs(const ContentAddress &);
+
+struct StorePathDescriptor {
+ std::string name;
+ ContentAddressWithReferences info;
+
+ bool operator == (const StorePathDescriptor & other) const
+ {
+ return name == other.name;
+ // FIXME second field
+ }
+
+ bool operator < (const StorePathDescriptor & other) const
+ {
+ return name < other.name;
+ // FIXME second field
+ }
+};
+
}
diff --git a/src/libstore/derivations.cc b/src/libstore/derivations.cc
index 07b4e772b..925a78083 100644
--- a/src/libstore/derivations.cc
+++ b/src/libstore/derivations.cc
@@ -27,8 +27,8 @@ std::optional<StorePath> DerivationOutput::path(const Store & store, std::string
StorePath DerivationOutputCAFixed::path(const Store & store, std::string_view drvName, std::string_view outputName) const {
return store.makeFixedOutputPath(
- hash.method, hash.hash,
- outputPathName(drvName, outputName));
+ outputPathName(drvName, outputName),
+ { hash, {} });
}
diff --git a/src/libstore/derivations.hh b/src/libstore/derivations.hh
index d48266774..be19aa300 100644
--- a/src/libstore/derivations.hh
+++ b/src/libstore/derivations.hh
@@ -130,8 +130,8 @@ struct Derivation : BasicDerivation
/* Return the underlying basic derivation but with these changes:
- 1. Input drvs are emptied, but the outputs of them that were used are
- added directly to input sources.
+ 1. Input drvs are emptied, but the outputs of them that were used are
+ added directly to input sources.
2. Input placeholders are replaced with realized input store paths. */
std::optional<BasicDerivation> tryResolve(Store & store);
diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc
index 18545f659..e6b02cce6 100644
--- a/src/libstore/local-store.cc
+++ b/src/libstore/local-store.cc
@@ -567,7 +567,7 @@ void LocalStore::checkDerivationOutputs(const StorePath & drvPath, const Derivat
envHasRightPath(doia.path, i.first);
},
[&](DerivationOutputCAFixed dof) {
- StorePath path = makeFixedOutputPath(dof.hash.method, dof.hash.hash, drvName);
+ StorePath path = makeFixedOutputPath(drvName, { dof.hash, {} });
envHasRightPath(path, i.first);
},
[&](DerivationOutputCAFloating _) {
@@ -923,7 +923,10 @@ void LocalStore::querySubstitutablePathInfos(const StorePathCAMap & paths, Subst
// recompute store path so that we can use a different store root
if (path.second) {
- subPath = makeFixedOutputPathFromCA(path.first.name(), *path.second);
+ subPath = makeFixedOutputPathFromCA({
+ .name = std::string { path.first.name() },
+ .info = caWithoutRefs(*path.second),
+ });
if (sub->storeDir == storeDir)
assert(subPath == path.first);
if (subPath != path.first)
@@ -1164,7 +1167,18 @@ StorePath LocalStore::addToStoreFromDump(Source & source0, const string & name,
auto [hash, size] = hashSink->finish();
- auto dstPath = makeFixedOutputPath(method, hash, name);
+ auto desc = StorePathDescriptor {
+ name,
+ FixedOutputInfo {
+ {
+ .method = method,
+ .hash = hash,
+ },
+ {},
+ },
+ };
+
+ auto dstPath = makeFixedOutputPathFromCA(desc);
addTempRoot(dstPath);
@@ -1184,7 +1198,7 @@ StorePath LocalStore::addToStoreFromDump(Source & source0, const string & name,
autoGC();
if (inMemory) {
- StringSource dumpSource { dump };
+ StringSource dumpSource { dump };
/* Restore from the NAR in memory. */
if (method == FileIngestionMethod::Recursive)
restorePath(realPath, dumpSource);
@@ -1209,9 +1223,8 @@ StorePath LocalStore::addToStoreFromDump(Source & source0, const string & name,
optimisePath(realPath);
- ValidPathInfo info { dstPath, narHash.first };
+ ValidPathInfo info { *this, std::move(desc), narHash.first };
info.narSize = narHash.second;
- info.ca = FixedOutputHash { .method = method, .hash = hash };
registerValidPath(info);
}
@@ -1226,7 +1239,10 @@ StorePath LocalStore::addTextToStore(const string & name, const string & s,
const StorePathSet & references, RepairFlag repair)
{
auto hash = hashString(htSHA256, s);
- auto dstPath = makeTextPath(name, hash, references);
+ auto dstPath = makeTextPath(name, TextInfo {
+ { .hash = hash },
+ references,
+ });
addTempRoot(dstPath);
diff --git a/src/libstore/nar-info.hh b/src/libstore/nar-info.hh
index 39ced76e5..fd37b85db 100644
--- a/src/libstore/nar-info.hh
+++ b/src/libstore/nar-info.hh
@@ -17,6 +17,9 @@ struct NarInfo : ValidPathInfo
std::string system;
NarInfo() = delete;
+ NarInfo(const Store & store, StorePathDescriptor && ca, Hash narHash)
+ : ValidPathInfo(store, std::move(ca), narHash)
+ { }
NarInfo(StorePath && path, Hash narHash) : ValidPathInfo(std::move(path), narHash) { }
NarInfo(const ValidPathInfo & info) : ValidPathInfo(info) { }
NarInfo(const Store & store, const std::string & s, const std::string & whence);
diff --git a/src/libstore/path-info.hh b/src/libstore/path-info.hh
index 509f100d7..8c4791ac0 100644
--- a/src/libstore/path-info.hh
+++ b/src/libstore/path-info.hh
@@ -13,47 +13,6 @@ namespace nix {
class Store;
-template<typename Ref>
-struct PathReferences
-{
- std::set<Ref> references;
- bool hasSelfReference = false;
-
- /* Functions to view references + hasSelfReference as one set, mainly for
- compatibility's sake. */
- StorePathSet referencesPossiblyToSelf(const Ref & self) const;
- void insertReferencePossiblyToSelf(const Ref & self, Ref && ref);
- void setReferencesPossiblyToSelf(const Ref & self, std::set<Ref> && refs);
-};
-
-template<typename Ref>
-StorePathSet PathReferences<Ref>::referencesPossiblyToSelf(const Ref & self) const
-{
- StorePathSet refs { references };
- if (hasSelfReference)
- refs.insert(self);
- return refs;
-}
-
-template<typename Ref>
-void PathReferences<Ref>::insertReferencePossiblyToSelf(const Ref & self, Ref && ref)
-{
- if (ref == self)
- hasSelfReference = true;
- else
- references.insert(std::move(ref));
-}
-
-template<typename Ref>
-void PathReferences<Ref>::setReferencesPossiblyToSelf(const Ref & self, std::set<Ref> && refs)
-{
- if (refs.count(self))
- hasSelfReference = true;
- refs.erase(self);
-
- references = refs;
-}
-
struct SubstitutablePathInfo : PathReferences<StorePath>
{
@@ -68,7 +27,6 @@ struct ValidPathInfo : PathReferences<StorePath>
{
StorePath path;
std::optional<StorePath> deriver;
- // TODO document this
Hash narHash;
time_t registrationTime = 0;
uint64_t narSize = 0; // 0 = unknown
@@ -117,6 +75,8 @@ struct ValidPathInfo : PathReferences<StorePath>
void sign(const Store & store, const SecretKey & secretKey);
+ std::optional<StorePathDescriptor> fullStorePathDescriptorOpt() const;
+
/* Return true iff the path is verifiably content-addressed. */
bool isContentAddressed(const Store & store) const;
@@ -143,6 +103,9 @@ struct ValidPathInfo : PathReferences<StorePath>
ValidPathInfo(StorePath && path, Hash narHash) : path(std::move(path)), narHash(narHash) { };
ValidPathInfo(const StorePath & path, Hash narHash) : path(path), narHash(narHash) { };
+ ValidPathInfo(const Store & store,
+ StorePathDescriptor && ca, Hash narHash);
+
virtual ~ValidPathInfo() { }
};
diff --git a/src/libstore/path.hh b/src/libstore/path.hh
index b03a0f69d..5f239ceb6 100644
--- a/src/libstore/path.hh
+++ b/src/libstore/path.hh
@@ -1,6 +1,7 @@
#pragma once
-#include "content-address.hh"
+#include <string_view>
+
#include "types.hh"
namespace nix {
@@ -64,8 +65,6 @@ typedef std::set<StorePath> StorePathSet;
typedef std::vector<StorePath> StorePaths;
typedef std::map<string, StorePath> OutputPathMap;
-typedef std::map<StorePath, std::optional<ContentAddress>> StorePathCAMap;
-
/* Extension of derivations in the Nix store. */
const std::string drvExtension = ".drv";
diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc
index 7041edbe5..5d63b8e3c 100644
--- a/src/libstore/store-api.cc
+++ b/src/libstore/store-api.cc
@@ -7,6 +7,7 @@
#include "thread-pool.hh"
#include "json.hh"
#include "url.hh"
+#include "references.hh"
#include "archive.hh"
#include "callback.hh"
@@ -163,63 +164,61 @@ 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 `s' since that would be
+ ambiguous. */
static std::string makeType(
const Store & store,
string && type,
- const StorePathSet & references,
- bool hasSelfReference = false)
+ const PathReferences<StorePath> & references)
{
- for (auto & i : references) {
+ for (auto & i : references.references) {
type += ":";
type += store.printStorePath(i);
}
- if (hasSelfReference) type += ":self";
+ if (references.hasSelfReference) 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.type == htSHA256 && info.method == FileIngestionMethod::Recursive) {
+ return makeStorePath(makeType(*this, "source", info.references), info.hash, name);
} else {
- assert(references.empty());
+ assert(info.references.references.size() == 0);
+ assert(!info.references.hasSelfReference);
return makeStorePath("output:out",
hashString(htSHA256,
"fixed:out:"
- + makeFileIngestionPrefix(method)
- + hash.to_string(Base16, true) + ":"),
+ + makeFileIngestionPrefix(info.method)
+ + info.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.type == htSHA256);
+ return makeStorePath(
+ makeType(*this, "text", PathReferences<StorePath> { info.references }),
+ info.hash,
+ name);
+}
+
+
+StorePath Store::makeFixedOutputPathFromCA(const StorePathDescriptor & desc) const
{
// New template
return std::visit(overloaded {
- [&](TextHash th) {
- return makeTextPath(name, th.hash, references);
+ [&](TextInfo ti) {
+ return makeTextPath(desc.name, ti);
},
- [&](FixedOutputHash fsh) {
- return makeFixedOutputPath(fsh.method, fsh.hash, name, references, hasSelfReference);
+ [&](FixedOutputInfo foi) {
+ return makeFixedOutputPath(desc.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);
+ }, desc.info);
}
@@ -229,14 +228,24 @@ 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 {
+ {
+ .method = method,
+ .hash = h,
+ },
+ {},
+ };
+ return std::make_pair(makeFixedOutputPath(name, caInfo), h);
}
StorePath Store::computeStorePathForText(const string & name, const string & s,
const StorePathSet & references) const
{
- return makeTextPath(name, hashString(htSHA256, s), references);
+ return makeTextPath(name, TextInfo {
+ { .hash = hashString(htSHA256, s) },
+ references,
+ });
}
@@ -326,11 +335,20 @@ ValidPathInfo Store::addToStoreSlow(std::string_view name, const Path & srcPath,
throw Error("hash mismatch for '%s'", srcPath);
ValidPathInfo info {
- makeFixedOutputPath(method, hash, name),
+ *this,
+ StorePathDescriptor {
+ std::string { name },
+ FixedOutputInfo {
+ {
+ .method = method,
+ .hash = hash,
+ },
+ {},
+ },
+ },
narHash,
};
info.narSize = narSize;
- info.ca = FixedOutputHash { .method = method, .hash = hash };
if (!isValidPath(info.path)) {
auto source = sinkToSource([&](Sink & scratchpadSink) {
@@ -496,7 +514,7 @@ void Store::queryPathInfo(const StorePath & storePath,
auto callbackPtr = std::make_shared<decltype(callback)>(std::move(callback));
queryPathInfoUncached(storePath,
- {[this, storePathS{printStorePath(storePath)}, hashPart, callbackPtr](std::future<std::shared_ptr<const ValidPathInfo>> fut) {
+ {[this, storePath, hashPart, callbackPtr](std::future<std::shared_ptr<const ValidPathInfo>> fut) {
try {
auto info = fut.get();
@@ -509,11 +527,9 @@ void Store::queryPathInfo(const StorePath & storePath,
state_->pathInfoCache.upsert(hashPart, PathInfoCacheValue { .value = info });
}
- auto storePath = parseStorePath(storePathS);
-
if (!info || !goodStorePath(storePath, info->path)) {
stats.narInfoMissing++;
- throw InvalidPath("path '%s' is not valid", storePathS);
+ throw InvalidPath("path '%s' is not valid", printStorePath(storePath));
}
(*callbackPtr)(ref<const ValidPathInfo>(info));
@@ -536,13 +552,13 @@ StorePathSet Store::queryValidPaths(const StorePathSet & paths, SubstituteFlag m
std::condition_variable wakeup;
ThreadPool pool;
- auto doQuery = [&](const Path & path) {
+ auto doQuery = [&](const StorePath & path) {
checkInterrupt();
- queryPathInfo(parseStorePath(path), {[path, this, &state_, &wakeup](std::future<ref<const ValidPathInfo>> fut) {
+ queryPathInfo(path, {[path, this, &state_, &wakeup](std::future<ref<const ValidPathInfo>> fut) {
auto state(state_.lock());
try {
auto info = fut.get();
- state->valid.insert(parseStorePath(path));
+ state->valid.insert(path);
} catch (InvalidPath &) {
} catch (...) {
state->exc = std::current_exception();
@@ -554,7 +570,7 @@ StorePathSet Store::queryValidPaths(const StorePathSet & paths, SubstituteFlag m
};
for (auto & path : paths)
- pool.enqueue(std::bind(doQuery, printStorePath(path))); // FIXME
+ pool.enqueue(std::bind(doQuery, path));
pool.process();
@@ -737,7 +753,8 @@ void copyStorePath(ref<Store> srcStore, ref<Store> dstStore,
// 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->fullStorePathDescriptorOpt().value());
if (dstStore->storeDir == srcStore->storeDir)
assert(info->path == info2->path);
info = info2;
@@ -799,7 +816,8 @@ std::map<StorePath, StorePath> copyPaths(ref<Store> srcStore, ref<Store> dstStor
auto info = srcStore->queryPathInfo(storePath);
auto storePathForDst = storePath;
if (info->ca && info->references.empty()) {
- storePathForDst = dstStore->makeFixedOutputPathFromCA(storePath.name(), *info->ca);
+ storePathForDst = dstStore->makeFixedOutputPathFromCA(
+ info->fullStorePathDescriptorOpt().value());
if (dstStore->storeDir == srcStore->storeDir)
assert(storePathForDst == storePath);
if (storePathForDst != storePath)
@@ -826,7 +844,8 @@ std::map<StorePath, StorePath> copyPaths(ref<Store> srcStore, ref<Store> dstStor
auto storePathForDst = storePath;
if (info->ca && info->references.empty()) {
- storePathForDst = dstStore->makeFixedOutputPathFromCA(storePath.name(), *info->ca);
+ storePathForDst = dstStore->makeFixedOutputPathFromCA(
+ info->fullStorePathDescriptorOpt().value());
if (dstStore->storeDir == srcStore->storeDir)
assert(storePathForDst == storePath);
if (storePathForDst != storePath)
@@ -947,19 +966,37 @@ void ValidPathInfo::sign(const Store & store, const SecretKey & secretKey)
sigs.insert(secretKey.signDetached(fingerprint(store)));
}
+std::optional<StorePathDescriptor> ValidPathInfo::fullStorePathDescriptorOpt() const
+{
+ if (! ca)
+ return std::nullopt;
+
+ return StorePathDescriptor {
+ .name = std::string { path.name() },
+ .info = std::visit(overloaded {
+ [&](TextHash th) {
+ TextInfo info { th };
+ assert(!hasSelfReference);
+ info.references = references;
+ return ContentAddressWithReferences { info };
+ },
+ [&](FixedOutputHash foh) {
+ FixedOutputInfo info { foh };
+ info.references = static_cast<PathReferences<StorePath>>(*this);
+ return ContentAddressWithReferences { info };
+ },
+ }, *ca),
+ };
+}
+
bool ValidPathInfo::isContentAddressed(const Store & store) const
{
- if (! ca) return false;
+ auto fullCaOpt = fullStorePathDescriptorOpt();
- auto caPath = std::visit(overloaded {
- [&](TextHash th) {
- assert(!hasSelfReference);
- return store.makeTextPath(path.name(), th.hash, references);
- },
- [&](FixedOutputHash fsh) {
- return store.makeFixedOutputPath(fsh.method, fsh.hash, path.name(), references, hasSelfReference);
- }
- }, *ca);
+ if (! fullCaOpt)
+ return false;
+
+ auto caPath = store.makeFixedOutputPathFromCA(*fullCaOpt);
bool res = caPath == path;
@@ -997,6 +1034,26 @@ Strings ValidPathInfo::shortRefs() const
}
+ValidPathInfo::ValidPathInfo(
+ const Store & store,
+ StorePathDescriptor && info,
+ Hash narHash)
+ : path(store.makeFixedOutputPathFromCA(info))
+ , narHash(narHash)
+{
+ std::visit(overloaded {
+ [this](TextInfo ti) {
+ this->references = ti.references;
+ this->ca = TextHash { std::move(ti) };
+ },
+ [this](FixedOutputInfo foi) {
+ *(static_cast<PathReferences<StorePath> *>(this)) = foi.references;
+ this->ca = FixedOutputHash { (FixedOutputHash) std::move(foi) };
+ },
+ }, std::move(info.info));
+}
+
+
Derivation Store::derivationFromPath(const StorePath & drvPath)
{
ensurePath(drvPath);
diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh
index 854446987..e6a6053a3 100644
--- a/src/libstore/store-api.hh
+++ b/src/libstore/store-api.hh
@@ -170,6 +170,8 @@ struct BuildResult
}
};
+typedef std::map<StorePath, std::optional<ContentAddress>> StorePathCAMap;
+
struct StoreConfig : public Config
{
using Config::Config;
@@ -313,17 +315,11 @@ public:
StorePath makeOutputPath(std::string_view id,
const Hash & hash, std::string_view name) const;
- StorePath makeFixedOutputPath(FileIngestionMethod method,
- const Hash & hash, std::string_view name,
- const StorePathSet & references = {},
- bool hasSelfReference = false) const;
+ StorePath makeFixedOutputPath(std::string_view name, const FixedOutputInfo & info) const;
- StorePath makeTextPath(std::string_view name, const Hash & hash,
- const StorePathSet & references = {}) const;
+ StorePath makeTextPath(std::string_view name, const TextInfo & info) const;
- StorePath makeFixedOutputPathFromCA(std::string_view name, ContentAddress ca,
- const StorePathSet & references = {},
- bool hasSelfReference = false) const;
+ StorePath makeFixedOutputPathFromCA(const StorePathDescriptor & info) const;
/* This is the preparatory part of addToStore(); it computes the
store path to which srcPath is to be copied. Returns the store