1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-16 07:22:43 +01:00

refactor(libutil): add CompressedSource

Introduce a `CompressedSource` class in libutil's `serialise.hh` that
compresses a `RestartableSource` and owns the compressed data. This is a
general-purpose utility that can be used anywhere compressed data needs
to be treated as a source.
This commit is contained in:
Bernardo Meurer Costa 2025-10-30 01:19:44 +00:00
parent bffbdcfddc
commit 93fe3354b5
No known key found for this signature in database
3 changed files with 61 additions and 9 deletions

View file

@ -272,6 +272,50 @@ struct StringSource : RestartableSource
}
};
/**
* Compresses a RestartableSource using the specified compression method.
*
* @note currently this buffers the entire compressed data stream in memory. In the future it may instead compress data
* on demand, lazily pulling from the original `RestartableSource`. In that case, the `size()` method would go away
* because we would not in fact know the compressed size in advance.
*/
struct CompressedSource : RestartableSource
{
private:
std::string compressedData;
std::string compressionMethod;
StringSource stringSource;
public:
/**
* Compress a RestartableSource using the specified compression method.
*
* @param source The source data to compress
* @param compressionMethod The compression method to use (e.g., "xz", "br")
*/
CompressedSource(RestartableSource & source, const std::string & compressionMethod);
size_t read(char * data, size_t len) override
{
return stringSource.read(data, len);
}
void restart() override
{
stringSource.restart();
}
uint64_t size() const
{
return compressedData.size();
}
std::string_view getCompressionMethod() const
{
return compressionMethod;
}
};
/**
* Create a restartable Source from a factory function.
*

View file

@ -1,4 +1,5 @@
#include "nix/util/serialise.hh"
#include "nix/util/compression.hh"
#include "nix/util/signals.hh"
#include "nix/util/util.hh"
@ -252,6 +253,19 @@ void StringSource::skip(size_t len)
pos += len;
}
CompressedSource::CompressedSource(RestartableSource & source, const std::string & compressionMethod)
: compressedData([&]() {
StringSink sink;
auto compressionSink = makeCompressionSink(compressionMethod, sink);
source.drainInto(*compressionSink);
compressionSink->finish();
return std::move(sink.s);
}())
, compressionMethod(compressionMethod)
, stringSource(compressedData)
{
}
std::unique_ptr<FinishSink> sourceToSink(std::function<void(Source &)> fun)
{
struct SourceToSink : FinishSink