Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 03acfdbe authored by Daniel Zheng's avatar Daniel Zheng
Browse files

Optimize zstd compression

reuse the same context for zstd compression. One context should be used
per compression thread for optimal performance. Discussion and
reccomendations can be found at go/android-hw-compression-vendor

Results (level 3 compression)
full ota on raven with optimizations:  1191.304 seconds
without optimizations:  1461.854 seconds

compression ratio remains unchanged and merge time difference are
negligible ~1% delta (probably just noise)

Test: ota_from_target_files, update_device.py
Change-Id: I3feede9f1f119874e369c54b29c594475fbf7376
parent de6e446e
Loading
Loading
Loading
Loading
+12 −2
Original line number Original line Diff line number Diff line
@@ -18,6 +18,7 @@
#include <unistd.h>
#include <unistd.h>


#include <limits>
#include <limits>
#include <memory>
#include <queue>
#include <queue>


#include <android-base/file.h>
#include <android-base/file.h>
@@ -174,12 +175,18 @@ class BrotliCompressor final : public ICompressor {


class ZstdCompressor final : public ICompressor {
class ZstdCompressor final : public ICompressor {
  public:
  public:
    ZstdCompressor(uint32_t compression_level) : ICompressor(compression_level){};
    ZstdCompressor(uint32_t compression_level)
        : ICompressor(compression_level), zstd_context_(ZSTD_createCCtx(), ZSTD_freeCCtx) {
        ZSTD_CCtx_setParameter(zstd_context_.get(), ZSTD_c_compressionLevel, compression_level);
        // FIXME: hardcoding a value of 12 here for 4k blocks, should change to be either set by
        // user, or optimized depending on block size
        ZSTD_CCtx_setParameter(zstd_context_.get(), ZSTD_c_windowLog, 12);
    };


    std::basic_string<uint8_t> Compress(const void* data, size_t length) const override {
    std::basic_string<uint8_t> Compress(const void* data, size_t length) const override {
        std::basic_string<uint8_t> buffer(ZSTD_compressBound(length), '\0');
        std::basic_string<uint8_t> buffer(ZSTD_compressBound(length), '\0');
        const auto compressed_size =
        const auto compressed_size =
                ZSTD_compress(buffer.data(), buffer.size(), data, length, GetCompressionLevel());
                ZSTD_compress2(zstd_context_.get(), buffer.data(), buffer.size(), data, length);
        if (compressed_size <= 0) {
        if (compressed_size <= 0) {
            LOG(ERROR) << "ZSTD compression failed " << compressed_size;
            LOG(ERROR) << "ZSTD compression failed " << compressed_size;
            return {};
            return {};
@@ -193,6 +200,9 @@ class ZstdCompressor final : public ICompressor {
        }
        }
        return buffer;
        return buffer;
    };
    };

  private:
    std::unique_ptr<ZSTD_CCtx, decltype(&ZSTD_freeCCtx)> zstd_context_;
};
};


bool CompressWorker::CompressBlocks(const void* buffer, size_t num_blocks,
bool CompressWorker::CompressBlocks(const void* buffer, size_t num_blocks,