* More remote operations.
* Added new operation hasSubstitutes(), which is more efficient than querySubstitutes().size() > 0.
This commit is contained in:
parent
aac547a8b3
commit
0565b5f2b3
12 changed files with 138 additions and 46 deletions
|
@ -660,7 +660,7 @@ void DerivationGoal::haveStoreExpr()
|
||||||
i != invalidOutputs.end(); ++i)
|
i != invalidOutputs.end(); ++i)
|
||||||
/* Don't bother creating a substitution goal if there are no
|
/* Don't bother creating a substitution goal if there are no
|
||||||
substitutes. */
|
substitutes. */
|
||||||
if (store->querySubstitutes(*i).size() > 0)
|
if (store->hasSubstitutes(*i))
|
||||||
addWaitee(worker.makeSubstitutionGoal(*i));
|
addWaitee(worker.makeSubstitutionGoal(*i));
|
||||||
|
|
||||||
if (waitees.empty()) /* to prevent hang (no wake-up event) */
|
if (waitees.empty()) /* to prevent hang (no wake-up event) */
|
||||||
|
|
|
@ -481,15 +481,15 @@ void registerSubstitute(const Transaction & txn,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Substitutes querySubstitutes(const Transaction & txn, const Path & srcPath)
|
Substitutes querySubstitutes(const Transaction & txn, const Path & path)
|
||||||
{
|
{
|
||||||
return readSubstitutes(txn, srcPath);
|
return readSubstitutes(txn, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Substitutes LocalStore::querySubstitutes(const Path & srcPath)
|
Substitutes LocalStore::querySubstitutes(const Path & path)
|
||||||
{
|
{
|
||||||
return nix::querySubstitutes(noTxn, srcPath);
|
return nix::querySubstitutes(noTxn, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,7 @@ void queryMissing(const PathSet & targets,
|
||||||
for (DerivationOutputs::iterator i = drv.outputs.begin();
|
for (DerivationOutputs::iterator i = drv.outputs.begin();
|
||||||
i != drv.outputs.end(); ++i)
|
i != drv.outputs.end(); ++i)
|
||||||
if (!store->isValidPath(i->second.path) &&
|
if (!store->isValidPath(i->second.path) &&
|
||||||
store->querySubstitutes(i->second.path).size() == 0)
|
!store->hasSubstitutes(i->second.path))
|
||||||
mustBuild = true;
|
mustBuild = true;
|
||||||
|
|
||||||
if (mustBuild) {
|
if (mustBuild) {
|
||||||
|
@ -81,7 +81,7 @@ void queryMissing(const PathSet & targets,
|
||||||
|
|
||||||
else {
|
else {
|
||||||
if (store->isValidPath(p)) continue;
|
if (store->isValidPath(p)) continue;
|
||||||
if (store->querySubstitutes(p).size() > 0)
|
if (store->hasSubstitutes(p))
|
||||||
willSubstitute.insert(p);
|
willSubstitute.insert(p);
|
||||||
PathSet refs;
|
PathSet refs;
|
||||||
store->queryReferences(p, todo);
|
store->queryReferences(p, todo);
|
||||||
|
|
|
@ -39,7 +39,7 @@ RemoteStore::RemoteStore()
|
||||||
throw SysError("dupping read side");
|
throw SysError("dupping read side");
|
||||||
|
|
||||||
execlp(worker.c_str(), worker.c_str(),
|
execlp(worker.c_str(), worker.c_str(),
|
||||||
"-vvv", "--slave", NULL);
|
"--slave", NULL);
|
||||||
|
|
||||||
throw SysError(format("executing `%1%'") % worker);
|
throw SysError(format("executing `%1%'") % worker);
|
||||||
|
|
||||||
|
@ -81,32 +81,44 @@ bool RemoteStore::isValidPath(const Path & path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Substitutes RemoteStore::querySubstitutes(const Path & srcPath)
|
Substitutes RemoteStore::querySubstitutes(const Path & path)
|
||||||
{
|
{
|
||||||
// writeInt(wopQuerySubstitutes);
|
throw Error("not implemented 2");
|
||||||
|
}
|
||||||
// throw Error("not implemented 2");
|
|
||||||
return Substitutes();
|
|
||||||
|
bool RemoteStore::hasSubstitutes(const Path & path)
|
||||||
|
{
|
||||||
|
writeInt(wopHasSubstitutes, to);
|
||||||
|
writeString(path, to);
|
||||||
|
unsigned int reply = readInt(from);
|
||||||
|
return reply != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Hash RemoteStore::queryPathHash(const Path & path)
|
Hash RemoteStore::queryPathHash(const Path & path)
|
||||||
{
|
{
|
||||||
throw Error("not implemented");
|
throw Error("not implemented 3");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RemoteStore::queryReferences(const Path & storePath,
|
void RemoteStore::queryReferences(const Path & path,
|
||||||
PathSet & references)
|
PathSet & references)
|
||||||
{
|
{
|
||||||
throw Error("not implemented");
|
writeInt(wopQueryReferences, to);
|
||||||
|
writeString(path, to);
|
||||||
|
PathSet references2 = readStringSet(from);
|
||||||
|
references.insert(references2.begin(), references2.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RemoteStore::queryReferrers(const Path & storePath,
|
void RemoteStore::queryReferrers(const Path & path,
|
||||||
PathSet & referrers)
|
PathSet & referrers)
|
||||||
{
|
{
|
||||||
throw Error("not implemented");
|
writeInt(wopQueryReferrers, to);
|
||||||
|
writeString(path, to);
|
||||||
|
PathSet referrers2 = readStringSet(from);
|
||||||
|
referrers.insert(referrers2.begin(), referrers2.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -123,7 +135,7 @@ Path RemoteStore::addToStore(const Path & srcPath)
|
||||||
Path RemoteStore::addToStoreFixed(bool recursive, string hashAlgo,
|
Path RemoteStore::addToStoreFixed(bool recursive, string hashAlgo,
|
||||||
const Path & srcPath)
|
const Path & srcPath)
|
||||||
{
|
{
|
||||||
throw Error("not implemented 4");
|
throw Error("not implemented 6");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -133,9 +145,7 @@ Path RemoteStore::addTextToStore(const string & suffix, const string & s,
|
||||||
writeInt(wopAddTextToStore, to);
|
writeInt(wopAddTextToStore, to);
|
||||||
writeString(suffix, to);
|
writeString(suffix, to);
|
||||||
writeString(s, to);
|
writeString(s, to);
|
||||||
writeInt(references.size(), to);
|
writeStringSet(references, to);
|
||||||
for (PathSet::iterator i = references.begin(); i != references.end(); ++i)
|
|
||||||
writeString(*i, to);
|
|
||||||
|
|
||||||
Path path = readString(from);
|
Path path = readString(from);
|
||||||
return path;
|
return path;
|
||||||
|
@ -144,13 +154,17 @@ Path RemoteStore::addTextToStore(const string & suffix, const string & s,
|
||||||
|
|
||||||
void RemoteStore::buildDerivations(const PathSet & drvPaths)
|
void RemoteStore::buildDerivations(const PathSet & drvPaths)
|
||||||
{
|
{
|
||||||
throw Error("not implemented 6");
|
writeInt(wopBuildDerivations, to);
|
||||||
|
writeStringSet(drvPaths, to);
|
||||||
|
readInt(from);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RemoteStore::ensurePath(const Path & storePath)
|
void RemoteStore::ensurePath(const Path & path)
|
||||||
{
|
{
|
||||||
throw Error("not implemented 7");
|
writeInt(wopEnsurePath, to);
|
||||||
|
writeString(path, to);
|
||||||
|
readInt(from);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -27,15 +27,15 @@ public:
|
||||||
|
|
||||||
bool isValidPath(const Path & path);
|
bool isValidPath(const Path & path);
|
||||||
|
|
||||||
Substitutes querySubstitutes(const Path & srcPath);
|
Substitutes querySubstitutes(const Path & path);
|
||||||
|
|
||||||
|
bool hasSubstitutes(const Path & path);
|
||||||
|
|
||||||
Hash queryPathHash(const Path & path);
|
Hash queryPathHash(const Path & path);
|
||||||
|
|
||||||
void queryReferences(const Path & storePath,
|
void queryReferences(const Path & path, PathSet & references);
|
||||||
PathSet & references);
|
|
||||||
|
|
||||||
void queryReferrers(const Path & storePath,
|
void queryReferrers(const Path & path, PathSet & referrers);
|
||||||
PathSet & referrers);
|
|
||||||
|
|
||||||
Path addToStore(const Path & srcPath);
|
Path addToStore(const Path & srcPath);
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ public:
|
||||||
|
|
||||||
void buildDerivations(const PathSet & drvPaths);
|
void buildDerivations(const PathSet & drvPaths);
|
||||||
|
|
||||||
void ensurePath(const Path & storePath);
|
void ensurePath(const Path & path);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Pipe toChild;
|
Pipe toChild;
|
||||||
|
|
|
@ -6,6 +6,12 @@
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
|
||||||
|
bool StoreAPI::hasSubstitutes(const Path & path)
|
||||||
|
{
|
||||||
|
return !querySubstitutes(path).empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool isInStore(const Path & path)
|
bool isInStore(const Path & path)
|
||||||
{
|
{
|
||||||
return path[0] == '/'
|
return path[0] == '/'
|
||||||
|
|
|
@ -43,7 +43,11 @@ public:
|
||||||
virtual bool isValidPath(const Path & path) = 0;
|
virtual bool isValidPath(const Path & path) = 0;
|
||||||
|
|
||||||
/* Return the substitutes for the given path. */
|
/* Return the substitutes for the given path. */
|
||||||
virtual Substitutes querySubstitutes(const Path & srcPath) = 0;
|
virtual Substitutes querySubstitutes(const Path & path) = 0;
|
||||||
|
|
||||||
|
/* More efficient variant if we just want to know if a path has
|
||||||
|
substitutes. */
|
||||||
|
virtual bool hasSubstitutes(const Path & path);
|
||||||
|
|
||||||
/* Queries the hash of a valid path. */
|
/* Queries the hash of a valid path. */
|
||||||
virtual Hash queryPathHash(const Path & path) = 0;
|
virtual Hash queryPathHash(const Path & path) = 0;
|
||||||
|
@ -121,7 +125,6 @@ extern boost::shared_ptr<StoreAPI> store;
|
||||||
boost::shared_ptr<StoreAPI> openStore(bool reserveSpace = true);
|
boost::shared_ptr<StoreAPI> openStore(bool reserveSpace = true);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,15 @@ typedef enum {
|
||||||
wopQuit,
|
wopQuit,
|
||||||
wopIsValidPath,
|
wopIsValidPath,
|
||||||
wopQuerySubstitutes,
|
wopQuerySubstitutes,
|
||||||
|
wopHasSubstitutes,
|
||||||
|
wopQueryPathHash,
|
||||||
|
wopQueryReferences,
|
||||||
|
wopQueryReferrers,
|
||||||
wopAddToStore,
|
wopAddToStore,
|
||||||
|
wopAddToStoreFixed,
|
||||||
wopAddTextToStore,
|
wopAddTextToStore,
|
||||||
|
wopBuildDerivations,
|
||||||
|
wopEnsurePath,
|
||||||
} WorkerOp;
|
} WorkerOp;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,14 @@ void writeString(const string & s, Sink & sink)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void writeStringSet(const StringSet & ss, Sink & sink)
|
||||||
|
{
|
||||||
|
writeInt(ss.size(), sink);
|
||||||
|
for (StringSet::iterator i = ss.begin(); i != ss.end(); ++i)
|
||||||
|
writeString(*i, sink);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void readPadding(unsigned int len, Source & source)
|
void readPadding(unsigned int len, Source & source)
|
||||||
{
|
{
|
||||||
if (len % 8) {
|
if (len % 8) {
|
||||||
|
@ -84,4 +92,14 @@ string readString(Source & source)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
StringSet readStringSet(Source & source)
|
||||||
|
{
|
||||||
|
unsigned int count = readInt(source);
|
||||||
|
StringSet ss;
|
||||||
|
while (count--)
|
||||||
|
ss.insert(readString(source));
|
||||||
|
return ss;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,12 +69,14 @@ struct FdSource : Source
|
||||||
void writePadding(unsigned int len, Sink & sink);
|
void writePadding(unsigned int len, Sink & sink);
|
||||||
void writeInt(unsigned int n, Sink & sink);
|
void writeInt(unsigned int n, Sink & sink);
|
||||||
void writeString(const string & s, Sink & sink);
|
void writeString(const string & s, Sink & sink);
|
||||||
|
void writeStringSet(const StringSet & ss, Sink & sink);
|
||||||
|
|
||||||
void readPadding(unsigned int len, Source & source);
|
void readPadding(unsigned int len, Source & source);
|
||||||
unsigned int readInt(Source & source);
|
unsigned int readInt(Source & source);
|
||||||
string readString(Source & source);
|
string readString(Source & source);
|
||||||
|
StringSet readStringSet(Source & source);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -832,18 +832,18 @@ static void opQuery(Globals & globals,
|
||||||
XMLAttrs attrs;
|
XMLAttrs attrs;
|
||||||
|
|
||||||
if (printStatus) {
|
if (printStatus) {
|
||||||
Substitutes subs = store->querySubstitutes(i->queryOutPath(globals.state));
|
bool hasSubs = store->hasSubstitutes(i->queryOutPath(globals.state));
|
||||||
bool isInstalled = installed.find(i->queryOutPath(globals.state)) != installed.end();
|
bool isInstalled = installed.find(i->queryOutPath(globals.state)) != installed.end();
|
||||||
bool isValid = store->isValidPath(i->queryOutPath(globals.state));
|
bool isValid = store->isValidPath(i->queryOutPath(globals.state));
|
||||||
if (xmlOutput) {
|
if (xmlOutput) {
|
||||||
attrs["installed"] = isInstalled ? "1" : "0";
|
attrs["installed"] = isInstalled ? "1" : "0";
|
||||||
attrs["valid"] = isValid ? "1" : "0";
|
attrs["valid"] = isValid ? "1" : "0";
|
||||||
attrs["substitutable"] = !subs.empty() ? "1" : "0";
|
attrs["substitutable"] = hasSubs ? "1" : "0";
|
||||||
} else
|
} else
|
||||||
columns.push_back(
|
columns.push_back(
|
||||||
(string) (isInstalled ? "I" : "-")
|
(string) (isInstalled ? "I" : "-")
|
||||||
+ (isValid ? "P" : "-")
|
+ (isValid ? "P" : "-")
|
||||||
+ (!subs.empty() ? "S" : "-"));
|
+ (hasSubs ? "S" : "-"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xmlOutput)
|
if (xmlOutput)
|
||||||
|
|
|
@ -8,6 +8,23 @@
|
||||||
using namespace nix;
|
using namespace nix;
|
||||||
|
|
||||||
|
|
||||||
|
Path readStorePath(Source & from)
|
||||||
|
{
|
||||||
|
Path path = readString(from);
|
||||||
|
assertStorePath(path);
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PathSet readStorePaths(Source & from)
|
||||||
|
{
|
||||||
|
PathSet paths = readStringSet(from);
|
||||||
|
for (PathSet::iterator i = paths.begin(); i != paths.end(); ++i)
|
||||||
|
assertStorePath(*i);
|
||||||
|
return paths;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void processConnection(Source & from, Sink & to)
|
void processConnection(Source & from, Sink & to)
|
||||||
{
|
{
|
||||||
store = boost::shared_ptr<StoreAPI>(new LocalStore(true));
|
store = boost::shared_ptr<StoreAPI>(new LocalStore(true));
|
||||||
|
@ -35,12 +52,29 @@ void processConnection(Source & from, Sink & to)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case wopIsValidPath: {
|
case wopIsValidPath: {
|
||||||
Path path = readString(from);
|
Path path = readStorePath(from);
|
||||||
assertStorePath(path);
|
|
||||||
writeInt(store->isValidPath(path), to);
|
writeInt(store->isValidPath(path), to);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case wopHasSubstitutes: {
|
||||||
|
Path path = readStorePath(from);
|
||||||
|
writeInt(store->hasSubstitutes(path), to);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case wopQueryReferences:
|
||||||
|
case wopQueryReferrers: {
|
||||||
|
Path path = readStorePath(from);
|
||||||
|
PathSet paths;
|
||||||
|
if (op == wopQueryReferences)
|
||||||
|
store->queryReferences(path, paths);
|
||||||
|
else
|
||||||
|
store->queryReferrers(path, paths);
|
||||||
|
writeStringSet(paths, to);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case wopAddToStore: {
|
case wopAddToStore: {
|
||||||
/* !!! uberquick hack */
|
/* !!! uberquick hack */
|
||||||
string baseName = readString(from);
|
string baseName = readString(from);
|
||||||
|
@ -55,17 +89,25 @@ void processConnection(Source & from, Sink & to)
|
||||||
case wopAddTextToStore: {
|
case wopAddTextToStore: {
|
||||||
string suffix = readString(from);
|
string suffix = readString(from);
|
||||||
string s = readString(from);
|
string s = readString(from);
|
||||||
unsigned int refCount = readInt(from);
|
PathSet refs = readStorePaths(from);
|
||||||
PathSet refs;
|
|
||||||
while (refCount--) {
|
|
||||||
Path ref = readString(from);
|
|
||||||
assertStorePath(ref);
|
|
||||||
refs.insert(ref);
|
|
||||||
}
|
|
||||||
writeString(store->addTextToStore(suffix, s, refs), to);
|
writeString(store->addTextToStore(suffix, s, refs), to);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case wopBuildDerivations: {
|
||||||
|
PathSet drvs = readStorePaths(from);
|
||||||
|
store->buildDerivations(drvs);
|
||||||
|
writeInt(1, to);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case wopEnsurePath: {
|
||||||
|
Path path = readStorePath(from);
|
||||||
|
store->ensurePath(path);
|
||||||
|
writeInt(1, to);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw Error(format("invalid operation %1%") % op);
|
throw Error(format("invalid operation %1%") % op);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue