libutil: convert readFile to generator

Change-Id: I5f92b15fd367d46eb047d74ab6e317b4f51a46d3
This commit is contained in:
eldritch horrors 2024-03-24 00:44:57 +01:00
parent 98d9dcb221
commit bb253a95cb
12 changed files with 38 additions and 27 deletions

View file

@ -416,7 +416,7 @@ StorePath BinaryCacheStore::addToStore(
if (method == FileIngestionMethod::Recursive) { if (method == FileIngestionMethod::Recursive) {
sink << dumpPath(srcPath, filter); sink << dumpPath(srcPath, filter);
} else { } else {
readFile(srcPath, sink); sink << readFileSource(srcPath);
} }
auto h = sink.finish().first; auto h = sink.finish().first;

View file

@ -2454,7 +2454,7 @@ SingleDrvOutputs LocalDerivationGoal::registerOutputs()
HashModuloSink caSink { outputHash.hashType, oldHashPart }; HashModuloSink caSink { outputHash.hashType, oldHashPart };
std::visit(overloaded { std::visit(overloaded {
[&](const TextIngestionMethod &) { [&](const TextIngestionMethod &) {
readFile(actualPath, caSink); caSink << readFileSource(actualPath);
}, },
[&](const FileIngestionMethod & m2) { [&](const FileIngestionMethod & m2) {
switch (m2) { switch (m2) {
@ -2462,7 +2462,7 @@ SingleDrvOutputs LocalDerivationGoal::registerOutputs()
caSink << dumpPath(actualPath); caSink << dumpPath(actualPath);
break; break;
case FileIngestionMethod::Flat: case FileIngestionMethod::Flat:
readFile(actualPath, caSink); caSink << readFileSource(actualPath);
break; break;
} }
}, },

View file

@ -71,7 +71,7 @@ protected:
void getFile(const std::string & path, Sink & sink) override void getFile(const std::string & path, Sink & sink) override
{ {
try { try {
readFile(binaryCacheDir + "/" + path, sink); sink << readFileSource(binaryCacheDir + "/" + path);
} catch (SysError & e) { } catch (SysError & e) {
if (e.errNo == ENOENT) if (e.errNo == ENOENT)
throw NoSuchBinaryCacheFile("file '%s' does not exist in binary cache", path); throw NoSuchBinaryCacheFile("file '%s' does not exist in binary cache", path);

View file

@ -1886,7 +1886,7 @@ ContentAddress LocalStore::hashCAPath(
HashModuloSink caSink ( hashType, std::string(pathHash) ); HashModuloSink caSink ( hashType, std::string(pathHash) );
std::visit(overloaded { std::visit(overloaded {
[&](const TextIngestionMethod &) { [&](const TextIngestionMethod &) {
readFile(path, caSink); caSink << readFileSource(path);
}, },
[&](const FileIngestionMethod & m2) { [&](const FileIngestionMethod & m2) {
switch (m2) { switch (m2) {
@ -1894,7 +1894,7 @@ ContentAddress LocalStore::hashCAPath(
caSink << dumpPath(path); caSink << dumpPath(path);
break; break;
case FileIngestionMethod::Flat: case FileIngestionMethod::Flat:
readFile(path, caSink); caSink << readFileSource(path);
break; break;
} }
}, },

View file

@ -271,13 +271,12 @@ StorePath Store::addToStore(
const StorePathSet & references) const StorePathSet & references)
{ {
Path srcPath(absPath(_srcPath)); Path srcPath(absPath(_srcPath));
auto source = sinkToSource([&](Sink & sink) { auto source = WireSource{
if (method == FileIngestionMethod::Recursive) method == FileIngestionMethod::Recursive
sink << dumpPath(srcPath, filter); ? static_cast<Generator<std::span<const char>, void>>(dumpPath(srcPath, filter))
else : readFileSource(srcPath)
readFile(srcPath, sink); };
}); return addToStoreFromDump(source, name, method, hashAlgo, repair, references);
return addToStoreFromDump(*source, name, method, hashAlgo, repair, references);
} }
void Store::addMultipleToStore( void Store::addMultipleToStore(

View file

@ -10,29 +10,40 @@
namespace nix { namespace nix {
template<typename T, typename Transform = std::identity> template<typename T, typename Transform = std::identity>
struct Generator : private Generator<T, void> struct Generator
{ {
struct promise_type; struct promise_type;
using handle_type = std::coroutine_handle<promise_type>; using handle_type = std::coroutine_handle<promise_type>;
explicit Generator(handle_type h) : Generator<T, void>{h, h.promise().state} {} explicit Generator(handle_type h) : impl{h, h.promise().state} {}
using Generator<T, void>::operator bool; explicit operator bool()
using Generator<T, void>::operator(); {
return bool(impl);
}
T operator()()
{
return impl();
}
operator Generator<T, void> &() & operator Generator<T, void> &() &
{ {
return *this; return impl;
} }
operator Generator<T, void>() && operator Generator<T, void>() &&
{ {
return std::move(*this); return std::move(impl);
} }
private:
Generator<T, void> impl;
}; };
template<typename T> template<typename T>
struct Generator<T, void> struct Generator<T, void>
{ {
template<typename, typename>
friend struct Generator;
template<typename T2, typename Transform> template<typename T2, typename Transform>
friend struct Generator<T2, Transform>::promise_type; friend struct Generator<T2, Transform>::promise_type;

View file

@ -325,7 +325,7 @@ Hash hashString(HashType ht, std::string_view s)
Hash hashFile(HashType ht, const Path & path) Hash hashFile(HashType ht, const Path & path)
{ {
HashSink sink(ht); HashSink sink(ht);
readFile(path, sink); sink << readFileSource(path);
return sink.finish().first; return sink.finish().first;
} }

View file

@ -388,7 +388,8 @@ void drainGenerator(Generator<std::span<const char>, T> g, std::derived_from<Sin
struct WireSource : Source struct WireSource : Source
{ {
WireSource(WireFormatGenerator && g) : g(std::move(g)) {} template<typename F>
explicit WireSource(Generator<std::span<const char>, F> g) : g(std::move(g)) {}
virtual size_t read(char * data, size_t len) virtual size_t read(char * data, size_t len)
{ {
@ -406,7 +407,7 @@ struct WireSource : Source
} }
private: private:
WireFormatGenerator g; Generator<std::span<const char>, void> g;
std::span<const char> buf{}; std::span<const char> buf{};
}; };

View file

@ -366,12 +366,12 @@ std::string readFile(const Path & path)
} }
void readFile(const Path & path, Sink & sink) Generator<std::span<const char>> readFileSource(const Path & path)
{ {
AutoCloseFD fd{open(path.c_str(), O_RDONLY | O_CLOEXEC)}; AutoCloseFD fd{open(path.c_str(), O_RDONLY | O_CLOEXEC)};
if (!fd) if (!fd)
throw SysError("opening file '%s'", path); throw SysError("opening file '%s'", path);
drainGenerator(drainFDSource(fd.get()), sink); co_yield drainFDSource(fd.get());
} }

View file

@ -163,7 +163,7 @@ unsigned char getFileType(const Path & path);
*/ */
std::string readFile(int fd); std::string readFile(int fd);
std::string readFile(const Path & path); std::string readFile(const Path & path);
void readFile(const Path & path, Sink & sink); Generator<std::span<const char>> readFileSource(const Path & path);
/** /**
* Write a string to a file. * Write a string to a file.

View file

@ -37,7 +37,7 @@ struct CmdAddToStore : MixDryRun, StoreCommand
Hash hash = narHash; Hash hash = narHash;
if (ingestionMethod == FileIngestionMethod::Flat) { if (ingestionMethod == FileIngestionMethod::Flat) {
HashSink hsink(htSHA256); HashSink hsink(htSHA256);
readFile(path, hsink); hsink << readFileSource(path);
hash = hsink.finish().first; hash = hsink.finish().first;
} }

View file

@ -85,7 +85,7 @@ struct CmdHashBase : Command
switch (mode) { switch (mode) {
case FileIngestionMethod::Flat: case FileIngestionMethod::Flat:
readFile(path, *hashSink); *hashSink << readFileSource(path);
break; break;
case FileIngestionMethod::Recursive: case FileIngestionMethod::Recursive:
*hashSink << dumpPath(path); *hashSink << dumpPath(path);