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

Code before:
    auto result1 = Codec::Create(compression, codec_options);
    auto result2 = Codec::Create(compression, codec_options);
    ASSERT_EQ(expect_success, result1.ok());
    ASSERT_EQ(expect_success, result2.ok());
    if (expect_success) {
      CheckCodecRoundtrip(*result1, *result2, data);
    }
  }
}

TEST(TestCodecMisc, SpecifyCodecOptionsZstd) {
  // for now only GZIP & Brotli & Zstd codec options supported, since it has specific
  // parameters to be customized, other codecs could directly go with CodecOptions, could
  // add more specific codec options if needed.
  struct CombinationOption {
    int level;
    std::unordered_map<int, int> cctx_params;
    std::unordered_map<int, int> dctx_params;
  };
  const CombinationOption combinations[] = {
      {2, {}, {}},
      {9, {}, {}},
      {15, {}, {}},
      {-992, {}, {}},
      {3, {{ZSTD_c_windowLog, 23}}, {}},
      {3, {{ZSTD_c_windowLog, 28}}, {{ZSTD_d_windowLogMax, 28}}}};

  std::vector<uint8_t> data = MakeRandomData(2000);
  for (const auto& combination : combinations) {
    const auto compression = Compression::ZSTD;
    if (!Codec::IsAvailable(compression)) {
      // Support for this codec hasn't been built
      continue;
    }
    auto codec_options = arrow::util::ZstdCodecOptions();
    codec_options.compression_level = combination.level;
    codec_options.cctx_params = combination.cctx_params;
    codec_options.dctx_params = combination.dctx_params;
    auto result1 = Codec::Create(compression, codec_options);
    auto result2 = Codec::Create(compression, codec_options);
    CheckCodecRoundtrip(*result1, *result2, data);
  }
}

TEST_P(CodecTest, MinMaxCompressionLevel) {
  auto type = GetCompression();
  ASSERT_OK_AND_ASSIGN(auto codec, Codec::Create(type));

  if (Codec::SupportsCompressionLevel(type)) {
    ASSERT_OK_AND_ASSIGN(auto min_level, Codec::MinimumCompressionLevel(type));
    ASSERT_OK_AND_ASSIGN(auto max_level, Codec::MaximumCompressionLevel(type));

Review comment (suggestion):
Given that the ZSTD headers might not be there, we might have to hardcode those options' numeric values instead.

Code after:
    option.decompression_context_params = std::move(decompression_context_params);
    return option;
  };
  constexpr int ZSTD_c_windowLog = 101;
  const std::pair<arrow::util::ZstdCodecOptions, bool> options[]{
      {make_option(2, {}, {}), true},
      {make_option(9, {}, {}), true},
      {make_option(15, {}, {}), true},
      {make_option(-992, {}, {}), true},
      {make_option(3, {{ZSTD_c_windowLog, 23}}, {}), true},
      {make_option(3, {{ZSTD_c_windowLog, 28}}, {}), true}};
  CheckSpecifyCodecOptions<arrow::util::ZstdCodecOptions>(Compression::ZSTD, options);
}

TEST(TestCodecMisc, ZstdLargerWindowLog) {
#ifndef ARROW_WITH_ZSTD
  GTEST_SKIP() << "Test requires Zstd compression";
#endif

  constexpr int ZSTD_c_windowLog = 101;

  arrow::util::ZstdCodecOptions option1;
  arrow::util::ZstdCodecOptions option2;
  option2.compression_context_params = {{ZSTD_c_windowLog, 28}};

  std::vector<uint8_t> data = MakeRandomData(4 * 1024 * 1024);
  data.reserve(data.size() * 2);
  data.insert(data.end(), data.begin(), data.end());

  auto compress = [&data](const arrow::util::ZstdCodecOptions& codec_option)
      -> Result<std::vector<uint8_t>> {
    ARROW_ASSIGN_OR_RAISE(auto codec, Codec::Create(Compression::ZSTD, codec_option));
    auto max_compressed_len = codec->MaxCompressedLen(data.size(), data.data());
    std::vector<uint8_t> compressed(max_compressed_len);

    ARROW_ASSIGN_OR_RAISE(
        auto actual_size,
        codec->Compress(data.size(), data.data(), max_compressed_len, compressed.data()));
    compressed.resize(actual_size);
    return compressed;
  };

  ASSERT_OK_AND_ASSIGN(auto compressed1, compress(option1));
  ASSERT_OK_AND_ASSIGN(auto compressed2, compress(option2));
  ASSERT_GT(compressed1.size(), compressed2.size());
}

TEST(TestCodecMisc, ZstdStreamLargerWindowLog) {
#ifndef ARROW_WITH_ZSTD
  GTEST_SKIP() << "Test requires Zstd compression";
#endif