* 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,10 +69,12 @@ 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…
	
	Add table
		Add a link
		
	
		Reference in a new issue