* More remote operations.

* Added new operation hasSubstitutes(), which is more efficient than
  querySubstitutes().size() > 0.
This commit is contained in:
Eelco Dolstra 2006-11-30 22:43:55 +00:00
parent aac547a8b3
commit 0565b5f2b3
12 changed files with 138 additions and 46 deletions

View file

@ -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) */

View file

@ -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);
} }

View file

@ -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);

View file

@ -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);
} }

View file

@ -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;

View file

@ -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] == '/'

View file

@ -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);
} }

View file

@ -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;

View file

@ -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;
}
} }

View file

@ -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);
} }

View file

@ -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)

View file

@ -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);
} }