Repository: apache/arrow
File: cpp/src/arrow/util/compression_zstd.cc (C++)

Code before:
  }

  Result<std::shared_ptr<Decompressor>> MakeDecompressor() override {
    ARROW_ASSIGN_OR_RAISE(auto dctx, createDCtx());
    return std::make_shared<ZSTDDecompressor>(std::move(dctx));
  }

  Compression::type compression_type() const override { return Compression::ZSTD; }
  int minimum_compression_level() const override { return ZSTD_minCLevel(); }
  int maximum_compression_level() const override { return ZSTD_maxCLevel(); }
  int default_compression_level() const override { return kZSTDDefaultCompressionLevel; }

  int compression_level() const override { return compression_level_; }

 private:
  Result<CCtxPtr> createCCtx() const {
    auto cctx = ZSTD_createCCtx();
    auto ret = ZSTD_CCtx_setParameter(cctx, ZSTD_c_compressionLevel, compression_level_);
    if (ZSTD_isError(ret)) {
      return ZSTDError(ret, "ZSTD_CCtx create failed: ");
    }
    for (auto& [key, value] : cctx_params_) {
      ret = ZSTD_CCtx_setParameter(cctx, static_cast<ZSTD_cParameter>(key), value);
      if (ZSTD_isError(ret)) {
        return ZSTDError(ret, "ZSTD_CCtx create failed: ");
      }
    }
    return {{cctx, ZSTD_freeCCtx}};
  }

  Result<DCtxPtr> createDCtx() const {
    auto dctx = ZSTD_createDCtx();
    for (auto& [key, value] : dctx_params_) {
      auto ret = ZSTD_DCtx_setParameter(dctx, static_cast<ZSTD_dParameter>(key), value);
      if (ZSTD_isError(ret)) {
        return ZSTDError(ret, "ZSTD_DCtx create failed: ");
      }
    }
    return {{dctx, ZSTD_freeDCtx}};
  }

  const int compression_level_;
  const std::unordered_map<int, int> cctx_params_;
  const std::unordered_map<int, int> dctx_params_;
};

}  // namespace

std::unique_ptr<Codec> MakeZSTDCodec(int compression_level,
                                     std::unordered_map<int, int> cctx_params,
                                     std::unordered_map<int, int> dctx_params) {

Review comment (suggestion):
This will leak the cctx on error, you should create the `std::unique_ptr` before this.

Code after:
    ARROW_ASSIGN_OR_RAISE(auto cctx, CreateCCtx());
    return std::make_shared<ZSTDCompressor>(std::move(cctx));
  }

  Result<std::shared_ptr<Decompressor>> MakeDecompressor() override {
    ARROW_ASSIGN_OR_RAISE(auto dctx, CreateDCtx());
    return std::make_shared<ZSTDDecompressor>(std::move(dctx));
  }

  Compression::type compression_type() const override { return Compression::ZSTD; }
  int minimum_compression_level() const override { return ZSTD_minCLevel(); }
  int maximum_compression_level() const override { return ZSTD_maxCLevel(); }
  int default_compression_level() const override { return kZSTDDefaultCompressionLevel; }

  int compression_level() const override { return compression_level_; }

 private:
  Result<CCtxPtr> CreateCCtx() const {
    CCtxPtr cctx{ZSTD_createCCtx(), ZSTD_freeCCtx};
    if (cctx == nullptr) {
      return Status::OutOfMemory("ZSTD_CCtx create failed");
    }
    auto ret =
        ZSTD_CCtx_setParameter(cctx.get(), ZSTD_c_compressionLevel, compression_level_);
    if (ZSTD_isError(ret)) {
      return ZSTDError(ret, "ZSTD_CCtx create failed: ");
    }
    for (auto& [key, value] : compression_context_params_) {
      ret = ZSTD_CCtx_setParameter(cctx.get(), static_cast<ZSTD_cParameter>(key), value);
      if (ZSTD_isError(ret)) {
        return ZSTDError(ret, "ZSTD_CCtx create failed: ");
      }
    }
    return cctx;
  }

  Result<DCtxPtr> CreateDCtx() const {
    DCtxPtr dctx{ZSTD_createDCtx(), ZSTD_freeDCtx};
    if (dctx == nullptr) {
      return Status::OutOfMemory("ZSTD_DCtx create failed");
    }
    for (auto& [key, value] : decompression_context_params_) {
      auto ret =
          ZSTD_DCtx_setParameter(dctx.get(), static_cast<ZSTD_dParameter>(key), value);
      if (ZSTD_isError(ret)) {
        return ZSTDError(ret, "ZSTD_DCtx create failed: ");
      }
    }
    return dctx;
  }