/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

// Format-level micro-benchmarks for the Parquet reader and writer. These drive
// ParquetWriterBuilder / ParquetFileBatchReader directly, so a format-layer change can be
// attributed without the catalog lookup, split planning, merge/sort and commit that the
// table-level read_write_benchmark includes. Each case comment says what that case answers.
//
// Every axis - type, cardinality, null density, batch size, encoding, selectivity - is swept on
// its own rather than as a combined matrix, because the point is attributing one change rather
// than describing a workload.
//
// Data is generated outside the timed region and on Arrow's default pool, because the writer
// cuts a new row group once its own pool crosses parquet.writer.max.memory.use.
//
// IO goes through the local FileSystem into a temporary directory - the project has no in-memory
// FileSystem - so absolute numbers are only meaningful relative to each other.

#include <algorithm>
#include <atomic>
#include <chrono>
#include <cstdint>
#include <functional>
#include <map>
#include <memory>
#include <mutex>
#include <optional>
#include <string>
#include <utility>
#include <vector>

#include "arrow/api.h"
#include "arrow/c/abi.h"
#include "arrow/c/bridge.h"
#include "arrow/c/helpers.h"
#include "arrow/util/bit_util.h"
#include "benchmark/benchmark.h"
#include "fmt/format.h"
#include "paimon/common/utils/arrow/arrow_input_stream_adapter.h"
#include "paimon/common/utils/arrow/mem_utils.h"
#include "paimon/common/utils/arrow/status_utils.h"
#include "paimon/common/utils/checked_cast.h"
#include "paimon/common/utils/path_util.h"
#include "paimon/defs.h"
#include "paimon/format/format_writer.h"
#include "paimon/format/parquet/parquet_field_id_converter.h"
#include "paimon/format/parquet/parquet_file_batch_reader.h"
#include "paimon/format/parquet/parquet_format_defs.h"
#include "paimon/format/parquet/parquet_writer_builder.h"
#include "paimon/fs/file_system.h"
#include "paimon/memory/memory_pool.h"
#include "paimon/metrics.h"
#include "paimon/predicate/literal.h"
#include "paimon/predicate/predicate.h"
#include "paimon/predicate/predicate_builder.h"
#include "paimon/reader/batch_reader.h"
#include "paimon/result.h"
#include "paimon/status.h"
#include "paimon/testing/utils/testharness.h"
#include "paimon/utils/roaring_bitmap32.h"

namespace {

using ::paimon::ArrowInputStreamAdapter;
using ::paimon::BatchReader;
using ::paimon::FieldType;
using ::paimon::FileStatus;
using ::paimon::FileSystem;
using ::paimon::FormatWriter;
using ::paimon::InputStream;
using ::paimon::Literal;
using ::paimon::OutputStream;
using ::paimon::PathUtil;
using ::paimon::Predicate;
using ::paimon::PredicateBuilder;
using ::paimon::Result;
using ::paimon::RoaringBitmap32;
using ::paimon::Status;
using ::paimon::parquet::ParquetFieldIdConverter;
using ::paimon::parquet::ParquetFileBatchReader;
using ::paimon::parquet::ParquetWriterBuilder;

constexpr int64_t kRowsPerFile = 100'000;
constexpr int64_t kRowsPerBatch = 10'000;
constexpr int32_t kReadBatchSize = 4096;
constexpr int32_t kWriteBatchSize = 1024;
// Small enough that a 100K-row file spans many pages, so page-level pruning has something to
// prune. Arrow's page limit is byte-based; a row-count limit is not available yet.
constexpr int64_t kPageSizeBytes = 64 * 1024;
// Four row groups per read fixture, so row-group pruning and page pruning are both in play.
constexpr int64_t kRowGroupLength = 25'000;
// Only StringFixture lowers this from arrow's 1MB default: at 1MB a 25K-row row group of distinct
// `value_<n>` entries still fits, so no cardinality this file writes would ever make the writer
// fall back to plain and the passthrough gate would have nothing to decline.
constexpr int64_t kDictionaryPageSizeBytes = 64 * 1024;
constexpr int64_t kStringCardinality = 1'000;
// Few enough distinct values that arrow keeps the column dictionary-encoded for the whole file,
// which is the shape the wide-schema case wants: per-column work small, per-batch cost visible.
constexpr int64_t kLowStringCardinality = 10;
constexpr int32_t kVectorDimension = 16;
constexpr int32_t kListLength = 4;
// Same as kListLength, so the MAP and LIST cases differ only in the extra key leaf.
constexpr int32_t kMapEntries = kListLength;
constexpr char kDefaultCompression[] = "zstd";
// Nulls are placed over a 100-row window, so a requested density is exact, not statistical.
constexpr int64_t kNullWindow = 100;

std::shared_ptr<arrow::Field> MakeField(const std::string& name,
                                        const std::shared_ptr<arrow::DataType>& type,
                                        int32_t field_id) {
    return arrow::field(name, type,
                        arrow::KeyValueMetadata::Make({ParquetFieldIdConverter::PARQUET_FIELD_ID},
                                                      {std::to_string(field_id)}));
}

std::shared_ptr<arrow::DataType> StructColumnType() {
    return arrow::struct_({arrow::field("a", arrow::int64()), arrow::field("b", arrow::utf8())});
}

std::shared_ptr<arrow::DataType> ListColumnType() {
    return arrow::list(arrow::int64());
}

std::shared_ptr<arrow::DataType> VectorColumnType() {
    return arrow::fixed_size_list(arrow::field("element", arrow::float32(), /*nullable=*/false),
                                  kVectorDimension);
}

std::shared_ptr<arrow::DataType> MapColumnType() {
    return arrow::map(arrow::utf8(), arrow::int64());
}

std::shared_ptr<arrow::DataType> DictionaryStringType() {
    return arrow::dictionary(arrow::int32(), arrow::utf8());
}

std::shared_ptr<arrow::DataType> DictionaryInt32Type() {
    return arrow::dictionary(arrow::int32(), arrow::int32());
}

// The three-column file the flat read cases scan. `id` is ordered so a range predicate maps
// onto a contiguous row range, which is what makes page-index pruning measurable.
std::shared_ptr<arrow::Schema> FlatSchema() {
    return arrow::schema({MakeField("id", arrow::int64(), 0), MakeField("name", arrow::utf8(), 1),
                          MakeField("amount", arrow::decimal128(18, 4), 2)});
}

std::shared_ptr<arrow::Schema> DecimalSchema(int32_t precision) {
    return arrow::schema({MakeField("amount", arrow::decimal128(precision, 4), 0)});
}

// One STRING column, so a dictionary case measures one encoder and nothing else.
std::shared_ptr<arrow::Schema> StringSchema() {
    return arrow::schema({MakeField("name", arrow::utf8(), 0)});
}

std::shared_ptr<arrow::Schema> DoubleSchema() {
    return arrow::schema({MakeField("value", arrow::float64(), 0)});
}

std::shared_ptr<arrow::Schema> NestedSchema() {
    return arrow::schema(
        {MakeField("id", arrow::int64(), 0), MakeField("info", StructColumnType(), 1),
         MakeField("tags", ListColumnType(), 2), MakeField("embedding", VectorColumnType(), 3),
         MakeField("attrs", MapColumnType(), 4)});
}

// A VECTOR is stored as a Parquet LIST and the reader hands back the file's own types, so a
// format-level read asks for the physical type; VectorFileBatchReader restores the view above.
std::shared_ptr<arrow::Schema> NestedReadSchema() {
    return arrow::schema({MakeField("id", arrow::int64(), 0),
                          MakeField("info", StructColumnType(), 1),
                          MakeField("tags", ListColumnType(), 2),
                          MakeField("embedding",
                                    arrow::list(arrow::field("element", arrow::float32(),
                                                             /*nullable=*/false)),
                                    3),
                          MakeField("attrs", MapColumnType(), 4)});
}

Result<std::shared_ptr<arrow::Array>> MakeInt64Column(int64_t num_rows, int64_t offset) {
    arrow::Int64Builder builder;
    PAIMON_RETURN_NOT_OK_FROM_ARROW(builder.Reserve(num_rows));
    for (int64_t i = 0; i < num_rows; ++i) {
        builder.UnsafeAppend(offset + i);
    }
    std::shared_ptr<arrow::Array> array;
    PAIMON_RETURN_NOT_OK_FROM_ARROW(builder.Finish(&array));
    return array;
}

Result<std::shared_ptr<arrow::Array>> MakeDoubleColumn(int64_t num_rows, int64_t offset) {
    arrow::DoubleBuilder builder;
    PAIMON_RETURN_NOT_OK_FROM_ARROW(builder.Reserve(num_rows));
    for (int64_t i = 0; i < num_rows; ++i) {
        builder.UnsafeAppend(static_cast<double>(offset + i) * 1.5);
    }
    std::shared_ptr<arrow::Array> array;
    PAIMON_RETURN_NOT_OK_FROM_ARROW(builder.Finish(&array));
    return array;
}

Result<std::shared_ptr<arrow::Array>> MakeBooleanColumn(int64_t num_rows, int64_t offset) {
    arrow::BooleanBuilder builder;
    PAIMON_RETURN_NOT_OK_FROM_ARROW(builder.Reserve(num_rows));
    for (int64_t i = 0; i < num_rows; ++i) {
        builder.UnsafeAppend(((offset + i) & 1) == 0);
    }
    std::shared_ptr<arrow::Array> array;
    PAIMON_RETURN_NOT_OK_FROM_ARROW(builder.Finish(&array));
    return array;
}

// Low cardinality is what arrow dictionary-encodes; high cardinality falls back to plain.
Result<std::shared_ptr<arrow::Array>> MakeStringColumn(int64_t num_rows, int64_t offset,
                                                       int64_t cardinality) {
    arrow::StringBuilder builder;
    PAIMON_RETURN_NOT_OK_FROM_ARROW(builder.Reserve(num_rows));
    for (int64_t i = 0; i < num_rows; ++i) {
        const int64_t value = (offset + i) % cardinality;
        PAIMON_RETURN_NOT_OK_FROM_ARROW(builder.Append("value_" + std::to_string(value)));
    }
    std::shared_ptr<arrow::Array> array;
    PAIMON_RETURN_NOT_OK_FROM_ARROW(builder.Finish(&array));
    return array;
}

// INT32 cycling through `cardinality` distinct values, the flat control for
// BM_ParquetWrite_DictionaryInt32: same logical values, same cardinality, same width, so the
// delta between the two is the dictionary materialization alone.
Result<std::shared_ptr<arrow::Array>> MakeInt32Column(int64_t num_rows, int64_t offset,
                                                      int64_t cardinality) {
    arrow::Int32Builder builder;
    PAIMON_RETURN_NOT_OK_FROM_ARROW(builder.Reserve(num_rows));
    for (int64_t i = 0; i < num_rows; ++i) {
        builder.UnsafeAppend(static_cast<int32_t>(((offset + i) % cardinality) * 7));
    }
    std::shared_ptr<arrow::Array> array;
    PAIMON_RETURN_NOT_OK_FROM_ARROW(builder.Finish(&array));
    return array;
}

// Dictionary-encoded input: `values->length()` distinct values behind an int32 index array. Arrow
// hands the indices straight to Parquet when the value type is binary-like
// (DictionaryDirectWriteSupported) and densifies them otherwise, so the value type alone decides
// whether the writer materializes anything.
Result<std::shared_ptr<arrow::Array>> MakeDictionaryColumn(
    const std::shared_ptr<arrow::Array>& values, int64_t num_rows, int64_t offset) {
    const int64_t cardinality = values->length();
    arrow::Int32Builder index_builder;
    PAIMON_RETURN_NOT_OK_FROM_ARROW(index_builder.Reserve(num_rows));
    for (int64_t i = 0; i < num_rows; ++i) {
        index_builder.UnsafeAppend(static_cast<int32_t>((offset + i) % cardinality));
    }
    std::shared_ptr<arrow::Array> indices;
    PAIMON_RETURN_NOT_OK_FROM_ARROW(index_builder.Finish(&indices));
    PAIMON_ASSIGN_OR_RAISE_FROM_ARROW(std::shared_ptr<arrow::Array> array,
                                      arrow::DictionaryArray::FromArrays(indices, values));
    return array;
}

// STRING values: binary-like, so arrow can write the indices directly. Every batch is built over
// the same alphabet, the shape a single input file produces.
Result<std::shared_ptr<arrow::Array>> MakeDictionaryStringColumn(int64_t num_rows, int64_t offset,
                                                                 int64_t cardinality) {
    PAIMON_ASSIGN_OR_RAISE(std::shared_ptr<arrow::Array> values,
                           MakeStringColumn(cardinality, /*offset=*/0, cardinality));
    return MakeDictionaryColumn(values, num_rows, offset);
}

// The same, except every batch carries its own dictionary - the shape a compaction rewrite
// produces, where each input file supplies one. A Parquet column chunk holds a single dictionary,
// so arrow keeps the first and falls back to plain encoding for the rest of the row group
// (column_writer.cc, `dictionary->Equals(*preserved_dictionary_)`).
//
// The decoded column is byte for byte what MakeDictionaryStringColumn produces: same values, same
// order, same widths, same cardinality. Only the dictionary object differs, so the delta between
// the two benchmarks is the cost of the fallback and nothing else. Generating a fresh alphabet per
// batch instead would change the data as well - different strings, different widths, a different
// global cardinality - and the comparison would measure all of that at once.
Result<std::shared_ptr<arrow::Array>> MakeChangingDictionaryStringColumn(int64_t num_rows,
                                                                         int64_t offset,
                                                                         int64_t cardinality) {
    // The alphabet is rotated by one position per batch and the indices are shifted the other way,
    // which cancels: index `(offset + cardinality - rotation + i) % cardinality` into an alphabet
    // whose entry `j` is `value_<(j + rotation) % cardinality>` is `value_<(offset + i) %
    // cardinality>` either way. `+ cardinality` keeps the shifted offset non-negative.
    const int64_t rotation = num_rows > 0 ? (offset / num_rows) % cardinality : 0;
    PAIMON_ASSIGN_OR_RAISE(std::shared_ptr<arrow::Array> values,
                           MakeStringColumn(cardinality, rotation, cardinality));
    return MakeDictionaryColumn(values, num_rows, offset + cardinality - rotation);
}

// INT32 values: is_base_binary_like excludes them, so arrow densifies before writing. The
// dictionary holds the same `i * 7` values MakeInt32Column emits inline, so the two are directly
// comparable.
Result<std::shared_ptr<arrow::Array>> MakeDictionaryInt32Column(int64_t num_rows, int64_t offset,
                                                                int64_t cardinality) {
    PAIMON_ASSIGN_OR_RAISE(std::shared_ptr<arrow::Array> values,
                           MakeInt32Column(cardinality, /*offset=*/0, cardinality));
    return MakeDictionaryColumn(values, num_rows, offset);
}

// Precision drives the Parquet physical type: <= 9 is INT32, <= 18 is INT64, larger is
// FIXED_LEN_BYTE_ARRAY, and the three take different transfer paths on read.
Result<std::shared_ptr<arrow::Array>> MakeDecimalColumn(int64_t num_rows, int64_t offset,
                                                        int32_t precision, int32_t scale) {
    arrow::Decimal128Builder builder(arrow::decimal128(precision, scale));
    PAIMON_RETURN_NOT_OK_FROM_ARROW(builder.Reserve(num_rows));
    for (int64_t i = 0; i < num_rows; ++i) {
        PAIMON_RETURN_NOT_OK_FROM_ARROW(builder.Append(arrow::Decimal128(offset + i)));
    }
    std::shared_ptr<arrow::Array> array;
    PAIMON_RETURN_NOT_OK_FROM_ARROW(builder.Finish(&array));
    return array;
}

Result<std::shared_ptr<arrow::Array>> MakeStructArray(
    const arrow::FieldVector& fields, const std::vector<std::shared_ptr<arrow::Array>>& columns) {
    PAIMON_ASSIGN_OR_RAISE_FROM_ARROW(std::shared_ptr<arrow::StructArray> array,
                                      arrow::StructArray::Make(columns, fields));
    return paimon::checked_pointer_cast<arrow::Array>(array);
}

Result<std::shared_ptr<arrow::Array>> MakeStructColumn(int64_t num_rows, int64_t offset) {
    PAIMON_ASSIGN_OR_RAISE(std::shared_ptr<arrow::Array> a, MakeInt64Column(num_rows, offset));
    PAIMON_ASSIGN_OR_RAISE(std::shared_ptr<arrow::Array> b,
                           MakeStringColumn(num_rows, offset, kStringCardinality));
    return MakeStructArray(StructColumnType()->fields(), {a, b});
}

// Constant element count per row, so the delta against a flat BIGINT column is the levels.
Result<std::shared_ptr<arrow::Array>> MakeListColumn(int64_t num_rows, int64_t offset) {
    auto value_builder = std::make_shared<arrow::Int64Builder>();
    arrow::ListBuilder builder(arrow::default_memory_pool(), value_builder, ListColumnType());
    PAIMON_RETURN_NOT_OK_FROM_ARROW(builder.Reserve(num_rows));
    PAIMON_RETURN_NOT_OK_FROM_ARROW(value_builder->Reserve(num_rows * kListLength));
    for (int64_t i = 0; i < num_rows; ++i) {
        PAIMON_RETURN_NOT_OK_FROM_ARROW(builder.Append());
        for (int32_t j = 0; j < kListLength; ++j) {
            value_builder->UnsafeAppend(offset + i + j);
        }
    }
    std::shared_ptr<arrow::Array> array;
    PAIMON_RETURN_NOT_OK_FROM_ARROW(builder.Finish(&array));
    return array;
}

// The writer converts VECTOR to a Parquet LIST, so this also covers ParquetVectorConverter.
Result<std::shared_ptr<arrow::Array>> MakeVectorColumn(int64_t num_rows, int64_t offset) {
    auto value_builder = std::make_shared<arrow::FloatBuilder>();
    arrow::FixedSizeListBuilder builder(arrow::default_memory_pool(), value_builder,
                                        VectorColumnType());
    PAIMON_RETURN_NOT_OK_FROM_ARROW(builder.Reserve(num_rows));
    PAIMON_RETURN_NOT_OK_FROM_ARROW(value_builder->Reserve(num_rows * kVectorDimension));
    for (int64_t i = 0; i < num_rows; ++i) {
        PAIMON_RETURN_NOT_OK_FROM_ARROW(builder.Append());
        for (int32_t j = 0; j < kVectorDimension; ++j) {
            value_builder->UnsafeAppend(static_cast<float>((offset + i) % 1024) +
                                        static_cast<float>(j));
        }
    }
    std::shared_ptr<arrow::Array> array;
    PAIMON_RETURN_NOT_OK_FROM_ARROW(builder.Finish(&array));
    return array;
}

// A Parquet MAP is a LIST of a two-field STRUCT, so against LIST the difference is the key leaf.
Result<std::shared_ptr<arrow::Array>> MakeMapColumn(int64_t num_rows, int64_t offset,
                                                    int32_t entries) {
    auto key_builder = std::make_shared<arrow::StringBuilder>();
    auto item_builder = std::make_shared<arrow::Int64Builder>();
    arrow::MapBuilder builder(arrow::default_memory_pool(), key_builder, item_builder,
                              MapColumnType());
    PAIMON_RETURN_NOT_OK_FROM_ARROW(builder.Reserve(num_rows));
    PAIMON_RETURN_NOT_OK_FROM_ARROW(key_builder->Reserve(num_rows * entries));
    PAIMON_RETURN_NOT_OK_FROM_ARROW(item_builder->Reserve(num_rows * entries));
    for (int64_t i = 0; i < num_rows; ++i) {
        PAIMON_RETURN_NOT_OK_FROM_ARROW(builder.Append());
        for (int32_t j = 0; j < entries; ++j) {
            PAIMON_RETURN_NOT_OK_FROM_ARROW(key_builder->Append("key_" + std::to_string(j)));
            item_builder->UnsafeAppend(offset + i + j);
        }
    }
    std::shared_ptr<arrow::Array> array;
    PAIMON_RETURN_NOT_OK_FROM_ARROW(builder.Finish(&array));
    return array;
}

// Masks `null_pct` percent of the slots null. Doing it after the fact rather than in every
// generator keeps the values identical across densities, so the delta between two settings is the
// level machinery alone. Only the top level is masked: a STRUCT or LIST row, not its leaves.
Result<std::shared_ptr<arrow::Array>> WithNulls(const std::shared_ptr<arrow::Array>& array,
                                                int64_t offset, int64_t null_pct) {
    if (null_pct <= 0) {
        return array;
    }
    // Builder output starts at slot 0, so the bitmap below can be indexed by position.
    if (array->data()->offset != 0) {
        return Status::Invalid("WithNulls expects an unsliced array");
    }
    const int64_t length = array->length();
    PAIMON_ASSIGN_OR_RAISE_FROM_ARROW(
        std::shared_ptr<arrow::Buffer> validity,
        arrow::AllocateEmptyBitmap(length, arrow::default_memory_pool()));
    int64_t null_count = 0;
    for (int64_t i = 0; i < length; ++i) {
        if ((offset + i) % kNullWindow < null_pct) {
            ++null_count;
        } else {
            arrow::bit_util::SetBit(validity->mutable_data(), i);
        }
    }
    std::shared_ptr<arrow::ArrayData> data = array->data()->Copy();
    data->buffers[0] = std::move(validity);
    data->SetNullCount(null_count);
    return arrow::MakeArray(data);
}

using BatchFactory = std::function<Result<std::shared_ptr<arrow::Array>>(
    const std::shared_ptr<arrow::Schema>& schema, int64_t offset, int64_t rows)>;

using ColumnFactory =
    std::function<Result<std::shared_ptr<arrow::Array>>(int64_t rows, int64_t offset)>;

ColumnFactory NullableColumnFactory(const ColumnFactory& make_column, int64_t null_pct) {
    return [make_column, null_pct](int64_t rows,
                                   int64_t offset) -> Result<std::shared_ptr<arrow::Array>> {
        PAIMON_ASSIGN_OR_RAISE(std::shared_ptr<arrow::Array> column, make_column(rows, offset));
        return WithNulls(column, offset, null_pct);
    };
}

// Lifts a one-column generator into a batch factory for a one-field schema.
BatchFactory SingleColumnBatch(const ColumnFactory& make_column) {
    return [make_column](const std::shared_ptr<arrow::Schema>& schema, int64_t offset,
                         int64_t rows) -> Result<std::shared_ptr<arrow::Array>> {
        PAIMON_ASSIGN_OR_RAISE(std::shared_ptr<arrow::Array> column, make_column(rows, offset));
        return MakeStructArray(schema->fields(), {column});
    };
}

// The same, but the batch is typed by the column rather than by the schema, so it can carry an
// encoding the schema does not declare. That is the shape a compaction rewrite produces: the file
// writer is built from the table's logical schema while the reader forwards whatever encoding the
// input file already had, leaving the writer to recover it from the batch.
BatchFactory SingleEncodedColumnBatch(const ColumnFactory& make_column) {
    return [make_column](const std::shared_ptr<arrow::Schema>& schema, int64_t offset,
                         int64_t rows) -> Result<std::shared_ptr<arrow::Array>> {
        PAIMON_ASSIGN_OR_RAISE(std::shared_ptr<arrow::Array> column, make_column(rows, offset));
        return MakeStructArray({schema->field(0)->WithType(column->type())}, {column});
    };
}

Result<std::shared_ptr<arrow::Array>> MakeNullableFlatBatch(
    const std::shared_ptr<arrow::Schema>& schema, int64_t offset, int64_t rows, int64_t null_pct) {
    PAIMON_ASSIGN_OR_RAISE(std::shared_ptr<arrow::Array> ids, MakeInt64Column(rows, offset));
    PAIMON_ASSIGN_OR_RAISE(ids, WithNulls(ids, offset, null_pct));
    PAIMON_ASSIGN_OR_RAISE(std::shared_ptr<arrow::Array> names,
                           MakeStringColumn(rows, offset, kStringCardinality));
    PAIMON_ASSIGN_OR_RAISE(names, WithNulls(names, offset, null_pct));
    PAIMON_ASSIGN_OR_RAISE(std::shared_ptr<arrow::Array> amounts,
                           MakeDecimalColumn(rows, offset, /*precision=*/18, /*scale=*/4));
    PAIMON_ASSIGN_OR_RAISE(amounts, WithNulls(amounts, offset, null_pct));
    return MakeStructArray(schema->fields(), {ids, names, amounts});
}

Result<std::shared_ptr<arrow::Array>> MakeFlatBatch(const std::shared_ptr<arrow::Schema>& schema,
                                                    int64_t offset, int64_t rows) {
    return MakeNullableFlatBatch(schema, offset, rows, /*null_pct=*/0);
}

// One low-cardinality VARCHAR per field, cheap enough that a wide schema leaves the per-column
// setup holding the measurement. The staggered offset keeps the columns from being identical.
Result<std::shared_ptr<arrow::Array>> MakeWideBatch(const std::shared_ptr<arrow::Schema>& schema,
                                                    int64_t offset, int64_t rows) {
    std::vector<std::shared_ptr<arrow::Array>> columns;
    columns.reserve(schema->num_fields());
    for (int32_t i = 0; i < schema->num_fields(); ++i) {
        PAIMON_ASSIGN_OR_RAISE(std::shared_ptr<arrow::Array> column,
                               MakeStringColumn(rows, offset + i, kLowStringCardinality));
        columns.push_back(std::move(column));
    }
    return MakeStructArray(schema->fields(), columns);
}

Result<std::shared_ptr<arrow::Array>> MakeNestedBatch(const std::shared_ptr<arrow::Schema>& schema,
                                                      int64_t offset, int64_t rows) {
    PAIMON_ASSIGN_OR_RAISE(std::shared_ptr<arrow::Array> ids, MakeInt64Column(rows, offset));
    PAIMON_ASSIGN_OR_RAISE(std::shared_ptr<arrow::Array> info, MakeStructColumn(rows, offset));
    PAIMON_ASSIGN_OR_RAISE(std::shared_ptr<arrow::Array> tags, MakeListColumn(rows, offset));
    PAIMON_ASSIGN_OR_RAISE(std::shared_ptr<arrow::Array> embedding, MakeVectorColumn(rows, offset));
    PAIMON_ASSIGN_OR_RAISE(std::shared_ptr<arrow::Array> attrs,
                           MakeMapColumn(rows, offset, kMapEntries));
    return MakeStructArray(schema->fields(), {ids, info, tags, embedding, attrs});
}

// Whether every AddBatch call gets its own array or they all share one. It matters for dictionary
// input: arrow compares each batch's dictionary against the previous one, so N distinct-but-equal
// dictionaries and one dictionary written N times are not the same write. Only
// BM_ParquetWrite_MemoryThreshold reuses one batch; every other case generates each batch
// independently. That is about the arrays, not the values - generators that cycle with a period
// dividing the batch size, such as the boolean and the low-cardinality string ones, produce
// batches that are equal in value but separate objects.
enum class BatchReuse { kFresh, kReused };

Result<std::vector<std::shared_ptr<arrow::Array>>> MakeBatches(
    const std::shared_ptr<arrow::Schema>& schema, const BatchFactory& make_batch,
    int64_t rows_per_batch, int64_t total_rows = kRowsPerFile,
    BatchReuse reuse = BatchReuse::kFresh) {
    if (reuse == BatchReuse::kReused) {
        // One array written N times cannot express a short final batch, and silently writing a
        // full one instead would put more rows in the file than the reported metrics divide by.
        if (total_rows % rows_per_batch != 0) {
            return Status::Invalid("BatchReuse::kReused needs total_rows divisible by " +
                                   std::to_string(rows_per_batch) + ", got " +
                                   std::to_string(total_rows));
        }
        PAIMON_ASSIGN_OR_RAISE(std::shared_ptr<arrow::Array> batch,
                               make_batch(schema, /*offset=*/0, rows_per_batch));
        return std::vector<std::shared_ptr<arrow::Array>>(total_rows / rows_per_batch,
                                                          std::move(batch));
    }
    std::vector<std::shared_ptr<arrow::Array>> batches;
    for (int64_t offset = 0; offset < total_rows; offset += rows_per_batch) {
        const int64_t rows = std::min<int64_t>(rows_per_batch, total_rows - offset);
        PAIMON_ASSIGN_OR_RAISE(std::shared_ptr<arrow::Array> batch,
                               make_batch(schema, offset, rows));
        batches.push_back(std::move(batch));
    }
    return batches;
}

Result<int64_t> WriteParquetFile(const std::shared_ptr<FileSystem>& fs, const std::string& path,
                                 const std::shared_ptr<arrow::Schema>& schema,
                                 const std::vector<std::shared_ptr<arrow::Array>>& batches,
                                 const std::map<std::string, std::string>& options,
                                 const std::string& compression) {
    ParquetWriterBuilder writer_builder(schema, kWriteBatchSize, options);
    PAIMON_ASSIGN_OR_RAISE(std::shared_ptr<OutputStream> out, fs->Create(path, /*overwrite=*/true));
    PAIMON_ASSIGN_OR_RAISE(std::unique_ptr<FormatWriter> writer,
                           writer_builder.Build(out, compression));
    for (const auto& batch : batches) {
        // AddBatch imports - and so consumes - the C array, so each batch needs a fresh export.
        ArrowArray c_array;
        PAIMON_RETURN_NOT_OK_FROM_ARROW(arrow::ExportArray(*batch, &c_array));
        PAIMON_RETURN_NOT_OK(writer->AddBatch(&c_array));
    }
    PAIMON_RETURN_NOT_OK(writer->Finish());
    PAIMON_RETURN_NOT_OK(out->Close());
    PAIMON_ASSIGN_OR_RAISE(FileStatus file_status, fs->GetFileStatus(path));
    return file_status.GetLen();
}

struct ReadStats {
    int64_t rows = 0;
    // Reader-side counterpart of file size: makes pruning and skipping visible apart from CPU.
    uint64_t storage_bytes = 0;
    // Without these a filtered case shows only that it got faster, not that pruning is why.
    uint64_t row_groups_total = 0;
    uint64_t row_groups_after_filter = 0;
    uint64_t batches = 0;
};

// Every counter read below is set unconditionally by the reader - the row-group pair in
// SetReadSchema, the batch count in NextBatch - so an absent one means the metric moved or stopped
// being recorded. Reporting that as a zero would hide the regression behind a plausible number,
// so the error propagates and fails the case instead.
Result<uint64_t> ReadCounter(const std::shared_ptr<paimon::Metrics>& metrics,
                             const std::string& name) {
    return metrics->GetCounter(name);
}

Result<ReadStats> ReadParquetFile(const std::shared_ptr<FileSystem>& fs, const std::string& path,
                                  const std::shared_ptr<arrow::Schema>& read_schema,
                                  const std::shared_ptr<Predicate>& predicate,
                                  const std::optional<RoaringBitmap32>& selection_bitmap,
                                  const std::map<std::string, std::string>& options,
                                  int32_t batch_size,
                                  const std::shared_ptr<arrow::MemoryPool>& pool) {
    PAIMON_ASSIGN_OR_RAISE(FileStatus file_status, fs->GetFileStatus(path));
    PAIMON_ASSIGN_OR_RAISE(std::shared_ptr<InputStream> input, fs->Open(path));
    auto in_stream = std::make_shared<ArrowInputStreamAdapter>(input, file_status.GetLen(), pool);
    // Held separately so the counter outlives the adapter the reader takes ownership of.
    std::shared_ptr<std::atomic<uint64_t>> storage_read_bytes = in_stream->StorageReadBytes();
    PAIMON_ASSIGN_OR_RAISE(
        std::unique_ptr<ParquetFileBatchReader> reader,
        ParquetFileBatchReader::Create(std::move(in_stream), options, batch_size,
                                       /*file_metadata=*/nullptr, storage_read_bytes, pool,
                                       /*hints=*/std::nullopt));

    // SetReadSchema imports the C schema and takes ownership of it.
    ArrowSchema c_schema;
    PAIMON_RETURN_NOT_OK_FROM_ARROW(arrow::ExportSchema(*read_schema, &c_schema));
    PAIMON_RETURN_NOT_OK(reader->SetReadSchema(&c_schema, predicate, selection_bitmap));

    ReadStats stats;
    while (true) {
        PAIMON_ASSIGN_OR_RAISE(BatchReader::ReadBatch batch, reader->NextBatch());
        if (BatchReader::IsEofBatch(batch)) {
            break;
        }
        stats.rows += batch.first->length;
        ArrowArrayRelease(batch.first.get());
        ArrowSchemaRelease(batch.second.get());
    }

    std::shared_ptr<paimon::Metrics> metrics = reader->GetReaderMetrics();
    PAIMON_ASSIGN_OR_RAISE(
        stats.row_groups_total,
        ReadCounter(metrics, paimon::parquet::ParquetMetrics::READ_ROW_GROUPS_TOTAL));
    PAIMON_ASSIGN_OR_RAISE(
        stats.row_groups_after_filter,
        ReadCounter(metrics, paimon::parquet::ParquetMetrics::READ_ROW_GROUPS_AFTER_FILTER));
    PAIMON_ASSIGN_OR_RAISE(stats.batches,
                           ReadCounter(metrics, paimon::parquet::ParquetMetrics::READ_BATCH_COUNT));
    reader->Close();
    stats.storage_bytes = storage_read_bytes->load();
    return stats;
}

// Row groups the written file actually ended up with. The writer decides that itself - by row
// count, or by its pool crossing parquet.writer.max.memory.use - so the footer is the only
// reliable source.
//
// The write schema is deliberately not used to read back, because for two cases it does not
// describe the file. A VECTOR is stored as a LIST, and CollectLeafIndices branches on the file
// type, so a FixedSizeList read type against a file LIST is rejected outright. A dictionary column
// is stored as its value type; that one survives leaf collection, which compares nothing for
// atomic fields, and would fail later against read_data_type_ once a batch is read. Create()
// resolves the file's own schema and sets the row-group counters while doing so, which is all this
// needs - no read schema, no batch read, and neither trap.
Result<uint64_t> ReadRowGroupCount(const std::shared_ptr<FileSystem>& fs, const std::string& path,
                                   const std::shared_ptr<arrow::MemoryPool>& pool) {
    PAIMON_ASSIGN_OR_RAISE(FileStatus file_status, fs->GetFileStatus(path));
    PAIMON_ASSIGN_OR_RAISE(std::shared_ptr<InputStream> input, fs->Open(path));
    auto in_stream = std::make_shared<ArrowInputStreamAdapter>(input, file_status.GetLen(), pool);
    PAIMON_ASSIGN_OR_RAISE(
        std::unique_ptr<ParquetFileBatchReader> reader,
        ParquetFileBatchReader::Create(std::move(in_stream), /*options=*/{}, kReadBatchSize,
                                       /*file_metadata=*/nullptr, /*storage_read_bytes=*/nullptr,
                                       pool, /*hints=*/std::nullopt));
    PAIMON_ASSIGN_OR_RAISE(uint64_t row_groups,
                           ReadCounter(reader->GetReaderMetrics(),
                                       paimon::parquet::ParquetMetrics::READ_ROW_GROUPS_TOTAL));
    reader->Close();
    return row_groups;
}

// Owns a temporary directory plus the shared FileSystem / MemoryPool, removed on destruction.
class BenchmarkEnv {
 public:
    static Result<std::unique_ptr<BenchmarkEnv>> Create() {
        std::unique_ptr<paimon::test::UniqueTestDirectory> dir =
            paimon::test::UniqueTestDirectory::Create();
        if (!dir) {
            return Status::IOError("failed to create a temporary benchmark directory");
        }
        return std::unique_ptr<BenchmarkEnv>(new BenchmarkEnv(std::move(dir)));
    }

    const std::shared_ptr<FileSystem>& fs() const {
        return fs_;
    }

    // The reader takes an arrow pool; the writer builder allocates its own from the paimon pool.
    const std::shared_ptr<arrow::MemoryPool>& arrow_pool() const {
        return arrow_pool_;
    }

    std::string PathOf(const std::string& file_name) const {
        return PathUtil::JoinPath(dir_->Str(), file_name);
    }

 private:
    explicit BenchmarkEnv(std::unique_ptr<paimon::test::UniqueTestDirectory> dir)
        : dir_(std::move(dir)),
          fs_(dir_->GetFileSystem()),
          arrow_pool_(paimon::GetArrowPool(paimon::GetDefaultPool())) {}

    std::unique_ptr<paimon::test::UniqueTestDirectory> dir_;
    std::shared_ptr<FileSystem> fs_;
    std::shared_ptr<arrow::MemoryPool> arrow_pool_;
};

// A file the read cases scan, built once per configuration; rebuilding it would dominate.
class ReadFixture {
 public:
    ReadFixture(const std::string& file_name, const std::shared_ptr<arrow::Schema>& schema,
                const BatchFactory& make_batch,
                const std::map<std::string, std::string>& write_options = {}) {
        status_ = Build(file_name, schema, make_batch, write_options);
    }

    const Status& status() const {
        return status_;
    }

    const std::string& path() const {
        return path_;
    }

    const std::shared_ptr<FileSystem>& fs() const {
        return env_->fs();
    }

    const std::shared_ptr<arrow::MemoryPool>& arrow_pool() const {
        return env_->arrow_pool();
    }

    int64_t file_bytes() const {
        return file_bytes_;
    }

 private:
    Status Build(const std::string& file_name, const std::shared_ptr<arrow::Schema>& schema,
                 const BatchFactory& make_batch,
                 const std::map<std::string, std::string>& write_options) {
        PAIMON_ASSIGN_OR_RAISE(env_, BenchmarkEnv::Create());
        path_ = env_->PathOf(file_name);
        PAIMON_ASSIGN_OR_RAISE(std::vector<std::shared_ptr<arrow::Array>> batches,
                               MakeBatches(schema, make_batch, kRowsPerBatch));
        std::map<std::string, std::string> options = write_options;
        options[paimon::parquet::PARQUET_PAGE_SIZE] = std::to_string(kPageSizeBytes);
        options[paimon::parquet::PARQUET_WRITE_MAX_ROW_GROUP_LENGTH] =
            std::to_string(kRowGroupLength);
        PAIMON_ASSIGN_OR_RAISE(file_bytes_, WriteParquetFile(env_->fs(), path_, schema, batches,
                                                             options, kDefaultCompression));
        return Status::OK();
    }

    std::unique_ptr<BenchmarkEnv> env_;
    std::string path_;
    int64_t file_bytes_ = 0;
    Status status_;
};

// Built on first use, so a case excluded by --benchmark_filter never pays to write its file.
// google/benchmark may report from a different thread than it registered on, hence the lock.
const ReadFixture& GetFixture(const std::string& key,
                              const std::function<std::unique_ptr<ReadFixture>()>& build) {
    static std::mutex mutex;
    static std::map<std::string, std::unique_ptr<ReadFixture>> fixtures;
    std::lock_guard<std::mutex> guard(mutex);
    std::unique_ptr<ReadFixture>& fixture = fixtures[key];
    if (!fixture) {
        fixture = build();
    }
    return *fixture;
}

const ReadFixture& FlatFixture() {
    return GetFixture("flat", [] {
        return std::make_unique<ReadFixture>("flat.parquet", FlatSchema(), &MakeFlatBatch);
    });
}

const ReadFixture& NestedFixture() {
    return GetFixture("nested", [] {
        return std::make_unique<ReadFixture>("nested.parquet", NestedSchema(), &MakeNestedBatch);
    });
}

const ReadFixture& NullableFlatFixture(int64_t null_pct) {
    const std::string key = "flat_nulls_" + std::to_string(null_pct);
    return GetFixture(key, [key, null_pct] {
        return std::make_unique<ReadFixture>(
            key + ".parquet", FlatSchema(),
            [null_pct](const std::shared_ptr<arrow::Schema>& schema, int64_t offset, int64_t rows) {
                return MakeNullableFlatBatch(schema, offset, rows, null_pct);
            });
    });
}

// A one-column file, for read cases that isolate a single decoder.
const ReadFixture& ColumnFixture(const std::string& key,
                                 const std::shared_ptr<arrow::Schema>& schema,
                                 const ColumnFactory& make_column) {
    return GetFixture(key, [key, schema, make_column] {
        return std::make_unique<ReadFixture>(key + ".parquet", schema,
                                             SingleColumnBatch(make_column));
    });
}

// The flat fixture only carries precision 18, so without this the FIXED_LEN_BYTE_ARRAY path that
// precision 38 takes is written but never read.
const ReadFixture& DecimalFixture(int32_t precision) {
    return ColumnFixture("decimal_" + std::to_string(precision), DecimalSchema(precision),
                         [precision](int64_t rows, int64_t offset) {
                             return MakeDecimalColumn(rows, offset, precision, /*scale=*/4);
                         });
}

// The flat schema carries no floating-point column, so a DOUBLE read needs a file of its own.
const ReadFixture& DoubleFixture() {
    return ColumnFixture("double", DoubleSchema(), &MakeDoubleColumn);
}

// A one-column STRING file at a chosen cardinality, written with a reduced dictionary page limit
// so both regimes the passthrough gate distinguishes are reachable within a 100K-row file. Under
// the limit every data page stays dictionary-encoded and the gate lets the column through; over
// it the writer emits the dictionary page it has and encodes the rest as plain, which is the case
// the gate has to decline. At kDictionaryPageSizeBytes a row group holds roughly 4K distinct
// `value_<n>` entries before overflowing, so cardinality alone picks the regime.
const ReadFixture& StringFixture(int64_t cardinality) {
    const std::string key = fmt::format("string_{}", cardinality);
    return GetFixture(key, [key, cardinality] {
        std::map<std::string, std::string> options;
        options[paimon::parquet::PARQUET_DICTIONARY_PAGE_SIZE] =
            std::to_string(kDictionaryPageSizeBytes);
        return std::make_unique<ReadFixture>(
            key + ".parquet", StringSchema(),
            SingleColumnBatch([cardinality](int64_t rows, int64_t offset) {
                return MakeStringColumn(rows, offset, cardinality);
            }),
            options);
    });
}

// The same data with dictionary encoding off, giving the read side a plain baseline.
const ReadFixture& PlainFlatFixture() {
    return GetFixture("flat_plain", [] {
        std::map<std::string, std::string> options;
        options[paimon::parquet::PARQUET_ENABLE_DICTIONARY] = "false";
        return std::make_unique<ReadFixture>("flat_plain.parquet", FlatSchema(), &MakeFlatBatch,
                                             options);
    });
}

// google/benchmark's own main exits 0 whatever happened, so a case that called SkipWithError
// prints as skipped while `ctest -L benchmark` still passes. Nothing here skips on purpose, so
// the flag every error sets becomes the process exit code. It is recorded here rather than in a
// custom reporter because passing one to RunSpecifiedBenchmarks would bypass
// CreateDefaultDisplayReporter and with it --benchmark_format, --benchmark_color and
// --benchmark_counters_tabular.
std::atomic<bool> g_failed{false};

bool FailBenchmark(::benchmark::State& state, const Status& status) {
    if (status.ok()) {
        return false;
    }
    g_failed.store(true);
    state.SkipWithError(status.ToString().c_str());
    return true;
}

class Timer {
 public:
    double ElapsedNanos() const {
        return std::chrono::duration<double, std::nano>(std::chrono::steady_clock::now() - started_)
            .count();
    }

 private:
    std::chrono::steady_clock::time_point started_ = std::chrono::steady_clock::now();
};

// google/benchmark reports items/s; ns per row is what the issue asks for, so the timed region
// is also measured directly and divided by the row count.
void ReportRowRate(::benchmark::State& state, int64_t rows, double elapsed_ns) {
    state.SetItemsProcessed(static_cast<int64_t>(state.iterations()) * rows);
    const double total_rows = static_cast<double>(state.iterations()) * static_cast<double>(rows);
    if (total_rows > 0) {
        state.counters["ns_per_row"] = ::benchmark::Counter(elapsed_ns / total_rows);
    }
}

// Bytes per iteration, plus the per-row form that shows a CPU-for-size trade next to ns_per_row.
void ReportBytes(::benchmark::State& state, const std::string& name, int64_t bytes, int64_t rows) {
    state.counters[name] = ::benchmark::Counter(static_cast<double>(bytes));
    if (rows > 0) {
        state.counters["bytes_per_row"] =
            ::benchmark::Counter(static_cast<double>(bytes) / static_cast<double>(rows));
    }
}

// Everything the writer needs per file - properties, output stream, schema conversion, footer -
// is inside the timed region, because that is what a caller pays per data file.
void RunWriteBenchmark(::benchmark::State& state, const std::shared_ptr<arrow::Schema>& schema,
                       const BatchFactory& make_batch, int64_t rows_per_batch,
                       const std::map<std::string, std::string>& options,
                       const std::string& compression, int64_t total_rows = kRowsPerFile,
                       BatchReuse reuse = BatchReuse::kFresh) {
    Result<std::unique_ptr<BenchmarkEnv>> env = BenchmarkEnv::Create();
    if (FailBenchmark(state, env.status())) {
        return;
    }
    Result<std::vector<std::shared_ptr<arrow::Array>>> batches =
        MakeBatches(schema, make_batch, rows_per_batch, total_rows, reuse);
    if (FailBenchmark(state, batches.status())) {
        return;
    }
    const std::string path = env.value()->PathOf("write_case.parquet");

    int64_t file_bytes = 0;
    Timer timer;
    for (auto _ : state) {
        Result<int64_t> written = WriteParquetFile(env.value()->fs(), path, schema, batches.value(),
                                                   options, compression);
        if (FailBenchmark(state, written.status())) {
            return;
        }
        file_bytes = written.value();
    }
    // Captured before the read-back below, which reopens the file and parses its footer. Reading
    // the timer after would put that inside ns_per_row but not inside google/benchmark's own
    // real_time, leaving the two disagreeing by a fixed amount that matters at low iteration
    // counts.
    const double elapsed_ns = timer.ElapsedNanos();

    // Read back rather than computed: with a byte-triggered flush the count is not predictable
    // from the arguments, and where a row-count limit does make it predictable, reporting the real
    // number is what would catch the prediction being wrong.
    Result<uint64_t> row_groups =
        ReadRowGroupCount(env.value()->fs(), path, env.value()->arrow_pool());
    if (FailBenchmark(state, row_groups.status())) {
        return;
    }

    ReportRowRate(state, total_rows, elapsed_ns);
    ReportBytes(state, "file_bytes", file_bytes, total_rows);
    state.counters["batches"] = ::benchmark::Counter(
        static_cast<double>((total_rows + rows_per_batch - 1) / rows_per_batch));
    state.counters["row_groups"] = ::benchmark::Counter(static_cast<double>(row_groups.value()));
}

// Single-column variant: one column isolates one encoder.
void RunColumnWriteBenchmark(::benchmark::State& state, const std::shared_ptr<arrow::Field>& field,
                             const ColumnFactory& make_column, int64_t rows_per_batch,
                             const std::map<std::string, std::string>& options,
                             int64_t total_rows = kRowsPerFile,
                             BatchReuse reuse = BatchReuse::kFresh) {
    RunWriteBenchmark(state, arrow::schema({field}), SingleColumnBatch(make_column), rows_per_batch,
                      options, kDefaultCompression, total_rows, reuse);
}

void BM_ParquetWrite_Int64(::benchmark::State& state) {
    RunColumnWriteBenchmark(state, MakeField("id", arrow::int64(), 0), &MakeInt64Column,
                            kRowsPerBatch, /*options=*/{});
}

void BM_ParquetWrite_Double(::benchmark::State& state) {
    RunColumnWriteBenchmark(state, MakeField("value", arrow::float64(), 0), &MakeDoubleColumn,
                            kRowsPerBatch, /*options=*/{});
}

void BM_ParquetWrite_Boolean(::benchmark::State& state) {
    RunColumnWriteBenchmark(state, MakeField("flag", arrow::boolean(), 0), &MakeBooleanColumn,
                            kRowsPerBatch, /*options=*/{});
}

void BM_ParquetWrite_String(::benchmark::State& state) {
    const int64_t cardinality = state.range(0);
    RunColumnWriteBenchmark(state, MakeField("name", arrow::utf8(), 0),
                            [cardinality](int64_t rows, int64_t offset) {
                                return MakeStringColumn(rows, offset, cardinality);
                            },
                            kRowsPerBatch, /*options=*/{});
}

// arg: number of distinct values. The flat control for BM_ParquetWrite_DictionaryInt32.
void BM_ParquetWrite_FlatInt32(::benchmark::State& state) {
    const int64_t cardinality = state.range(0);
    RunColumnWriteBenchmark(state, MakeField("value", arrow::int32(), 0),
                            [cardinality](int64_t rows, int64_t offset) {
                                return MakeInt32Column(rows, offset, cardinality);
                            },
                            kRowsPerBatch, /*options=*/{});
}

// arg: dictionary cardinality. Same values as BM_ParquetWrite_String at the same cardinality, but
// handed to the writer already dictionary-encoded - nothing in ParquetWriterBuilder rejects a
// dictionary arrow type, so the writer does reach this path - and the pair isolates what it saves
// when it can pass indices through instead of materializing every value.
void BM_ParquetWrite_DictionaryString(::benchmark::State& state) {
    const int64_t cardinality = state.range(0);
    RunColumnWriteBenchmark(state, MakeField("name", DictionaryStringType(), 0),
                            [cardinality](int64_t rows, int64_t offset) {
                                return MakeDictionaryStringColumn(rows, offset, cardinality);
                            },
                            kRowsPerBatch, /*options=*/{});
}

// arg: dictionary cardinality. The shape the append compaction rewrite actually produces, and the
// one BM_ParquetWrite_DictionaryString does not cover: there the schema itself is a DictionaryType,
// here the writer is built from a plain STRING schema - as a rewrite builds it, from the table's
// logical schema - and the batch arrives dictionary-encoded anyway. The delta against
// BM_ParquetWrite_String at the same cardinality is what the passthrough buys on the write side,
// including the per-batch schema fixup that recovers the encoding from the batch layout.
//
// One alphabet for the whole file, so the writer keeps writing indices: the favourable half of the
// passthrough. BM_ParquetWrite_ChangingDictionaryStringIntoStringSchema is the other half, and a
// rewrite of several input files lands between the two.
void BM_ParquetWrite_DictionaryStringIntoStringSchema(::benchmark::State& state) {
    const int64_t cardinality = state.range(0);
    RunWriteBenchmark(state, StringSchema(),
                      SingleEncodedColumnBatch([cardinality](int64_t rows, int64_t offset) {
                          return MakeDictionaryStringColumn(rows, offset, cardinality);
                      }),
                      kRowsPerBatch, /*options=*/{}, kDefaultCompression);
}

// arg: dictionary cardinality. The same write, except every batch brings its own dictionary, as
// the input files of a compaction do, which is the cost of forwarding an encoding the writer
// cannot reuse. All three of BM_ParquetWrite_String,
// BM_ParquetWrite_DictionaryStringIntoStringSchema and this one write the same logical column at
// the same cardinality, so the triple reads directly: the middle one against the first is what the
// passthrough buys, this one against the middle is what the fallback costs in time, and this one
// against the first is the output size a rewrite that materialized and rebuilt would have produced.
// Row groups here are cut the way they are in production - by size and by the writer's memory
// limit, not at batch boundaries.
void BM_ParquetWrite_ChangingDictionaryStringIntoStringSchema(::benchmark::State& state) {
    const int64_t cardinality = state.range(0);
    RunWriteBenchmark(state, StringSchema(),
                      SingleEncodedColumnBatch([cardinality](int64_t rows, int64_t offset) {
                          return MakeChangingDictionaryStringColumn(rows, offset, cardinality);
                      }),
                      kRowsPerBatch, /*options=*/{}, kDefaultCompression);
}

// The same axis on an INTEGER dictionary, which arrow cannot direct-write - is_base_binary_like
// excludes int32, so it densifies first. Its baseline is BM_ParquetWrite_FlatInt32 at the same
// cardinality, not the String case: only the flat INT32 control holds value, width and encoding
// fixed, so only that delta is the materialization cost.
void BM_ParquetWrite_DictionaryInt32(::benchmark::State& state) {
    const int64_t cardinality = state.range(0);
    RunColumnWriteBenchmark(state, MakeField("value", DictionaryInt32Type(), 0),
                            [cardinality](int64_t rows, int64_t offset) {
                                return MakeDictionaryInt32Column(rows, offset, cardinality);
                            },
                            kRowsPerBatch, /*options=*/{});
}

// Same data with dictionary encoding turned off, as an encoding baseline.
void BM_ParquetWrite_StringNoDictionary(::benchmark::State& state) {
    const int64_t cardinality = state.range(0);
    std::map<std::string, std::string> options;
    options[paimon::parquet::PARQUET_ENABLE_DICTIONARY] = "false";
    RunColumnWriteBenchmark(
        state, MakeField("name", arrow::utf8(), 0),
        [cardinality](int64_t rows, int64_t offset) {
            return MakeStringColumn(rows, offset, cardinality);
        },
        kRowsPerBatch, options);
}

void BM_ParquetWrite_Decimal(::benchmark::State& state) {
    const auto precision = static_cast<int32_t>(state.range(0));
    RunColumnWriteBenchmark(state, MakeField("amount", arrow::decimal128(precision, 4), 0),
                            [precision](int64_t rows, int64_t offset) {
                                return MakeDecimalColumn(rows, offset, precision, /*scale=*/4);
                            },
                            kRowsPerBatch, /*options=*/{});
}

void BM_ParquetWrite_Struct(::benchmark::State& state) {
    RunColumnWriteBenchmark(state, MakeField("info", StructColumnType(), 0), &MakeStructColumn,
                            kRowsPerBatch, /*options=*/{});
}

void BM_ParquetWrite_List(::benchmark::State& state) {
    RunColumnWriteBenchmark(state, MakeField("tags", ListColumnType(), 0), &MakeListColumn,
                            kRowsPerBatch, /*options=*/{});
}

void BM_ParquetWrite_Vector(::benchmark::State& state) {
    RunColumnWriteBenchmark(state, MakeField("embedding", VectorColumnType(), 0), &MakeVectorColumn,
                            kRowsPerBatch, /*options=*/{});
}

// arg: entries per map row.
void BM_ParquetWrite_Map(::benchmark::State& state) {
    const auto entries = static_cast<int32_t>(state.range(0));
    RunColumnWriteBenchmark(
        state, MakeField("attrs", MapColumnType(), 0),
        [entries](int64_t rows, int64_t offset) { return MakeMapColumn(rows, offset, entries); },
        kRowsPerBatch, /*options=*/{});
}

// arg: percentage of nulls. Every field is nullable, so the column is `optional` and definition
// levels are written at every density including zero; the sweep moves what arrow's null-free fast
// path is worth. BIGINT is the narrowest column, so levels are the largest share of what is left.
void BM_ParquetWrite_Nulls(::benchmark::State& state) {
    const int64_t null_pct = state.range(0);
    RunColumnWriteBenchmark(state, MakeField("id", arrow::int64(), 0),
                            NullableColumnFactory(&MakeInt64Column, null_pct), kRowsPerBatch,
                            /*options=*/{});
}

// arg: rows per AddBatch call, at a fixed total row count. Smaller batches mean the same data
// carries more per-batch fixed cost, and the file-level setup is amortized over more calls.
void BM_ParquetWrite_BatchSize(::benchmark::State& state) {
    RunColumnWriteBenchmark(state, MakeField("id", arrow::int64(), 0), &MakeInt64Column,
                            state.range(0), /*options=*/{});
}

// arg: number of columns at a fixed row count. With BM_ParquetWrite_BatchSize this separates the
// two ways per-AddBatch work grows - more calls, or more columns per call - where that work is
// AddBatch importing the C array plus arrow walking the schema, neither of which encodes a value.
void BM_ParquetWrite_ColumnCount(::benchmark::State& state) {
    const auto columns = static_cast<int32_t>(state.range(0));
    arrow::FieldVector fields;
    fields.reserve(columns);
    for (int32_t i = 0; i < columns; ++i) {
        fields.push_back(MakeField("c" + std::to_string(i), arrow::utf8(), i));
    }
    RunWriteBenchmark(state, arrow::schema(fields), &MakeWideBatch, kRowsPerBatch, /*options=*/{},
                      kDefaultCompression);
    state.counters["columns"] = ::benchmark::Counter(static_cast<double>(columns));
}

// arg: maximum rows per row group, the write-side half of BM_ParquetRead_Filtered - a row group
// is the unit the reader prunes, so more of them buys finer pruning at the cost of footer
// metadata, flush work and codec material. The byte-triggered counterpart is
// BM_ParquetWrite_MemoryThreshold.
void BM_ParquetWrite_RowGroupSize(::benchmark::State& state) {
    const int64_t row_group_length = state.range(0);
    std::map<std::string, std::string> options;
    options[paimon::parquet::PARQUET_WRITE_MAX_ROW_GROUP_LENGTH] = std::to_string(row_group_length);
    RunWriteBenchmark(state, FlatSchema(), &MakeFlatBatch, kRowsPerBatch, options,
                      kDefaultCompression);
}

// args: the parquet.writer.max.memory.use threshold in KiB, and the number of AddBatch calls.
// Unlike every other case here the file is not a fixed kRowsPerFile: batches are a fixed 10'000
// rows and the total grows with the batch count, because the question is whether retained size
// accumulates across batches until the writer cuts a row group. Holding the total fixed and
// shrinking the batch would measure AddBatch granularity instead, which is what
// BM_ParquetWrite_BatchSize already does. The input is low-cardinality dictionary data, where
// retained and flat size differ most, written as one batch object repeatedly rather than a fresh
// one each time so arrow sees the same dictionary rather than N equal ones.
//
// Nothing here sets a row-group row limit, so the byte threshold is the only thing that can
// trigger a flush. row_groups reports whether it fired at all; if it reads 1 everywhere the sweep
// measured nothing, and the unit test only covers the mechanism, not this particular setting.
void BM_ParquetWrite_MemoryThreshold(::benchmark::State& state) {
    constexpr int64_t kFlushRowsPerBatch = 10'000;
    std::map<std::string, std::string> options;
    options[paimon::parquet::PARQUET_WRITER_MAX_MEMORY_USE] = std::to_string(state.range(0) * 1024);
    RunColumnWriteBenchmark(
        state, MakeField("name", DictionaryStringType(), 0),
        [](int64_t rows, int64_t offset) {
            return MakeDictionaryStringColumn(rows, offset, kLowStringCardinality);
        },
        kFlushRowsPerBatch, options, kFlushRowsPerBatch * state.range(1), BatchReuse::kReused);
}

// Codec sweep over the mixed flat schema, so the CPU-versus-size trade shows on data that is not
// uniformly one type. Levels stay at the ParquetWriterBuilder defaults. The names are the ones
// Parquet accepts, not the ones arrow does: "lz4" resolves to arrow's LZ4_FRAME, which
// parquet::IsCodecSupported rejects, so the two framings Parquet defines are spelled out.
void BM_ParquetWrite_Compression(::benchmark::State& state, const char* compression) {
    RunWriteBenchmark(state, FlatSchema(), &MakeFlatBatch, kRowsPerBatch, /*options=*/{},
                      compression);
}

// Rows a read case has to materialize for its number to mean anything. Pruning is not precise, so
// a filtered case gets a range rather than an exact count. Without the bound, a fixture that
// silently stopped producing rows would just look fast.
struct RowExpectation {
    int64_t min = kRowsPerFile;
    int64_t max = kRowsPerFile;
};

void RunReadBenchmark(::benchmark::State& state, const ReadFixture& fixture,
                      const std::shared_ptr<arrow::Schema>& read_schema,
                      const std::shared_ptr<Predicate>& predicate,
                      const std::optional<RoaringBitmap32>& selection_bitmap,
                      const std::map<std::string, std::string>& options, int32_t batch_size,
                      const RowExpectation& expected = {}) {
    if (FailBenchmark(state, fixture.status())) {
        return;
    }

    ReadStats stats;
    Timer timer;
    for (auto _ : state) {
        Result<ReadStats> result =
            ReadParquetFile(fixture.fs(), fixture.path(), read_schema, predicate, selection_bitmap,
                            options, batch_size, fixture.arrow_pool());
        if (FailBenchmark(state, result.status())) {
            return;
        }
        stats = result.value();
    }
    if (stats.rows < expected.min || stats.rows > expected.max) {
        FailBenchmark(state, Status::Invalid("read " + std::to_string(stats.rows) +
                                             " rows, expected " + std::to_string(expected.min) +
                                             " to " + std::to_string(expected.max)));
        return;
    }

    const double elapsed_ns = timer.ElapsedNanos();
    ReportRowRate(state, stats.rows, elapsed_ns);
    // Normalized by what the file holds, not what this case materialized: pruning drops the
    // per-materialized-row numerator and denominator together, so ns_per_row and bytes_per_row can
    // rise while the run gets faster. Only a denominator every setting shares is comparable across
    // settings that prune by different amounts.
    const double total_input_rows =
        static_cast<double>(state.iterations()) * static_cast<double>(kRowsPerFile);
    if (total_input_rows > 0) {
        state.counters["ns_per_input_row"] = ::benchmark::Counter(elapsed_ns / total_input_rows);
        state.counters["bytes_per_input_row"] = ::benchmark::Counter(
            static_cast<double>(stats.storage_bytes) / static_cast<double>(kRowsPerFile));
    }
    ReportBytes(state, "read_bytes", static_cast<int64_t>(stats.storage_bytes), stats.rows);
    state.counters["rows_read"] = ::benchmark::Counter(static_cast<double>(stats.rows));
    state.counters["file_bytes"] = ::benchmark::Counter(static_cast<double>(fixture.file_bytes()));
    state.counters["row_groups"] =
        ::benchmark::Counter(static_cast<double>(stats.row_groups_total));
    state.counters["row_groups_after_filter"] =
        ::benchmark::Counter(static_cast<double>(stats.row_groups_after_filter));
    state.counters["batches"] = ::benchmark::Counter(static_cast<double>(stats.batches));
}

void BM_ParquetRead_FullScan(::benchmark::State& state) {
    RunReadBenchmark(state, FlatFixture(), FlatSchema(), /*predicate=*/nullptr,
                     /*selection_bitmap=*/std::nullopt, /*options=*/{}, kReadBatchSize);
}

// One column at a time, separating per-column transfer from materializing the whole row.
void BM_ParquetRead_Projection(::benchmark::State& state, const char* column) {
    std::shared_ptr<arrow::Field> field = FlatSchema()->GetFieldByName(column);
    if (!field) {
        FailBenchmark(state, Status::Invalid("unknown projection column"));
        return;
    }
    RunReadBenchmark(state, FlatFixture(), arrow::schema({field}), /*predicate=*/nullptr,
                     /*selection_bitmap=*/std::nullopt, /*options=*/{}, kReadBatchSize);
}

// args: percentage of rows the predicate keeps, and whether page-level pruning is on. The `id`
// column is ordered, so the surviving rows form a prefix; running both page-index settings makes
// the pruning gain attributable instead of merely visible.
void BM_ParquetRead_Filtered(::benchmark::State& state) {
    const int64_t threshold = kRowsPerFile * state.range(0) / 100;
    // `id` is ordered, so row-group statistics alone must already discard every group past the
    // threshold - that holds with page-index filtering off too. Bounding at the row-group grain
    // rather than at kRowsPerFile is what makes a pruning regression fail the case instead of
    // quietly reading the whole file.
    const int64_t row_group_bound =
        ((threshold + kRowGroupLength - 1) / kRowGroupLength) * kRowGroupLength;
    const bool enable_page_index = state.range(1) != 0;
    std::shared_ptr<Predicate> predicate = PredicateBuilder::LessThan(
        /*field_index=*/0, /*field_name=*/"id", FieldType::BIGINT, Literal(threshold));
    std::map<std::string, std::string> options;
    options[paimon::parquet::PARQUET_READ_ENABLE_PAGE_INDEX_FILTER] =
        enable_page_index ? "true" : "false";
    RunReadBenchmark(state, FlatFixture(), FlatSchema(), predicate,
                     /*selection_bitmap=*/std::nullopt, options, kReadBatchSize,
                     RowExpectation{threshold, row_group_bound});
}

// arg: distance between selected rows. The strides straddle the coalesce hole limit (32 rows by
// default), which splits this into two regimes: at or below it neighbouring single-row ranges
// merge into long spans, so rows_read runs far ahead of selected_rows and nothing is skipped;
// above it every row stays its own range and arrow's Skip decodes and discards each gap instead.
// Compare read_bytes and ns_per_input_row across the two.
void BM_ParquetRead_SkipHeavy(::benchmark::State& state) {
    const int64_t stride = state.range(0);
    RoaringBitmap32 bitmap;
    for (int64_t row = 0; row < kRowsPerFile; row += stride) {
        bitmap.Add(static_cast<int32_t>(row));
    }
    const int64_t selected = bitmap.Cardinality();
    state.counters["selected_rows"] = ::benchmark::Counter(static_cast<double>(selected));
    RunReadBenchmark(state, FlatFixture(), FlatSchema(), /*predicate=*/nullptr, bitmap,
                     /*options=*/{}, kReadBatchSize, RowExpectation{selected, kRowsPerFile});
}

// arg: percentage of nulls, the read side of BM_ParquetWrite_Nulls: definition levels have to be
// decoded back into a validity bitmap, and past some density arrow may do less work, not more.
void BM_ParquetRead_Nulls(::benchmark::State& state) {
    RunReadBenchmark(state, NullableFlatFixture(state.range(0)), FlatSchema(),
                     /*predicate=*/nullptr, /*selection_bitmap=*/std::nullopt, /*options=*/{},
                     kReadBatchSize);
}

// The VARCHAR column from a dictionary-encoded file and from a plain-encoded one. Both are
// decoded by arrow, so this is arrow's dictionary path against its plain path on equal values.
void BM_ParquetRead_Encoding(::benchmark::State& state, bool enable_dictionary) {
    std::shared_ptr<arrow::Field> field = FlatSchema()->GetFieldByName("name");
    RunReadBenchmark(state, enable_dictionary ? FlatFixture() : PlainFlatFixture(),
                     arrow::schema({field}), /*predicate=*/nullptr,
                     /*selection_bitmap=*/std::nullopt, /*options=*/{}, kReadBatchSize);
}

// args: string cardinality, and whether the parquet dictionary passthrough is on. With it on, a
// column the file stores dictionary-encoded end to end is handed back as a DictionaryArray instead
// of one materialized value per row, so the pair at a fixed cardinality is what the read half of
// the compaction rewrite saves. At a cardinality high enough that the writer fell back to plain,
// the gate declines and the two runs measure the same work - a divergence there means the gate
// stopped looking at the data page encodings and started trusting the dictionary page.
void BM_ParquetRead_DictionaryPassthrough(::benchmark::State& state) {
    const int64_t cardinality = state.range(0);
    const bool enable_passthrough = state.range(1) != 0;
    std::map<std::string, std::string> options;
    options[paimon::parquet::PARQUET_READ_ENABLE_DICTIONARY_PASSTHROUGH] =
        enable_passthrough ? "true" : "false";
    RunReadBenchmark(state, StringFixture(cardinality), StringSchema(), /*predicate=*/nullptr,
                     /*selection_bitmap=*/std::nullopt, options, kReadBatchSize);
}

// arg: decimal precision, the read side of BM_ParquetWrite_Decimal. Precision picks the physical
// type - INT32, INT64 or FIXED_LEN_BYTE_ARRAY, since ParquetWriterBuilder enables
// store_decimal_as_integer - and the three take different paths back to Decimal128Array.
void BM_ParquetRead_Decimal(::benchmark::State& state) {
    const auto precision = static_cast<int32_t>(state.range(0));
    RunReadBenchmark(state, DecimalFixture(precision), DecimalSchema(precision),
                     /*predicate=*/nullptr, /*selection_bitmap=*/std::nullopt, /*options=*/{},
                     kReadBatchSize);
}

void BM_ParquetRead_Double(::benchmark::State& state) {
    RunReadBenchmark(state, DoubleFixture(), DoubleSchema(), /*predicate=*/nullptr,
                     /*selection_bitmap=*/std::nullopt, /*options=*/{}, kReadBatchSize);
}

// arg: rows per NextBatch call. At a fixed row count this turns the per-batch fixed cost of
// ParquetFileBatchReader::NextBatch - Validate, the two metrics counters, the ArrowSchema
// export - into a number, separated from the per-row decoding cost.
void BM_ParquetRead_BatchSize(::benchmark::State& state) {
    RunReadBenchmark(state, FlatFixture(), FlatSchema(), /*predicate=*/nullptr,
                     /*selection_bitmap=*/std::nullopt, /*options=*/{},
                     static_cast<int32_t>(state.range(0)));
}

// Each nested column costs definition and repetition levels a flat column does not pay.
void BM_ParquetRead_Nested(::benchmark::State& state, const char* column) {
    std::shared_ptr<arrow::Schema> full_schema = NestedReadSchema();
    std::shared_ptr<arrow::Schema> read_schema = full_schema;
    if (column != nullptr) {
        std::shared_ptr<arrow::Field> field = full_schema->GetFieldByName(column);
        if (!field) {
            FailBenchmark(state, Status::Invalid("unknown nested column"));
            return;
        }
        read_schema = arrow::schema({field});
    }
    RunReadBenchmark(state, NestedFixture(), read_schema, /*predicate=*/nullptr,
                     /*selection_bitmap=*/std::nullopt, /*options=*/{}, kReadBatchSize);
}

}  // namespace

BENCHMARK(BM_ParquetWrite_Int64)->Unit(benchmark::kMillisecond)->UseRealTime();
BENCHMARK(BM_ParquetWrite_Double)->Unit(benchmark::kMillisecond)->UseRealTime();
BENCHMARK(BM_ParquetWrite_Boolean)->Unit(benchmark::kMillisecond)->UseRealTime();
BENCHMARK(BM_ParquetWrite_String)
    ->ArgName("cardinality")
    ->Arg(10)
    ->Arg(1000)
    ->Arg(kRowsPerFile)
    ->Unit(benchmark::kMillisecond)
    ->UseRealTime();
BENCHMARK(BM_ParquetWrite_StringNoDictionary)
    ->ArgName("cardinality")
    ->Arg(10)
    ->Arg(1000)
    ->Arg(kRowsPerFile)
    ->Unit(benchmark::kMillisecond)
    ->UseRealTime();
BENCHMARK(BM_ParquetWrite_FlatInt32)
    ->ArgName("cardinality")
    ->Arg(10)
    ->Arg(100)
    ->Arg(1000)
    ->Arg(10000)
    ->Unit(benchmark::kMillisecond)
    ->UseRealTime();
BENCHMARK(BM_ParquetWrite_DictionaryString)
    ->ArgName("cardinality")
    ->Arg(10)
    ->Arg(100)
    ->Arg(1000)
    ->Arg(10000)
    ->Unit(benchmark::kMillisecond)
    ->UseRealTime();
// Same cardinality axis as BM_ParquetWrite_String and BM_ParquetWrite_StringNoDictionary, which
// are its baselines: the three have to line up point for point or the low/medium/high comparison
// cannot be made.
BENCHMARK(BM_ParquetWrite_DictionaryStringIntoStringSchema)
    ->ArgName("cardinality")
    ->Arg(10)
    ->Arg(1000)
    ->Arg(kRowsPerFile)
    ->Unit(benchmark::kMillisecond)
    ->UseRealTime();
// Same axis again, so the three points can be read against the run above them.
BENCHMARK(BM_ParquetWrite_ChangingDictionaryStringIntoStringSchema)
    ->ArgName("cardinality")
    ->Arg(10)
    ->Arg(1000)
    ->Arg(kRowsPerFile)
    ->Unit(benchmark::kMillisecond)
    ->UseRealTime();
BENCHMARK(BM_ParquetWrite_DictionaryInt32)
    ->ArgName("cardinality")
    ->Arg(10)
    ->Arg(100)
    ->Arg(1000)
    ->Arg(10000)
    ->Unit(benchmark::kMillisecond)
    ->UseRealTime();
BENCHMARK(BM_ParquetWrite_Decimal)
    ->ArgName("precision")
    ->Arg(9)
    ->Arg(18)
    ->Arg(38)
    ->Unit(benchmark::kMillisecond)
    ->UseRealTime();
BENCHMARK(BM_ParquetWrite_Struct)->Unit(benchmark::kMillisecond)->UseRealTime();
BENCHMARK(BM_ParquetWrite_List)->Unit(benchmark::kMillisecond)->UseRealTime();
BENCHMARK(BM_ParquetWrite_Vector)->Unit(benchmark::kMillisecond)->UseRealTime();
BENCHMARK(BM_ParquetWrite_Map)
    ->ArgName("entries")
    ->Arg(3)
    ->Arg(5)
    ->Arg(10)
    ->Unit(benchmark::kMillisecond)
    ->UseRealTime();
BENCHMARK(BM_ParquetWrite_Nulls)
    ->ArgName("null_pct")
    ->Arg(0)
    ->Arg(20)
    ->Arg(50)
    ->Arg(70)
    ->Arg(100)
    ->Unit(benchmark::kMillisecond)
    ->UseRealTime();
BENCHMARK(BM_ParquetWrite_BatchSize)
    ->ArgName("rows_per_batch")
    ->Arg(100)
    ->Arg(1000)
    ->Arg(10000)
    ->Unit(benchmark::kMillisecond)
    ->UseRealTime();
BENCHMARK(BM_ParquetWrite_ColumnCount)
    ->ArgName("columns")
    ->Arg(1)
    ->Arg(5)
    ->Arg(10)
    ->Arg(20)
    ->Unit(benchmark::kMillisecond)
    ->UseRealTime();
BENCHMARK(BM_ParquetWrite_RowGroupSize)
    ->ArgName("row_group_rows")
    ->Arg(5000)
    ->Arg(25000)
    ->Arg(kRowsPerFile)
    ->Unit(benchmark::kMillisecond)
    ->UseRealTime();
BENCHMARK(BM_ParquetWrite_MemoryThreshold)
    ->ArgNames({"max_memory_kib", "batches"})
    ->Args({512, 50})
    ->Args({512, 200})
    ->Args({4096, 200})
    ->Args({65536, 200})
    ->Unit(benchmark::kMillisecond)
    ->UseRealTime();
BENCHMARK_CAPTURE(BM_ParquetWrite_Compression, none, "none")
    ->Unit(benchmark::kMillisecond)
    ->UseRealTime();
BENCHMARK_CAPTURE(BM_ParquetWrite_Compression, snappy, "snappy")
    ->Unit(benchmark::kMillisecond)
    ->UseRealTime();
BENCHMARK_CAPTURE(BM_ParquetWrite_Compression, gzip, "gzip")
    ->Unit(benchmark::kMillisecond)
    ->UseRealTime();
BENCHMARK_CAPTURE(BM_ParquetWrite_Compression, lz4_raw, "lz4_raw")
    ->Unit(benchmark::kMillisecond)
    ->UseRealTime();
BENCHMARK_CAPTURE(BM_ParquetWrite_Compression, lz4_hadoop, "lz4_hadoop")
    ->Unit(benchmark::kMillisecond)
    ->UseRealTime();
BENCHMARK_CAPTURE(BM_ParquetWrite_Compression, brotli, "brotli")
    ->Unit(benchmark::kMillisecond)
    ->UseRealTime();
BENCHMARK_CAPTURE(BM_ParquetWrite_Compression, zstd, "zstd")
    ->Unit(benchmark::kMillisecond)
    ->UseRealTime();

BENCHMARK(BM_ParquetRead_FullScan)->Unit(benchmark::kMillisecond)->UseRealTime();
BENCHMARK_CAPTURE(BM_ParquetRead_Projection, id, "id")
    ->Unit(benchmark::kMillisecond)
    ->UseRealTime();
BENCHMARK_CAPTURE(BM_ParquetRead_Projection, name, "name")
    ->Unit(benchmark::kMillisecond)
    ->UseRealTime();
BENCHMARK_CAPTURE(BM_ParquetRead_Projection, amount, "amount")
    ->Unit(benchmark::kMillisecond)
    ->UseRealTime();
BENCHMARK(BM_ParquetRead_Filtered)
    ->ArgNames({"keep_pct", "page_index"})
    ->Args({1, 1})
    ->Args({1, 0})
    ->Args({10, 1})
    ->Args({10, 0})
    ->Args({50, 1})
    ->Args({50, 0})
    ->Unit(benchmark::kMillisecond)
    ->UseRealTime();
BENCHMARK(BM_ParquetRead_SkipHeavy)
    ->ArgName("stride")
    ->Arg(8)
    ->Arg(32)
    ->Arg(64)
    ->Arg(512)
    ->Arg(4096)
    ->Unit(benchmark::kMillisecond)
    ->UseRealTime();
BENCHMARK(BM_ParquetRead_Nulls)
    ->ArgName("null_pct")
    ->Arg(0)
    ->Arg(20)
    ->Arg(50)
    ->Arg(70)
    ->Arg(100)
    ->Unit(benchmark::kMillisecond)
    ->UseRealTime();
BENCHMARK_CAPTURE(BM_ParquetRead_Encoding, dictionary, true)
    ->Unit(benchmark::kMillisecond)
    ->UseRealTime();
BENCHMARK_CAPTURE(BM_ParquetRead_Encoding, plain, false)
    ->Unit(benchmark::kMillisecond)
    ->UseRealTime();
// The same cardinality axis the write cases use, so the read and write halves of a rewrite can be
// added up at each point. At kRowsPerFile every value is distinct, which overflows
// kDictionaryPageSizeBytes and is the point where the gate has to decline.
BENCHMARK(BM_ParquetRead_DictionaryPassthrough)
    ->ArgNames({"cardinality", "passthrough"})
    ->Args({10, 0})
    ->Args({10, 1})
    ->Args({1000, 0})
    ->Args({1000, 1})
    ->Args({kRowsPerFile, 0})
    ->Args({kRowsPerFile, 1})
    ->Unit(benchmark::kMillisecond)
    ->UseRealTime();
BENCHMARK(BM_ParquetRead_Decimal)
    ->ArgName("precision")
    ->Arg(9)
    ->Arg(18)
    ->Arg(38)
    ->Unit(benchmark::kMillisecond)
    ->UseRealTime();
BENCHMARK(BM_ParquetRead_Double)->Unit(benchmark::kMillisecond)->UseRealTime();
BENCHMARK(BM_ParquetRead_BatchSize)
    ->ArgName("batch_size")
    ->Arg(512)
    ->Arg(4096)
    ->Arg(16384)
    ->Unit(benchmark::kMillisecond)
    ->UseRealTime();
BENCHMARK_CAPTURE(BM_ParquetRead_Nested, info_struct, "info")
    ->Unit(benchmark::kMillisecond)
    ->UseRealTime();
BENCHMARK_CAPTURE(BM_ParquetRead_Nested, tags_list, "tags")
    ->Unit(benchmark::kMillisecond)
    ->UseRealTime();
BENCHMARK_CAPTURE(BM_ParquetRead_Nested, embedding_vector, "embedding")
    ->Unit(benchmark::kMillisecond)
    ->UseRealTime();
BENCHMARK_CAPTURE(BM_ParquetRead_Nested, attrs_map, "attrs")
    ->Unit(benchmark::kMillisecond)
    ->UseRealTime();
BENCHMARK_CAPTURE(BM_ParquetRead_Nested, all_columns, nullptr)
    ->Unit(benchmark::kMillisecond)
    ->UseRealTime();

int main(int argc, char** argv) {
    ::benchmark::Initialize(&argc, argv);
    if (::benchmark::ReportUnrecognizedArguments(argc, argv)) {
        return 1;
    }
    ::benchmark::RunSpecifiedBenchmarks();
    ::benchmark::Shutdown();
    return g_failed.load() ? 1 : 0;
}
