Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split out VisibleStore and ReferrersStore from Store #8213

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion perl/lib/Nix/CopyClosure.pm
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ sub copyToOpen {
$useSubstitutes = 0 if $dryRun || !defined $useSubstitutes;

# Get the closure of this path.
my @closure = reverse(topoSortPaths(computeFSClosure(0, $includeOutputs,
my @closure = reverse(topoSortPaths(computeFSClosure($includeOutputs,
map { followLinksToStorePath $_ } @{$storePaths})));

# Send the "query valid paths" command with the "lock" option
Expand Down
4 changes: 2 additions & 2 deletions perl/lib/Nix/Store.xs
Original file line number Diff line number Diff line change
Expand Up @@ -144,12 +144,12 @@ SV * queryPathFromHashPart(char * hashPart)
}


SV * computeFSClosure(int flipDirection, int includeOutputs, ...)
SV * computeFSClosure(int includeOutputs, ...)
PPCODE:
try {
StorePathSet paths;
for (int n = 2; n < items; ++n)
store()->computeFSClosure(store()->parseStorePath(SvPV_nolen(ST(n))), paths, flipDirection, includeOutputs);
store()->computeFSClosure(store()->parseStorePath(SvPV_nolen(ST(n))), paths, includeOutputs);
for (auto & i : paths)
XPUSHs(sv_2mortal(newSVpv(store()->printStorePath(i).c_str(), 0)));
} catch (Error & e) {
Expand Down
5 changes: 4 additions & 1 deletion src/libcmd/command.cc
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#include "command.hh"
#include "markdown.hh"
#include "store-api.hh"
#include "store-cast.hh"
#include "local-fs-store.hh"
#include "visible-store.hh"
#include "derivations.hh"
#include "nixexpr.hh"
#include "profiles.hh"
Expand Down Expand Up @@ -185,10 +187,11 @@ void BuiltPathsCommand::run(ref<Store> store, Installables && installables)
{
BuiltPaths paths;
if (all) {
auto & visibleStore = require<VisibleStore>(*store);
if (installables.size())
throw UsageError("'--all' does not expect arguments");
// XXX: Only uses opaque paths, ignores all the realisations
for (auto & p : store->queryAllValidPaths())
for (auto & p : visibleStore.queryAllValidPaths())
paths.emplace_back(BuiltPath::Opaque{p});
} else {
paths = Installable::toBuiltPaths(getEvalStore(), store, realiseMode, operateOn, installables);
Expand Down
14 changes: 10 additions & 4 deletions src/libstore/build/local-derivation-goal.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1224,10 +1224,16 @@ struct RestrictedStoreConfig : virtual LocalFSStoreConfig
const std::string name() { return "Restricted Store"; }
};

/* A wrapper around LocalStore that only allows building/querying of
paths that are in the input closures of the build or were added via
recursive Nix calls. */
struct RestrictedStore : public virtual RestrictedStoreConfig, public virtual IndirectRootStore, public virtual GcStore
/**
* A wrapper around `LocalStore` that only allows building/querying of
* paths that are in the input closures of the build or were added via
* recursive Nix calls.
*/
struct RestrictedStore
: public virtual RestrictedStoreConfig
, public virtual IndirectRootStore
, public virtual GcStore
, public virtual ReferrersStore
{
ref<LocalStore> next;

Expand Down
11 changes: 7 additions & 4 deletions src/libstore/daemon.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "gc-store.hh"
#include "log-store.hh"
#include "indirect-root-store.hh"
#include "referrers-store.hh"
#include "path-with-outputs.hh"
#include "finally.hh"
#include "archive.hh"
Expand Down Expand Up @@ -342,9 +343,10 @@ static void performOp(TunnelLogger * logger, ref<Store> store,
if (op == WorkerProto::Op::QueryReferences)
for (auto & i : store->queryPathInfo(path)->references)
paths.insert(i);
else if (op == WorkerProto::Op::QueryReferrers)
store->queryReferrers(path, paths);
else if (op == WorkerProto::Op::QueryValidDerivers)
else if (op == WorkerProto::Op::QueryReferrers) {
auto & referrersStore = require<ReferrersStore>(*store);
referrersStore.queryReferrers(path, paths);
} else if (op == WorkerProto::Op::QueryValidDerivers)
paths = store->queryValidDerivers(path);
else paths = store->queryDerivationOutputs(path);
logger->stopWork();
Expand Down Expand Up @@ -814,7 +816,8 @@ static void performOp(TunnelLogger * logger, ref<Store> store,

case WorkerProto::Op::QueryAllValidPaths: {
logger->startWork();
auto paths = store->queryAllValidPaths();
auto & visibleStore = require<VisibleStore>(*store);
auto paths = visibleStore.queryAllValidPaths();
logger->stopWork();
WorkerProto::write(*store, wconn, paths);
break;
Expand Down
2 changes: 1 addition & 1 deletion src/libstore/gc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -710,7 +710,7 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
try {
StorePathSet closure;
computeFSClosure(*path, closure,
/* flipDirection */ false, gcKeepOutputs, gcKeepDerivations);
gcKeepOutputs, gcKeepDerivations);
for (auto & p : closure)
alive.insert(p);
} catch (InvalidPath &) { }
Expand Down
6 changes: 3 additions & 3 deletions src/libstore/legacy-ssh-store.cc
Original file line number Diff line number Diff line change
Expand Up @@ -303,11 +303,11 @@ void LegacySSHStore::buildPaths(const std::vector<DerivedPath> & drvPaths, Build


void LegacySSHStore::computeFSClosure(const StorePathSet & paths,
StorePathSet & out, bool flipDirection,
StorePathSet & out,
bool includeOutputs, bool includeDerivers)
{
if (flipDirection || includeDerivers) {
Store::computeFSClosure(paths, out, flipDirection, includeOutputs, includeDerivers);
if (includeDerivers) {
Store::computeFSClosure(paths, out, includeOutputs, includeDerivers);
return;
}

Expand Down
2 changes: 1 addition & 1 deletion src/libstore/legacy-ssh-store.hh
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ public:
{ unsupported("repairPath"); }

void computeFSClosure(const StorePathSet & paths,
StorePathSet & out, bool flipDirection = false,
StorePathSet & out,
bool includeOutputs = false, bool includeDerivers = false) override;

StorePathSet queryValidPaths(const StorePathSet & paths,
Expand Down
3 changes: 2 additions & 1 deletion src/libstore/local-binary-cache-store.cc
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "binary-cache-store.hh"
#include "visible-store.hh"
#include "globals.hh"
#include "nar-info-disk-cache.hh"

Expand All @@ -20,7 +21,7 @@ struct LocalBinaryCacheStoreConfig : virtual BinaryCacheStoreConfig
}
};

class LocalBinaryCacheStore : public virtual LocalBinaryCacheStoreConfig, public virtual BinaryCacheStore
class LocalBinaryCacheStore : public virtual LocalBinaryCacheStoreConfig, public virtual BinaryCacheStore, public virtual VisibleStore
{
private:

Expand Down
2 changes: 2 additions & 0 deletions src/libstore/local-store.hh
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "pathlocks.hh"
#include "store-api.hh"
#include "indirect-root-store.hh"
#include "referrers-store.hh"
#include "sync.hh"

#include <chrono>
Expand Down Expand Up @@ -69,6 +70,7 @@ struct LocalStoreConfig : virtual LocalFSStoreConfig
class LocalStore : public virtual LocalStoreConfig
, public virtual IndirectRootStore
, public virtual GcStore
, public virtual ReferrersStore
{
private:

Expand Down
118 changes: 72 additions & 46 deletions src/libstore/misc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#include "globals.hh"
#include "local-store.hh"
#include "store-api.hh"
#include "referrers-store.hh"
#include "store-cast.hh"
#include "thread-pool.hh"
#include "realisation.hh"
#include "topo-sort.hh"
Expand All @@ -12,52 +14,18 @@

namespace nix {

void Store::computeFSClosure(const StorePathSet & startPaths,
StorePathSet & paths_, bool flipDirection, bool includeOutputs, bool includeDerivers)
{
std::function<std::set<StorePath>(const StorePath & path, std::future<ref<const ValidPathInfo>> &)> queryDeps;
if (flipDirection)
queryDeps = [&](const StorePath& path,
std::future<ref<const ValidPathInfo>> & fut) {
StorePathSet res;
StorePathSet referrers;
queryReferrers(path, referrers);
for (auto& ref : referrers)
if (ref != path)
res.insert(ref);

if (includeOutputs)
for (auto& i : queryValidDerivers(path))
res.insert(i);

if (includeDerivers && path.isDerivation())
for (auto& [_, maybeOutPath] : queryPartialDerivationOutputMap(path))
if (maybeOutPath && isValidPath(*maybeOutPath))
res.insert(*maybeOutPath);
return res;
};
else
queryDeps = [&](const StorePath& path,
std::future<ref<const ValidPathInfo>> & fut) {
StorePathSet res;
auto info = fut.get();
for (auto& ref : info->references)
if (ref != path)
res.insert(ref);

if (includeOutputs && path.isDerivation())
for (auto& [_, maybeOutPath] : queryPartialDerivationOutputMap(path))
if (maybeOutPath && isValidPath(*maybeOutPath))
res.insert(*maybeOutPath);

if (includeDerivers && info->deriver && isValidPath(*info->deriver))
res.insert(*info->deriver);
return res;
};
typedef std::set<StorePath> QueryDeps(const StorePath & path, std::future<ref<const ValidPathInfo>> &);

static void computeClosure(
Store & store,
std::function<QueryDeps> queryDeps,
const StorePathSet & startPaths,
StorePathSet & paths_,
bool includeOutputs, bool includeDerivers)
{
computeClosure<StorePath>(
startPaths, paths_,
[&](const StorePath& path,
[&](const StorePath & path,
std::function<void(std::promise<std::set<StorePath>>&)>
processEdges) {
std::promise<std::set<StorePath>> promise;
Expand All @@ -70,17 +38,75 @@ void Store::computeFSClosure(const StorePathSet & startPaths,
promise.set_exception(std::current_exception());
}
};
queryPathInfo(path, getDependencies);
store.queryPathInfo(path, getDependencies);
processEdges(promise);
});
}

void ReferrersStore::computeFSCoClosure(const StorePathSet & startPaths,
StorePathSet & paths_, bool includeOutputs, bool includeDerivers)
{
std::function<QueryDeps> queryDeps;
queryDeps = [&](const StorePath & path,
std::future<ref<const ValidPathInfo>> & fut) {
StorePathSet res;
StorePathSet referrers;
queryReferrers(path, referrers);
for (auto& ref : referrers)
if (ref != path)
res.insert(ref);

if (includeOutputs)
for (auto& i : queryValidDerivers(path))
res.insert(i);

if (includeDerivers && path.isDerivation())
for (auto& [_, maybeOutPath] : queryPartialDerivationOutputMap(path))
if (maybeOutPath && isValidPath(*maybeOutPath))
res.insert(*maybeOutPath);
return res;
};
computeClosure(*this, queryDeps, startPaths, paths_, includeOutputs, includeDerivers);
}

void Store::computeFSClosure(const StorePathSet & startPaths,
StorePathSet & paths_, bool includeOutputs, bool includeDerivers)
{
std::function<QueryDeps> queryDeps;
queryDeps = [&](const StorePath& path,
std::future<ref<const ValidPathInfo>> & fut) {
StorePathSet res;
auto info = fut.get();
for (auto& ref : info->references)
if (ref != path)
res.insert(ref);

if (includeOutputs && path.isDerivation())
for (auto& [_, maybeOutPath] : queryPartialDerivationOutputMap(path))
if (maybeOutPath && isValidPath(*maybeOutPath))
res.insert(*maybeOutPath);

if (includeDerivers && info->deriver && isValidPath(*info->deriver))
res.insert(*info->deriver);
return res;
};
computeClosure(*this, queryDeps, startPaths, paths_, includeOutputs, includeDerivers);
}

void ReferrersStore::computeFSCoClosure(const StorePath & startPath,
StorePathSet & paths_, bool includeOutputs, bool includeDerivers)
{
StorePathSet paths;
paths.insert(startPath);
computeFSCoClosure(paths, paths_, includeOutputs, includeDerivers);
}

void Store::computeFSClosure(const StorePath & startPath,
StorePathSet & paths_, bool flipDirection, bool includeOutputs, bool includeDerivers)
StorePathSet & paths_, bool includeOutputs, bool includeDerivers)
{
StorePathSet paths;
paths.insert(startPath);
computeFSClosure(paths, paths_, flipDirection, includeOutputs, includeDerivers);
computeFSClosure(paths, paths_, includeOutputs, includeDerivers);
}


Expand Down
56 changes: 56 additions & 0 deletions src/libstore/referrers-store.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#pragma once
///@file

#include "visible-store.hh"

namespace nix {

/**
* A store that allows querying referrers.
*
* The referrers relation is the dual of the references relation, the
* latter being the "regular" one we are usually interested in.
*
* This is no inherent reason why this should be a subclass of
* `VisibleStore`; it just so happens that every extent store object we
* have to day that implements `queryReferrers()` also implements
* `queryAllValidPaths()`. If that ceases to be the case, we can revisit
* this; until this having this interface inheritance means fewer
* interface combinations to think about.
*/
struct ReferrersStore : virtual VisibleStore
{
inline static std::string operationName = "Query referrers";

/**
* Queries the set of incoming FS references for a store path.
* The result is not cleared.
*
* @param path The path of the store object we care about incoming
* references to.
*
* @param [out] referrers The set in which to collect the referrers
* of `path`.
*/
virtual void queryReferrers(const StorePath & path, StorePathSet & referrers) = 0;

/**
* @param [out] out Place in here the set of all store paths in the
* file system co-closure of `storePath`; that is, all paths than
* directly or indirectly refer from it. `out` is not cleared.
*
* Whereas `Store::computeFSClosure` uses the `references` relation,
* this function uses the dual of it which is the `referrers`
* relation.
*/
virtual void computeFSCoClosure(const StorePathSet & paths,
StorePathSet & out,
bool includeOutputs = false, bool includeDerivers = false);

void computeFSCoClosure(const StorePath & path,
StorePathSet & out,
bool includeOutputs = false, bool includeDerivers = false);

};

}
5 changes: 4 additions & 1 deletion src/libstore/remote-store.hh
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "store-api.hh"
#include "gc-store.hh"
#include "log-store.hh"
#include "referrers-store.hh"


namespace nix {
Expand Down Expand Up @@ -38,7 +39,9 @@ struct RemoteStoreConfig : virtual StoreConfig
class RemoteStore : public virtual RemoteStoreConfig,
public virtual Store,
public virtual GcStore,
public virtual LogStore
public virtual LogStore,
public virtual ReferrersStore

{
public:

Expand Down
Loading
Loading