1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-07-09 12:03:55 +02:00

queryMissing(): Return a struct

...instead of having a bunch of pass-by-reference arguments.
This commit is contained in:
Eelco Dolstra 2025-07-04 15:39:47 +02:00
parent d4f67fd46d
commit af05ce0f6d
11 changed files with 59 additions and 79 deletions

View file

@ -46,10 +46,8 @@ void printGCWarning()
void printMissing(ref<Store> store, const std::vector<DerivedPath> & paths, Verbosity lvl) void printMissing(ref<Store> store, const std::vector<DerivedPath> & paths, Verbosity lvl)
{ {
uint64_t downloadSize, narSize; auto missing = store->queryMissing(paths);
StorePathSet willBuild, willSubstitute, unknown; printMissing(store, missing.willBuild, missing.willSubstitute, missing.unknown, missing.downloadSize, missing.narSize, lvl);
store->queryMissing(paths, willBuild, willSubstitute, unknown, downloadSize, narSize);
printMissing(store, willBuild, willSubstitute, unknown, downloadSize, narSize, lvl);
} }

View file

@ -324,9 +324,7 @@ void Worker::run(const Goals & _topGoals)
} }
/* Call queryMissing() to efficiently query substitutes. */ /* Call queryMissing() to efficiently query substitutes. */
StorePathSet willBuild, willSubstitute, unknown; store.queryMissing(topPaths);
uint64_t downloadSize, narSize;
store.queryMissing(topPaths, willBuild, willSubstitute, unknown, downloadSize, narSize);
debug("entered goal loop"); debug("entered goal loop");

View file

@ -948,14 +948,12 @@ static void performOp(TunnelLogger * logger, ref<Store> store,
case WorkerProto::Op::QueryMissing: { case WorkerProto::Op::QueryMissing: {
auto targets = WorkerProto::Serialise<DerivedPaths>::read(*store, rconn); auto targets = WorkerProto::Serialise<DerivedPaths>::read(*store, rconn);
logger->startWork(); logger->startWork();
StorePathSet willBuild, willSubstitute, unknown; auto missing = store->queryMissing(targets);
uint64_t downloadSize, narSize;
store->queryMissing(targets, willBuild, willSubstitute, unknown, downloadSize, narSize);
logger->stopWork(); logger->stopWork();
WorkerProto::write(*store, wconn, willBuild); WorkerProto::write(*store, wconn, missing.willBuild);
WorkerProto::write(*store, wconn, willSubstitute); WorkerProto::write(*store, wconn, missing.willSubstitute);
WorkerProto::write(*store, wconn, unknown); WorkerProto::write(*store, wconn, missing.unknown);
conn.to << downloadSize << narSize; conn.to << missing.downloadSize << missing.narSize;
break; break;
} }

View file

@ -149,9 +149,7 @@ struct RemoteStore :
void addSignatures(const StorePath & storePath, const StringSet & sigs) override; void addSignatures(const StorePath & storePath, const StringSet & sigs) override;
void queryMissing(const std::vector<DerivedPath> & targets, MissingPaths queryMissing(const std::vector<DerivedPath> & targets) override;
StorePathSet & willBuild, StorePathSet & willSubstitute, StorePathSet & unknown,
uint64_t & downloadSize, uint64_t & narSize) override;
void addBuildLog(const StorePath & drvPath, std::string_view log) override; void addBuildLog(const StorePath & drvPath, std::string_view log) override;

View file

@ -71,6 +71,18 @@ struct KeyedBuildResult;
typedef std::map<StorePath, std::optional<ContentAddress>> StorePathCAMap; typedef std::map<StorePath, std::optional<ContentAddress>> StorePathCAMap;
/**
* Information about what paths will be built or substituted, returned
* by Store::queryMissing().
*/
struct MissingPaths
{
StorePathSet willBuild;
StorePathSet willSubstitute;
StorePathSet unknown;
uint64_t downloadSize{0};
uint64_t narSize{0};
};
/** /**
* About the class hierarchy of the store types: * About the class hierarchy of the store types:
@ -694,9 +706,7 @@ public:
* derivations that will be built, and the set of output paths that * derivations that will be built, and the set of output paths that
* will be substituted. * will be substituted.
*/ */
virtual void queryMissing(const std::vector<DerivedPath> & targets, virtual MissingPaths queryMissing(const std::vector<DerivedPath> & targets);
StorePathSet & willBuild, StorePathSet & willSubstitute, StorePathSet & unknown,
uint64_t & downloadSize, uint64_t & narSize);
/** /**
* Sort a set of paths topologically under the references * Sort a set of paths topologically under the references

View file

@ -98,23 +98,17 @@ const ContentAddress * getDerivationCA(const BasicDerivation & drv)
return nullptr; return nullptr;
} }
void Store::queryMissing(const std::vector<DerivedPath> & targets, MissingPaths Store::queryMissing(const std::vector<DerivedPath> & targets)
StorePathSet & willBuild_, StorePathSet & willSubstitute_, StorePathSet & unknown_,
uint64_t & downloadSize_, uint64_t & narSize_)
{ {
Activity act(*logger, lvlDebug, actUnknown, "querying info about missing paths"); Activity act(*logger, lvlDebug, actUnknown, "querying info about missing paths");
downloadSize_ = narSize_ = 0;
// FIXME: make async. // FIXME: make async.
ThreadPool pool(fileTransferSettings.httpConnections); ThreadPool pool(fileTransferSettings.httpConnections);
struct State struct State
{ {
std::unordered_set<std::string> done; std::unordered_set<std::string> done;
StorePathSet & unknown, & willSubstitute, & willBuild; MissingPaths res;
uint64_t & downloadSize;
uint64_t & narSize;
}; };
struct DrvState struct DrvState
@ -125,7 +119,7 @@ void Store::queryMissing(const std::vector<DerivedPath> & targets,
DrvState(size_t left) : left(left) { } DrvState(size_t left) : left(left) { }
}; };
Sync<State> state_(State{{}, unknown_, willSubstitute_, willBuild_, downloadSize_, narSize_}); Sync<State> state_;
std::function<void(DerivedPath)> doPath; std::function<void(DerivedPath)> doPath;
@ -143,7 +137,7 @@ void Store::queryMissing(const std::vector<DerivedPath> & targets,
auto mustBuildDrv = [&](const StorePath & drvPath, const Derivation & drv) { auto mustBuildDrv = [&](const StorePath & drvPath, const Derivation & drv) {
{ {
auto state(state_.lock()); auto state(state_.lock());
state->willBuild.insert(drvPath); state->res.willBuild.insert(drvPath);
} }
for (const auto & [inputDrv, inputNode] : drv.inputDrvs.map) { for (const auto & [inputDrv, inputNode] : drv.inputDrvs.map) {
@ -203,7 +197,7 @@ void Store::queryMissing(const std::vector<DerivedPath> & targets,
if (!isValidPath(drvPath)) { if (!isValidPath(drvPath)) {
// FIXME: we could try to substitute the derivation. // FIXME: we could try to substitute the derivation.
auto state(state_.lock()); auto state(state_.lock());
state->unknown.insert(drvPath); state->res.unknown.insert(drvPath);
return; return;
} }
@ -282,7 +276,7 @@ void Store::queryMissing(const std::vector<DerivedPath> & targets,
if (infos.empty()) { if (infos.empty()) {
auto state(state_.lock()); auto state(state_.lock());
state->unknown.insert(bo.path); state->res.unknown.insert(bo.path);
return; return;
} }
@ -291,9 +285,9 @@ void Store::queryMissing(const std::vector<DerivedPath> & targets,
{ {
auto state(state_.lock()); auto state(state_.lock());
state->willSubstitute.insert(bo.path); state->res.willSubstitute.insert(bo.path);
state->downloadSize += info->second.downloadSize; state->res.downloadSize += info->second.downloadSize;
state->narSize += info->second.narSize; state->res.narSize += info->second.narSize;
} }
for (auto & ref : info->second.references) for (auto & ref : info->second.references)
@ -306,6 +300,8 @@ void Store::queryMissing(const std::vector<DerivedPath> & targets,
pool.enqueue(std::bind(doPath, path)); pool.enqueue(std::bind(doPath, path));
pool.process(); pool.process();
return std::move(state_.lock()->res);
} }

View file

@ -855,9 +855,7 @@ void RemoteStore::addSignatures(const StorePath & storePath, const StringSet & s
} }
void RemoteStore::queryMissing(const std::vector<DerivedPath> & targets, MissingPaths RemoteStore::queryMissing(const std::vector<DerivedPath> & targets)
StorePathSet & willBuild, StorePathSet & willSubstitute, StorePathSet & unknown,
uint64_t & downloadSize, uint64_t & narSize)
{ {
{ {
auto conn(getConnection()); auto conn(getConnection());
@ -868,16 +866,16 @@ void RemoteStore::queryMissing(const std::vector<DerivedPath> & targets,
conn->to << WorkerProto::Op::QueryMissing; conn->to << WorkerProto::Op::QueryMissing;
WorkerProto::write(*this, *conn, targets); WorkerProto::write(*this, *conn, targets);
conn.processStderr(); conn.processStderr();
willBuild = WorkerProto::Serialise<StorePathSet>::read(*this, *conn); MissingPaths res;
willSubstitute = WorkerProto::Serialise<StorePathSet>::read(*this, *conn); res.willBuild = WorkerProto::Serialise<StorePathSet>::read(*this, *conn);
unknown = WorkerProto::Serialise<StorePathSet>::read(*this, *conn); res.willSubstitute = WorkerProto::Serialise<StorePathSet>::read(*this, *conn);
conn->from >> downloadSize >> narSize; res.unknown = WorkerProto::Serialise<StorePathSet>::read(*this, *conn);
return; conn->from >> res.downloadSize >> res.narSize;
return res;
} }
fallback: fallback:
return Store::queryMissing(targets, willBuild, willSubstitute, return Store::queryMissing(targets);
unknown, downloadSize, narSize);
} }

View file

@ -143,13 +143,7 @@ struct RestrictedStore : public virtual IndirectRootStore, public virtual GcStor
unsupported("addSignatures"); unsupported("addSignatures");
} }
void queryMissing( MissingPaths queryMissing(const std::vector<DerivedPath> & targets) override;
const std::vector<DerivedPath> & targets,
StorePathSet & willBuild,
StorePathSet & willSubstitute,
StorePathSet & unknown,
uint64_t & downloadSize,
uint64_t & narSize) override;
virtual std::optional<std::string> getBuildLogExact(const StorePath & path) override virtual std::optional<std::string> getBuildLogExact(const StorePath & path) override
{ {
@ -306,19 +300,14 @@ std::vector<KeyedBuildResult> RestrictedStore::buildPathsWithResults(
return results; return results;
} }
void RestrictedStore::queryMissing( MissingPaths RestrictedStore::queryMissing(const std::vector<DerivedPath> & targets)
const std::vector<DerivedPath> & targets,
StorePathSet & willBuild,
StorePathSet & willSubstitute,
StorePathSet & unknown,
uint64_t & downloadSize,
uint64_t & narSize)
{ {
/* This is slightly impure since it leaks information to the /* This is slightly impure since it leaks information to the
client about what paths will be built/substituted or are client about what paths will be built/substituted or are
already present. Probably not a big deal. */ already present. Probably not a big deal. */
std::vector<DerivedPath> allowed; std::vector<DerivedPath> allowed;
StorePathSet unknown;
for (auto & req : targets) { for (auto & req : targets) {
if (goal.isAllowed(req)) if (goal.isAllowed(req))
allowed.emplace_back(req); allowed.emplace_back(req);
@ -326,7 +315,12 @@ void RestrictedStore::queryMissing(
unknown.insert(pathPartOfReq(req)); unknown.insert(pathPartOfReq(req));
} }
next->queryMissing(allowed, willBuild, willSubstitute, unknown, downloadSize, narSize); auto res = next->queryMissing(allowed);
for (auto & p : unknown)
res.unknown.insert(p);
return res;
} }
} }

View file

@ -790,15 +790,12 @@ void Store::substitutePaths(const StorePathSet & paths)
for (auto & path : paths) for (auto & path : paths)
if (!path.isDerivation()) if (!path.isDerivation())
paths2.emplace_back(DerivedPath::Opaque{path}); paths2.emplace_back(DerivedPath::Opaque{path});
uint64_t downloadSize, narSize; auto missing = queryMissing(paths2);
StorePathSet willBuild, willSubstitute, unknown;
queryMissing(paths2,
willBuild, willSubstitute, unknown, downloadSize, narSize);
if (!willSubstitute.empty()) if (!missing.willSubstitute.empty())
try { try {
std::vector<DerivedPath> subs; std::vector<DerivedPath> subs;
for (auto & p : willSubstitute) subs.emplace_back(DerivedPath::Opaque{p}); for (auto & p : missing.willSubstitute) subs.emplace_back(DerivedPath::Opaque{p});
buildPaths(subs); buildPaths(subs);
} catch (Error & e) { } catch (Error & e) {
logWarning(e.info()); logWarning(e.info());

View file

@ -422,13 +422,10 @@ static void main_nix_build(int argc, char * * argv)
auto buildPaths = [&](const std::vector<DerivedPath> & paths) { auto buildPaths = [&](const std::vector<DerivedPath> & paths) {
/* Note: we do this even when !printMissing to efficiently /* Note: we do this even when !printMissing to efficiently
fetch binary cache data. */ fetch binary cache data. */
uint64_t downloadSize, narSize; auto missing = store->queryMissing(paths);
StorePathSet willBuild, willSubstitute, unknown;
store->queryMissing(paths,
willBuild, willSubstitute, unknown, downloadSize, narSize);
if (settings.printMissing) if (settings.printMissing)
printMissing(ref<Store>(store), willBuild, willSubstitute, unknown, downloadSize, narSize); printMissing(ref<Store>(store), missing.willBuild, missing.willSubstitute, missing.unknown, missing.downloadSize, missing.narSize);
if (!dryRun) if (!dryRun)
store->buildPaths(paths, buildMode, evalStore); store->buildPaths(paths, buildMode, evalStore);

View file

@ -146,23 +146,19 @@ static void opRealise(Strings opFlags, Strings opArgs)
for (auto & i : opArgs) for (auto & i : opArgs)
paths.push_back(followLinksToStorePathWithOutputs(*store, i)); paths.push_back(followLinksToStorePathWithOutputs(*store, i));
uint64_t downloadSize, narSize; auto missing = store->queryMissing(toDerivedPaths(paths));
StorePathSet willBuild, willSubstitute, unknown;
store->queryMissing(
toDerivedPaths(paths),
willBuild, willSubstitute, unknown, downloadSize, narSize);
/* Filter out unknown paths from `paths`. */ /* Filter out unknown paths from `paths`. */
if (ignoreUnknown) { if (ignoreUnknown) {
std::vector<StorePathWithOutputs> paths2; std::vector<StorePathWithOutputs> paths2;
for (auto & i : paths) for (auto & i : paths)
if (!unknown.count(i.path)) paths2.push_back(i); if (!missing.unknown.count(i.path)) paths2.push_back(i);
paths = std::move(paths2); paths = std::move(paths2);
unknown = StorePathSet(); missing.unknown = StorePathSet();
} }
if (settings.printMissing) if (settings.printMissing)
printMissing(ref<Store>(store), willBuild, willSubstitute, unknown, downloadSize, narSize); printMissing(ref<Store>(store), missing.willBuild, missing.willSubstitute, missing.unknown, missing.downloadSize, missing.narSize);
if (dryRun) return; if (dryRun) return;