// 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.

#include "meta-store/document_message.h"

#include <bthread/bthread.h>
#include <fmt/format.h>
#include <foundationdb/fdb_c_options.g.h>
#include <gen_cpp/cloud.pb.h>
#include <gen_cpp/olap_common.pb.h>
#include <gen_cpp/olap_file.pb.h>
#include <gtest/gtest.h>

#include <iostream>
#include <memory>
#include <mutex>
#include <string>
#include <string_view>

#include "common/config.h"
#include "common/util.h"
#include "meta-store/document_message_get_range.h"
#include "meta-store/keys.h"
#include "meta-store/mem_txn_kv.h"
#include "meta-store/txn_kv.h"
#include "meta-store/txn_kv_error.h"
#include "meta-store/versionstamp.h"

using namespace doris::cloud;

static std::mutex config_mutex;

int main(int argc, char** argv) {
    config::init(nullptr, true);
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

// Convert a string to a hex-escaped string.
// A non-displayed character is represented as \xHH where HH is the hexadecimal value of the character.
// A displayed character is represented as itself.
static std::string escape_hex(std::string_view data) {
    std::string result;
    for (char c : data) {
        if (isprint(c)) {
            result += c;
        } else {
            result += fmt::format("\\x{:02x}", static_cast<unsigned char>(c));
        }
    }
    return result;
}

static size_t count_range(TxnKv* txn_kv, std::string_view begin = "",
                          std::string_view end = "\xFF") {
    std::unique_ptr<Transaction> txn;
    EXPECT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
    if (!txn) {
        return 0; // Failed to create transaction
    }

    FullRangeGetOptions opts;
    opts.txn = txn.get();
    auto iter = txn_kv->full_range_get(std::string(begin), std::string(end), std::move(opts));
    size_t total = 0;
    for (auto&& kvp = iter->next(); kvp.has_value(); kvp = iter->next()) {
        total += 1;
    }

    EXPECT_TRUE(iter->is_valid()); // The iterator should still be valid after the next call.
    return total;
}

static bool is_empty_range(TxnKv* txn_kv, std::string_view begin = "",
                           std::string_view end = "\xFF") {
    return count_range(txn_kv, begin, end) == 0;
}

static std::string dump_range(TxnKv* txn_kv, std::string_view begin = "",
                              std::string_view end = "\xFF") {
    std::unique_ptr<Transaction> txn;
    if (txn_kv->create_txn(&txn) != TxnErrorCode::TXN_OK) {
        return "Failed to create dump range transaction";
    }
    FullRangeGetOptions opts;
    opts.txn = txn.get();
    auto iter = txn_kv->full_range_get(std::string(begin), std::string(end), std::move(opts));
    std::string buffer;
    for (auto&& kv = iter->next(); kv.has_value(); kv = iter->next()) {
        buffer +=
                fmt::format("Key: {}, Value: {}\n", escape_hex(kv->first), escape_hex(kv->second));
    }
    EXPECT_TRUE(iter->is_valid()); // The iterator should still be valid after the next call.
    return buffer;
}

TEST(DocumentMessageTest, SplitSingleMessage) {
    auto txn_kv = std::make_shared<MemTxnKv>();
    {
        // Write a message that does not need to be split.
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        SplitSingleMessagePB msg;
        msg.set_other_fields(1);
        ASSERT_TRUE(document_put(txn.get(), "split_single_message_key", std::move(msg)));
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);

        // Read the message back.
        std::unique_ptr<Transaction> read_txn;
        ASSERT_EQ(txn_kv->create_txn(&read_txn), TxnErrorCode::TXN_OK);
        SplitSingleMessagePB read_msg;
        ASSERT_EQ(document_get(read_txn.get(), "split_single_message_key", &read_msg),
                  TxnErrorCode::TXN_OK);
        ASSERT_EQ(read_msg.other_fields(), 1);

        ASSERT_EQ(count_range(txn_kv.get()), 1) << dump_range(txn_kv.get());

        // Remove the message.
        document_remove<SplitSingleMessagePB>(read_txn.get(), "split_single_message_key");
        ASSERT_EQ(read_txn->commit(), TxnErrorCode::TXN_OK);
    }

    ASSERT_TRUE(is_empty_range(txn_kv.get())) << dump_range(txn_kv.get());

    {
        // Write a message that needs to be split.
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        SplitSingleMessagePB msg;
        msg.set_other_fields(2);
        auto* key_bounds = msg.mutable_segment_key_bounds();
        key_bounds->set_min_key("min_key");
        key_bounds->set_max_key("max_key");

        ASSERT_TRUE(document_put(txn.get(), "split_single_message_key_split", std::move(msg)));
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);

        // Read the message back.
        std::unique_ptr<Transaction> read_txn;
        ASSERT_EQ(txn_kv->create_txn(&read_txn), TxnErrorCode::TXN_OK);
        SplitSingleMessagePB read_msg;
        ASSERT_EQ(document_get(read_txn.get(), "split_single_message_key_split", &read_msg),
                  TxnErrorCode::TXN_OK);
        ASSERT_EQ(read_msg.other_fields(), 2);
        ASSERT_EQ(read_msg.segment_key_bounds().min_key(), "min_key");
        ASSERT_EQ(read_msg.segment_key_bounds().max_key(), "max_key");
        ASSERT_EQ(count_range(txn_kv.get()), 2) << dump_range(txn_kv.get());

        // Remove the message.
        document_remove<SplitSingleMessagePB>(read_txn.get(), "split_single_message_key_split");
        ASSERT_EQ(read_txn->commit(), TxnErrorCode::TXN_OK);
    }

    ASSERT_TRUE(is_empty_range(txn_kv.get())) << dump_range(txn_kv.get());
}

TEST(DocumentMessageTest, DocumentPutRowsetMeta) {
    std::unique_lock lock(config_mutex);
    config::enable_split_rowset_meta_pb = true;
    config::split_rowset_meta_pb_size = 0; // Always split the rowset meta pb.

    auto txn_kv = std::make_shared<MemTxnKv>();
    doris::RowsetMetaCloudPB meta;
    meta.set_rowset_id(123);
    meta.set_rowset_id_v2("document_put_rowset_meta");
    meta.set_start_version(10000);
    meta.set_end_version(10005);
    meta.set_num_rows(100);
    meta.set_num_segments(1);
    doris::KeyBoundsPB* key_bounds = meta.mutable_segments_key_bounds()->Add();
    key_bounds->set_min_key("min_key");
    key_bounds->set_max_key("max_key");
    key_bounds = meta.mutable_segments_key_bounds()->Add();
    key_bounds->set_min_key("min_key2");
    key_bounds->set_max_key("max_key2");

    std::string rowset_meta_key =
            meta_rowset_key({meta.rowset_id_v2(), meta.end_version(), meta.num_segments()});
    {
        // create a txn , and put rowset meta
        doris::RowsetMetaCloudPB meta_copy(meta);
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        ASSERT_TRUE(document_put(txn.get(), rowset_meta_key, std::move(meta_copy)));
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    {
        // create a txn , and get rowset meta
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        doris::RowsetMetaCloudPB saved_meta;
        ASSERT_EQ(document_get(txn.get(), rowset_meta_key, &saved_meta), TxnErrorCode::TXN_OK);
        ASSERT_EQ(saved_meta.rowset_id_v2(), meta.rowset_id_v2());
        ASSERT_EQ(saved_meta.end_version(), meta.end_version());
        ASSERT_EQ(saved_meta.start_version(), meta.start_version());
        ASSERT_EQ(saved_meta.num_rows(), meta.num_rows());
        ASSERT_EQ(saved_meta.num_segments(), meta.num_segments());
        ASSERT_EQ(saved_meta.segments_key_bounds_size(), 2);
        ASSERT_EQ(saved_meta.segments_key_bounds(0).min_key(), "min_key");
        ASSERT_EQ(saved_meta.segments_key_bounds(0).max_key(), "max_key");
        ASSERT_EQ(saved_meta.segments_key_bounds(1).min_key(), "min_key2");
        ASSERT_EQ(saved_meta.segments_key_bounds(1).max_key(), "max_key2");
    }

    ASSERT_GE(txn_kv->total_kvs(), 2) << dump_range(txn_kv.get());

    {
        // create a txn, and remove rowset meta
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        document_remove<doris::RowsetMetaCloudPB>(txn.get(), rowset_meta_key);
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    ASSERT_TRUE(is_empty_range(txn_kv.get())) << dump_range(txn_kv.get());
}

TEST(DocumentMessageTest, DocumentPutRowsetMetaWithoutSplit) {
    std::unique_lock lock(config_mutex);
    config::enable_split_rowset_meta_pb = false;

    auto txn_kv = std::make_shared<MemTxnKv>();
    doris::RowsetMetaCloudPB meta;
    meta.set_rowset_id(123);
    meta.set_rowset_id_v2("document_put_rowset_meta");
    meta.set_start_version(10000);
    meta.set_end_version(10005);
    meta.set_num_rows(100);
    meta.set_num_segments(1);
    doris::KeyBoundsPB* key_bounds = meta.mutable_segments_key_bounds()->Add();
    key_bounds->set_min_key("min_key");
    key_bounds->set_max_key("max_key");

    std::string rowset_meta_key =
            meta_rowset_key({meta.rowset_id_v2(), meta.end_version(), meta.num_segments()});
    {
        // create a txn , and put rowset meta
        doris::RowsetMetaCloudPB meta_copy(meta);
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        ASSERT_TRUE(document_put(txn.get(), rowset_meta_key, std::move(meta_copy)));
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    {
        // create a txn , and get rowset meta
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        doris::RowsetMetaCloudPB saved_meta;
        ASSERT_EQ(document_get(txn.get(), rowset_meta_key, &saved_meta), TxnErrorCode::TXN_OK);
        ASSERT_EQ(saved_meta.rowset_id_v2(), meta.rowset_id_v2());
        ASSERT_EQ(saved_meta.end_version(), meta.end_version());
        ASSERT_EQ(saved_meta.start_version(), meta.start_version());
        ASSERT_EQ(saved_meta.num_rows(), meta.num_rows());
        ASSERT_EQ(saved_meta.num_segments(), meta.num_segments());
        ASSERT_EQ(saved_meta.segments_key_bounds_size(), 1);
        ASSERT_EQ(saved_meta.segments_key_bounds(0).min_key(), "min_key");
        ASSERT_EQ(saved_meta.segments_key_bounds(0).max_key(), "max_key");
    }

    ASSERT_EQ(txn_kv->total_kvs(), 1) << dump_range(txn_kv.get());

    {
        // create a txn, and remove rowset meta
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        document_remove<doris::RowsetMetaCloudPB>(txn.get(), rowset_meta_key);
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    ASSERT_TRUE(is_empty_range(txn_kv.get())) << dump_range(txn_kv.get());

    {
        // Allow split but no thing to split, because the rowset meta pb is small enough.
        config::enable_split_rowset_meta_pb = true;
        config::split_rowset_meta_pb_size = 100000000; // Big enough to not split.
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        doris::RowsetMetaCloudPB meta_copy(meta);
        ASSERT_TRUE(document_put(txn.get(), rowset_meta_key, std::move(meta_copy)));
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);

        // Read the message back.
        std::unique_ptr<Transaction> read_txn;
        ASSERT_EQ(txn_kv->create_txn(&read_txn), TxnErrorCode::TXN_OK);
        doris::RowsetMetaCloudPB read_meta;
        ASSERT_EQ(document_get(read_txn.get(), rowset_meta_key, &read_meta), TxnErrorCode::TXN_OK);
        ASSERT_EQ(read_meta.rowset_id_v2(), meta.rowset_id_v2());
        ASSERT_EQ(read_meta.end_version(), meta.end_version());
        ASSERT_EQ(read_meta.start_version(), meta.start_version());
        ASSERT_EQ(read_meta.num_rows(), meta.num_rows());
        ASSERT_EQ(read_meta.num_segments(), meta.num_segments());
        ASSERT_EQ(read_meta.segments_key_bounds_size(), 1);
        ASSERT_EQ(read_meta.segments_key_bounds(0).min_key(), "min_key");
        ASSERT_EQ(read_meta.segments_key_bounds(0).max_key(), "max_key");

        // Remove the message.
        document_remove<doris::RowsetMetaCloudPB>(read_txn.get(), rowset_meta_key);
        ASSERT_EQ(read_txn->commit(), TxnErrorCode::TXN_OK);
    }

    {
        // Allow split but no thing to split, because the split fields is empty.
        config::enable_split_rowset_meta_pb = true;
        config::split_rowset_meta_pb_size = 0; // Always split the rowset meta pb.
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        doris::RowsetMetaCloudPB meta_copy(meta);
        meta_copy.clear_segments_key_bounds(); // Clear the segments key bounds to make it empty.
        ASSERT_TRUE(document_put(txn.get(), rowset_meta_key, std::move(meta_copy)));
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);

        // If you meat a failed here, it means the rowset meta pb is split into multiple keys,
        // you should clear the split fields you added.
        ASSERT_EQ(txn_kv->total_kvs(), 1) << dump_range(txn_kv.get());

        // Read the message back.
        std::unique_ptr<Transaction> read_txn;
        ASSERT_EQ(txn_kv->create_txn(&read_txn), TxnErrorCode::TXN_OK);
        doris::RowsetMetaCloudPB read_meta;
        ASSERT_EQ(document_get(read_txn.get(), rowset_meta_key, &read_meta), TxnErrorCode::TXN_OK);
        ASSERT_EQ(read_meta.rowset_id_v2(), meta.rowset_id_v2());
        ASSERT_EQ(read_meta.end_version(), meta.end_version());
        ASSERT_EQ(read_meta.start_version(), meta.start_version());
        ASSERT_EQ(read_meta.num_rows(), meta.num_rows());
        ASSERT_EQ(read_meta.num_segments(), meta.num_segments());
        ASSERT_EQ(read_meta.segments_key_bounds_size(), 0); // No segments key bounds
        // Remove the message.
        document_remove<doris::RowsetMetaCloudPB>(read_txn.get(), rowset_meta_key);
        ASSERT_EQ(read_txn->commit(), TxnErrorCode::TXN_OK);
    }

    ASSERT_TRUE(is_empty_range(txn_kv.get())) << dump_range(txn_kv.get());
}

TEST(DocumentMessageTest, DocumentPutTabletSchemaCloudPB) {
    std::unique_lock lock(config_mutex);
    config::enable_split_tablet_schema_pb = true;
    config::split_tablet_schema_pb_size = 0; // Always split the tablet schema pb.

    auto txn_kv = std::make_shared<MemTxnKv>();
    doris::TabletSchemaCloudPB schema;
    schema.set_keys_type(doris::DUP_KEYS);
    schema.set_num_short_key_columns(2);
    schema.set_num_rows_per_row_block(1024);
    schema.set_compress_kind(doris::COMPRESS_LZ4);
    schema.set_next_column_unique_id(10);
    schema.set_schema_version(1);

    // Add multiple columns to test splitting
    for (int i = 0; i < 3; ++i) {
        doris::ColumnPB* column = schema.add_column();
        column->set_name(fmt::format("col_{}", i));
        column->set_unique_id(i + 1);
        column->set_type("INT");
        column->set_is_key(i < 2); // First 2 columns are key columns
        column->set_is_nullable(false);
    }

    std::string schema_key = versioned::meta_schema_key({"instance_id", 10, 0});
    {
        // create a txn and put tablet schema
        doris::TabletSchemaCloudPB schema_copy(schema);
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        ASSERT_TRUE(document_put(txn.get(), schema_key, std::move(schema_copy)));
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    {
        // create a txn and get tablet schema
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        doris::TabletSchemaCloudPB saved_schema;
        ASSERT_EQ(document_get(txn.get(), schema_key, &saved_schema), TxnErrorCode::TXN_OK);
        ASSERT_EQ(saved_schema.keys_type(), schema.keys_type());
        ASSERT_EQ(saved_schema.num_short_key_columns(), schema.num_short_key_columns());
        ASSERT_EQ(saved_schema.num_rows_per_row_block(), schema.num_rows_per_row_block());
        ASSERT_EQ(saved_schema.compress_kind(), schema.compress_kind());
        ASSERT_EQ(saved_schema.next_column_unique_id(), schema.next_column_unique_id());
        ASSERT_EQ(saved_schema.schema_version(), schema.schema_version());
        ASSERT_EQ(saved_schema.column_size(), 3);
        for (int i = 0; i < 3; ++i) {
            ASSERT_EQ(saved_schema.column(i).name(), fmt::format("col_{}", i));
            ASSERT_EQ(saved_schema.column(i).unique_id(), i + 1);
            ASSERT_EQ(saved_schema.column(i).type(), "INT");
            ASSERT_EQ(saved_schema.column(i).is_key(), i < 2);
            ASSERT_EQ(saved_schema.column(i).is_nullable(), false);
        }
    }

    ASSERT_GE(txn_kv->total_kvs(), 2) << dump_range(txn_kv.get());

    {
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);

        std::string begin_key = versioned::meta_schema_key({"instance_id", 10, 0});
        std::string end_key = versioned::meta_schema_key({"instance_id", 10, INT64_MAX});
        FullRangeGetOptions options;
        std::unique_ptr<FullRangeGetIterator> iter =
                txn->full_range_get(begin_key, end_key, std::move(options));
        for (auto kvp = iter->next(); kvp.has_value(); kvp = iter->next()) {
            auto&& [key, _] = *kvp;
            int64_t decode_index_id = -1;
            int64_t schema_version = -1;
            std::string_view key_view(key);
            ASSERT_TRUE(versioned::decode_meta_schema_key(&key_view, &decode_index_id,
                                                          &schema_version));
            ASSERT_EQ(10, decode_index_id);
            ASSERT_EQ(0, schema_version);
        }
    }

    {
        // create a txn and remove tablet schema
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        document_remove<doris::TabletSchemaCloudPB>(txn.get(), schema_key);
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    ASSERT_TRUE(is_empty_range(txn_kv.get())) << dump_range(txn_kv.get());
}

TEST(DocumentMessageTest, DocumentPutTabletSchemaCloudPBWithoutSplit) {
    std::unique_lock lock(config_mutex);
    config::enable_split_tablet_schema_pb = false;

    auto txn_kv = std::make_shared<MemTxnKv>();
    doris::TabletSchemaCloudPB schema;
    schema.set_keys_type(doris::DUP_KEYS);
    schema.set_num_short_key_columns(1);
    schema.set_num_rows_per_row_block(1024);
    schema.set_compress_kind(doris::COMPRESS_LZ4);
    schema.set_next_column_unique_id(5);
    schema.set_schema_version(1);

    // Add one column
    doris::ColumnPB* column = schema.add_column();
    column->set_name("test_col");
    column->set_unique_id(1);
    column->set_type("VARCHAR");
    column->set_is_key(true);
    column->set_is_nullable(false);

    std::string schema_key = "tablet_schema_key_no_split";
    {
        // create a txn and put tablet schema
        doris::TabletSchemaCloudPB schema_copy(schema);
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        ASSERT_TRUE(document_put(txn.get(), schema_key, std::move(schema_copy)));
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    {
        // create a txn and get tablet schema
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        doris::TabletSchemaCloudPB saved_schema;
        ASSERT_EQ(document_get(txn.get(), schema_key, &saved_schema), TxnErrorCode::TXN_OK);
        ASSERT_EQ(saved_schema.keys_type(), schema.keys_type());
        ASSERT_EQ(saved_schema.num_short_key_columns(), schema.num_short_key_columns());
        ASSERT_EQ(saved_schema.column_size(), 1);
        ASSERT_EQ(saved_schema.column(0).name(), "test_col");
        ASSERT_EQ(saved_schema.column(0).unique_id(), 1);
        ASSERT_EQ(saved_schema.column(0).type(), "VARCHAR");
    }

    ASSERT_EQ(txn_kv->total_kvs(), 1) << dump_range(txn_kv.get());

    {
        // create a txn and remove tablet schema
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        document_remove<doris::TabletSchemaCloudPB>(txn.get(), schema_key);
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    ASSERT_TRUE(is_empty_range(txn_kv.get())) << dump_range(txn_kv.get());

    {
        // Allow split but nothing to split, because the split fields is empty.
        config::enable_split_tablet_schema_pb = true;
        config::split_tablet_schema_pb_size = 0; // Always split
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        doris::TabletSchemaCloudPB schema_copy(schema);
        schema_copy.clear_column(); // Clear the columns to make it empty.
        ASSERT_TRUE(document_put(txn.get(), schema_key, std::move(schema_copy)));
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);

        // If you meet a failure here, it means the tablet schema pb is split into multiple keys,
        // you should clear the split fields you added.
        ASSERT_EQ(txn_kv->total_kvs(), 1) << dump_range(txn_kv.get());

        // Read the message back.
        std::unique_ptr<Transaction> read_txn;
        ASSERT_EQ(txn_kv->create_txn(&read_txn), TxnErrorCode::TXN_OK);
        doris::TabletSchemaCloudPB read_schema;
        ASSERT_EQ(document_get(read_txn.get(), schema_key, &read_schema), TxnErrorCode::TXN_OK);
        ASSERT_EQ(read_schema.keys_type(), schema.keys_type());
        ASSERT_EQ(read_schema.num_short_key_columns(), schema.num_short_key_columns());
        ASSERT_EQ(read_schema.column_size(), 0); // No columns
        // Remove the message.
        document_remove<doris::TabletSchemaCloudPB>(read_txn.get(), schema_key);
        ASSERT_EQ(read_txn->commit(), TxnErrorCode::TXN_OK);
    }

    ASSERT_TRUE(is_empty_range(txn_kv.get())) << dump_range(txn_kv.get());
}

TEST(DocumentMessageTest, DocumentPutVersionPB) {
    auto txn_kv = std::make_shared<MemTxnKv>();
    VersionPB version_pb;
    version_pb.set_version(123);

    {
        // create a txn , and put version pb
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        ASSERT_TRUE(document_put(txn.get(), "version_key", std::move(version_pb)));
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    {
        // create a txn , and get version pb
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        VersionPB saved_version_pb;
        ASSERT_EQ(document_get(txn.get(), "version_key", &saved_version_pb), TxnErrorCode::TXN_OK);
        ASSERT_EQ(saved_version_pb.version(), 123);
    }

    ASSERT_EQ(txn_kv->total_kvs(), 1) << dump_range(txn_kv.get());

    {
        // create a txn, and remove version pb
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        document_remove<VersionPB>(txn.get(), "version_key");
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    ASSERT_TRUE(is_empty_range(txn_kv.get())) << dump_range(txn_kv.get());
}

TEST(DocumentMessageTest, DocumentGetAllRowsetMeta) {
    std::unique_lock lock(config_mutex);
    config::enable_split_rowset_meta_pb = true;
    config::split_rowset_meta_pb_size = 0; // Always split the rowset meta pb.

    auto txn_kv = std::make_shared<MemTxnKv>();
    doris::RowsetMetaCloudPB meta;
    meta.set_rowset_id(123);
    meta.set_rowset_id_v2("document_put_rowset_meta");
    meta.set_start_version(10000);
    meta.set_end_version(10005);
    meta.set_num_rows(100);
    meta.set_num_segments(1);
    doris::KeyBoundsPB* key_bounds = meta.mutable_segments_key_bounds()->Add();
    key_bounds->set_min_key("min_key");
    key_bounds->set_max_key("max_key");

    std::string rowset_meta_key_prefix = "rowset_meta_key_";
    for (int i = 0; i < 10; ++i) {
        // create a txn , and put rowset meta
        std::string rowset_meta_key = rowset_meta_key_prefix + std::to_string(i);
        doris::RowsetMetaCloudPB meta_copy(meta);
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        ASSERT_TRUE(document_put(txn.get(), rowset_meta_key, std::move(meta_copy)));
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    {
        // scan all rowset meta keys
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        FullRangeGetOptions opts;
        opts.txn = txn.get();
        opts.batch_limit = 2;
        auto iter = txn_kv->full_range_get(rowset_meta_key_prefix, rowset_meta_key_prefix + '\xFF',
                                           std::move(opts));
        int count = 0;
        while (true) {
            doris::RowsetMetaCloudPB saved_meta;
            TxnErrorCode err = document_get(iter.get(), &saved_meta);
            if (err == TxnErrorCode::TXN_KEY_NOT_FOUND) {
                break; // No more keys to read
            }
            ASSERT_EQ(err, TxnErrorCode::TXN_OK);
            ASSERT_EQ(saved_meta.rowset_id_v2(), meta.rowset_id_v2());
            ASSERT_EQ(saved_meta.end_version(), meta.end_version());
            ASSERT_EQ(saved_meta.start_version(), meta.start_version());
            ASSERT_EQ(saved_meta.num_rows(), meta.num_rows());
            ASSERT_EQ(saved_meta.num_segments(), meta.num_segments());
            ASSERT_EQ(saved_meta.segments_key_bounds_size(), 1);
            ASSERT_EQ(saved_meta.segments_key_bounds(0).min_key(), "min_key");
            ASSERT_EQ(saved_meta.segments_key_bounds(0).max_key(), "max_key");
            count += 1;
        }
        ASSERT_EQ(count, 10) << dump_range(txn_kv.get());
    }
}

TEST(DocumentMessageTest, DocumentGetAllTabletSchemaCloudPB) {
    std::unique_lock lock(config_mutex);
    config::enable_split_tablet_schema_pb = true;
    config::split_tablet_schema_pb_size = 0; // Always split the tablet schema pb.

    auto txn_kv = std::make_shared<MemTxnKv>();
    doris::TabletSchemaCloudPB schema;
    schema.set_keys_type(doris::DUP_KEYS);
    schema.set_num_short_key_columns(1);
    schema.set_num_rows_per_row_block(1024);
    schema.set_compress_kind(doris::COMPRESS_LZ4);
    schema.set_next_column_unique_id(5);
    schema.set_schema_version(1);

    doris::ColumnPB* column = schema.add_column();
    column->set_name("test_col");
    column->set_unique_id(1);
    column->set_type("VARCHAR");
    column->set_is_key(true);
    column->set_is_nullable(false);

    std::string schema_key_prefix = "tablet_schema_key_";
    for (int i = 0; i < 10; ++i) {
        // create a txn and put tablet schema
        doris::TabletSchemaCloudPB schema_copy(schema);
        schema_copy.set_schema_version(i + 1);
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        ASSERT_TRUE(document_put(txn.get(), schema_key_prefix + std::to_string(i),
                                 std::move(schema_copy)));
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    {
        // scan all tablet schema keys
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        FullRangeGetOptions opts;
        opts.txn = txn.get();
        opts.batch_limit = 2;
        auto iter = txn_kv->full_range_get(schema_key_prefix, schema_key_prefix + '\xFF',
                                           std::move(opts));
        int count = 0;
        while (true) {
            doris::TabletSchemaCloudPB saved_schema;
            TxnErrorCode code = document_get(iter.get(), &saved_schema);
            if (code == TxnErrorCode::TXN_KEY_NOT_FOUND) {
                break;
            }
            ASSERT_EQ(code, TxnErrorCode::TXN_OK);
            ASSERT_EQ(saved_schema.keys_type(), schema.keys_type());
            ASSERT_EQ(saved_schema.num_short_key_columns(), schema.num_short_key_columns());
            ASSERT_EQ(saved_schema.column_size(), 1);
            ASSERT_EQ(saved_schema.column(0).name(), "test_col");
            ASSERT_EQ(saved_schema.column(0).unique_id(), 1);
            ASSERT_EQ(saved_schema.column(0).type(), "VARCHAR");
            ASSERT_EQ(saved_schema.schema_version(), count + 1);
            count += 1;
        }
        ASSERT_EQ(count, 10) << dump_range(txn_kv.get());
    }
}

TEST(DocumentMessageTest, VersionedDocumentPut) {
    std::unique_lock lock(config_mutex);
    config::enable_split_rowset_meta_pb = true;
    config::split_rowset_meta_pb_size = 0; // Always split the rowset meta pb.

    auto txn_kv = std::make_shared<MemTxnKv>();
    doris::RowsetMetaCloudPB meta;
    meta.set_rowset_id(123);
    meta.set_rowset_id_v2("versioned_document_test");
    meta.set_start_version(10000);
    meta.set_end_version(10005);
    meta.set_num_rows(100);
    meta.set_num_segments(1);
    doris::KeyBoundsPB* key_bounds = meta.mutable_segments_key_bounds()->Add();
    key_bounds->set_min_key("min_key");
    key_bounds->set_max_key("max_key");

    std::string key_prefix = "versioned_rowset_meta_key_";
    {
        // Create a txn and put versioned rowset meta with initial version
        doris::RowsetMetaCloudPB meta_copy(meta);
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        ASSERT_TRUE(versioned::document_put(txn.get(), key_prefix, std::move(meta_copy)));
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    Versionstamp version;
    {
        // Get the rowset meta with version
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        doris::RowsetMetaCloudPB read_meta;
        ASSERT_EQ(versioned::document_get(txn.get(), key_prefix, &read_meta, &version),
                  TxnErrorCode::TXN_OK);
    }

    // Remove the range
    {
        // Create a txn and remove the versioned rowset meta
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        versioned::document_remove<doris::RowsetMetaCloudPB>(txn.get(), key_prefix, version);
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    ASSERT_TRUE(is_empty_range(txn_kv.get())) << dump_range(txn_kv.get());

    {
        // Create a txn and try to get the removed versioned rowset meta
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        doris::RowsetMetaCloudPB read_meta;
        ASSERT_EQ(versioned::document_get(txn.get(), key_prefix, &read_meta, &version),
                  TxnErrorCode::TXN_KEY_NOT_FOUND);
    }
}

TEST(DocumentMessageTest, VersionedDocumentPutAndGet) {
    std::unique_lock lock(config_mutex);
    config::enable_split_rowset_meta_pb = true;
    config::split_rowset_meta_pb_size = 0; // Always split the rowset meta pb.

    auto txn_kv = std::make_shared<MemTxnKv>();
    doris::RowsetMetaCloudPB meta;
    meta.set_rowset_id(123);
    meta.set_rowset_id_v2("versioned_document_test");
    meta.set_start_version(10000);
    meta.set_end_version(10005);
    meta.set_num_rows(100);
    meta.set_num_segments(1);
    doris::KeyBoundsPB* key_bounds = meta.mutable_segments_key_bounds()->Add();
    key_bounds->set_min_key("min_key");
    key_bounds->set_max_key("max_key");
    key_bounds = meta.mutable_segments_key_bounds()->Add();
    key_bounds->set_min_key("min_key2");
    key_bounds->set_max_key("max_key2");

    std::string key_prefix = "versioned_rowset_meta_key_";
    {
        // Create a txn and put versioned rowset meta with initial version
        doris::RowsetMetaCloudPB meta_copy(meta);
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        ASSERT_TRUE(versioned::document_put(txn.get(), key_prefix, std::move(meta_copy)));
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    {
        // Get the rowset meta with version
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        doris::RowsetMetaCloudPB read_meta;
        Versionstamp version;
        ASSERT_EQ(versioned::document_get(txn.get(), key_prefix, &read_meta, &version),
                  TxnErrorCode::TXN_OK);

        // Verify the metadata
        ASSERT_EQ(read_meta.rowset_id_v2(), meta.rowset_id_v2());
        ASSERT_EQ(read_meta.end_version(), meta.end_version());
        ASSERT_EQ(read_meta.start_version(), meta.start_version());
        ASSERT_EQ(read_meta.num_rows(), meta.num_rows());
        ASSERT_EQ(read_meta.num_segments(), meta.num_segments());
        ASSERT_EQ(read_meta.segments_key_bounds_size(), 2);
        ASSERT_EQ(read_meta.segments_key_bounds(0).min_key(), "min_key");
        ASSERT_EQ(read_meta.segments_key_bounds(0).max_key(), "max_key");
        ASSERT_EQ(read_meta.segments_key_bounds(1).min_key(), "min_key2");
        ASSERT_EQ(read_meta.segments_key_bounds(1).max_key(), "max_key2");
    }

    {
        // Update the rowset meta with a new version
        doris::RowsetMetaCloudPB updated_meta(meta);
        updated_meta.set_num_rows(200); // Change num_rows
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        ASSERT_TRUE(versioned::document_put(txn.get(), key_prefix, std::move(updated_meta)));
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    {
        // Get the latest version of rowset meta
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        doris::RowsetMetaCloudPB read_meta;
        Versionstamp version;
        ASSERT_EQ(versioned::document_get(txn.get(), key_prefix, &read_meta, &version),
                  TxnErrorCode::TXN_OK);

        // Verify the updated metadata
        ASSERT_EQ(read_meta.rowset_id_v2(), meta.rowset_id_v2());
        ASSERT_EQ(read_meta.end_version(), meta.end_version());
        ASSERT_EQ(read_meta.start_version(), meta.start_version());
        ASSERT_EQ(read_meta.num_rows(), 200); // This should now be 200
        ASSERT_EQ(read_meta.num_segments(), meta.num_segments());
        ASSERT_EQ(read_meta.segments_key_bounds_size(), 2);
        ASSERT_EQ(read_meta.segments_key_bounds(0).min_key(), "min_key");
        ASSERT_EQ(read_meta.segments_key_bounds(0).max_key(), "max_key");
        ASSERT_EQ(read_meta.segments_key_bounds(1).min_key(), "min_key2");
        ASSERT_EQ(read_meta.segments_key_bounds(1).max_key(), "max_key2");
    }

    // Testing with a non-splittable message
    {
        std::string simple_key_prefix = "versioned_version_pb_key_";
        VersionPB version_pb;
        version_pb.set_version(123);

        // Put the simple message
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        ASSERT_TRUE(versioned::document_put(txn.get(), simple_key_prefix, std::move(version_pb)));
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);

        // Get the simple message
        std::unique_ptr<Transaction> read_txn;
        ASSERT_EQ(txn_kv->create_txn(&read_txn), TxnErrorCode::TXN_OK);
        VersionPB read_version_pb;
        Versionstamp version;
        ASSERT_EQ(versioned::document_get(read_txn.get(), simple_key_prefix, &read_version_pb,
                                          &version),
                  TxnErrorCode::TXN_OK);

        // Verify the simple message
        ASSERT_EQ(read_version_pb.version(), 123);
    }
}

TEST(DocumentMessageTest, VersionedDocumentPutAndGetWithVersionstamp) {
    std::unique_lock lock(config_mutex);
    config::enable_split_rowset_meta_pb = true;
    config::split_rowset_meta_pb_size = 0; // Always split the rowset meta pb.

    auto txn_kv = std::make_shared<MemTxnKv>();
    doris::RowsetMetaCloudPB meta;
    meta.set_rowset_id(123);
    meta.set_rowset_id_v2("versioned_document_test");
    meta.set_start_version(10000);
    meta.set_end_version(10005);
    meta.set_num_rows(100);
    meta.set_num_segments(1);
    doris::KeyBoundsPB* key_bounds = meta.mutable_segments_key_bounds()->Add();
    key_bounds->set_min_key("min_key");
    key_bounds->set_max_key("max_key");
    key_bounds = meta.mutable_segments_key_bounds()->Add();
    key_bounds->set_min_key("min_key2");
    key_bounds->set_max_key("max_key2");

    std::string key_prefix = "versioned_rowset_meta_key_";
    {
        // Create a txn and put versioned rowset meta with initial version
        doris::RowsetMetaCloudPB meta_copy(meta);
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        ASSERT_TRUE(versioned::document_put(txn.get(), key_prefix, std::move(meta_copy)));
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    Versionstamp first_versionstamp;
    {
        // Get the rowset meta with version
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        doris::RowsetMetaCloudPB read_meta;
        ASSERT_EQ(versioned::document_get(txn.get(), key_prefix, &read_meta, &first_versionstamp),
                  TxnErrorCode::TXN_OK);

        // Verify the metadata
        ASSERT_EQ(read_meta.rowset_id_v2(), meta.rowset_id_v2());
        ASSERT_EQ(read_meta.end_version(), meta.end_version());
        ASSERT_EQ(read_meta.start_version(), meta.start_version());
        ASSERT_EQ(read_meta.num_rows(), meta.num_rows());
        ASSERT_EQ(read_meta.num_segments(), meta.num_segments());
        ASSERT_EQ(read_meta.segments_key_bounds_size(), 2);
        ASSERT_EQ(read_meta.segments_key_bounds(0).min_key(), "min_key");
        ASSERT_EQ(read_meta.segments_key_bounds(0).max_key(), "max_key");
        ASSERT_EQ(read_meta.segments_key_bounds(1).min_key(), "min_key2");
        ASSERT_EQ(read_meta.segments_key_bounds(1).max_key(), "max_key2");
    }

    {
        // Update the rowset meta with a new version
        doris::RowsetMetaCloudPB updated_meta(meta);
        updated_meta.set_num_rows(200); // Change num_rows
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        ASSERT_TRUE(versioned::document_put(txn.get(), key_prefix, std::move(updated_meta)));
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    {
        // Get the latest version of rowset meta
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        doris::RowsetMetaCloudPB read_meta;
        Versionstamp version;
        ASSERT_EQ(versioned::document_get(txn.get(), key_prefix, &read_meta, &version),
                  TxnErrorCode::TXN_OK);

        // Verify the updated metadata
        ASSERT_EQ(read_meta.rowset_id_v2(), meta.rowset_id_v2());
        ASSERT_EQ(read_meta.end_version(), meta.end_version());
        ASSERT_EQ(read_meta.start_version(), meta.start_version());
        ASSERT_EQ(read_meta.num_rows(), 200); // This should now be 200
        ASSERT_EQ(read_meta.num_segments(), meta.num_segments());
        ASSERT_EQ(read_meta.segments_key_bounds_size(), 2);
        ASSERT_EQ(read_meta.segments_key_bounds(0).min_key(), "min_key");
        ASSERT_EQ(read_meta.segments_key_bounds(0).max_key(), "max_key");
        ASSERT_EQ(read_meta.segments_key_bounds(1).min_key(), "min_key2");
        ASSERT_EQ(read_meta.segments_key_bounds(1).max_key(), "max_key2");
    }

    {
        // Get the previous version of rowset meta
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        doris::RowsetMetaCloudPB read_meta;
        Versionstamp snapshot_version(first_versionstamp.version() + 1, 0);
        Versionstamp version;
        ASSERT_EQ(versioned::document_get(txn.get(), key_prefix, snapshot_version, &read_meta,
                                          &version),
                  TxnErrorCode::TXN_OK);

        // Verify the updated metadata
        ASSERT_EQ(read_meta.rowset_id_v2(), meta.rowset_id_v2());
        ASSERT_EQ(read_meta.end_version(), meta.end_version());
        ASSERT_EQ(read_meta.start_version(), meta.start_version());
        ASSERT_EQ(read_meta.num_rows(), meta.num_rows());
        ASSERT_EQ(read_meta.num_segments(), meta.num_segments());
        ASSERT_EQ(read_meta.segments_key_bounds_size(), 2);
        ASSERT_EQ(read_meta.segments_key_bounds(0).min_key(), "min_key");
        ASSERT_EQ(read_meta.segments_key_bounds(0).max_key(), "max_key");
        ASSERT_EQ(read_meta.segments_key_bounds(1).min_key(), "min_key2");
        ASSERT_EQ(read_meta.segments_key_bounds(1).max_key(), "max_key2");
    }

    {
        // Not found
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        doris::RowsetMetaCloudPB read_meta;
        Versionstamp snapshot_version(Versionstamp::min());
        Versionstamp version;
        ASSERT_EQ(versioned::document_get(txn.get(), key_prefix, snapshot_version, &read_meta,
                                          &version),
                  TxnErrorCode::TXN_KEY_NOT_FOUND)
                << dump_range(txn_kv.get());
    }
}

TEST(DocumentMessageTest, VersionedDocumentPutTabletSchemaCloudPB) {
    std::unique_lock lock(config_mutex);
    config::enable_split_tablet_schema_pb = true;
    config::split_tablet_schema_pb_size = 0; // Always split the tablet schema pb.

    auto txn_kv = std::make_shared<MemTxnKv>();
    doris::TabletSchemaCloudPB schema;
    schema.set_keys_type(doris::DUP_KEYS);
    schema.set_num_short_key_columns(2);
    schema.set_num_rows_per_row_block(1024);
    schema.set_compress_kind(doris::COMPRESS_LZ4);
    schema.set_next_column_unique_id(10);
    schema.set_schema_version(1);

    // Add multiple columns to test splitting
    for (int i = 0; i < 3; ++i) {
        doris::ColumnPB* column = schema.add_column();
        column->set_name(fmt::format("col_{}", i));
        column->set_unique_id(i + 1);
        column->set_type("INT");
        column->set_is_key(i < 2); // First 2 columns are key columns
        column->set_is_nullable(false);
    }

    std::string key_prefix = "versioned_tablet_schema_key_";
    {
        // Create a txn and put versioned tablet schema with initial version
        doris::TabletSchemaCloudPB schema_copy(schema);
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        ASSERT_TRUE(versioned::document_put(txn.get(), key_prefix, std::move(schema_copy)));
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    Versionstamp version;
    {
        // Get the tablet schema with version
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        doris::TabletSchemaCloudPB read_schema;
        ASSERT_EQ(versioned::document_get(txn.get(), key_prefix, &read_schema, &version),
                  TxnErrorCode::TXN_OK);
        ASSERT_EQ(read_schema.keys_type(), schema.keys_type());
        ASSERT_EQ(read_schema.num_short_key_columns(), schema.num_short_key_columns());
        ASSERT_EQ(read_schema.column_size(), 3);
        for (int i = 0; i < 3; ++i) {
            ASSERT_EQ(read_schema.column(i).name(), fmt::format("col_{}", i));
            ASSERT_EQ(read_schema.column(i).unique_id(), i + 1);
            ASSERT_EQ(read_schema.column(i).type(), "INT");
        }
    }

    // Remove the range
    {
        // Create a txn and remove the versioned tablet schema
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        versioned::document_remove<doris::TabletSchemaCloudPB>(txn.get(), key_prefix, version);
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    ASSERT_TRUE(is_empty_range(txn_kv.get())) << dump_range(txn_kv.get());
}

TEST(DocumentMessageTest, VersionedDocumentPutVersionPB) {
    auto txn_kv = std::make_shared<MemTxnKv>();
    VersionPB version_pb;
    version_pb.set_version(123);

    {
        // create a txn , and put version pb
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        ASSERT_TRUE(versioned::document_put(txn.get(), "version_key", std::move(version_pb)));
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    Versionstamp versionstamp;
    {
        // create a txn , and get version pb
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        VersionPB saved_version_pb;
        ASSERT_EQ(
                versioned::document_get(txn.get(), "version_key", &saved_version_pb, &versionstamp),
                TxnErrorCode::TXN_OK);
        ASSERT_EQ(saved_version_pb.version(), 123);
    }

    ASSERT_EQ(txn_kv->total_kvs(), 1) << dump_range(txn_kv.get());

    {
        // create a txn, and remove version pb
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        versioned::document_remove<VersionPB>(txn.get(), "version_key", versionstamp);
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    ASSERT_TRUE(is_empty_range(txn_kv.get())) << dump_range(txn_kv.get());
}

TEST(DocumentMessageTest, VersionedSplitSingleMessage) {
    auto txn_kv = std::make_shared<MemTxnKv>();
    {
        // Write a message that does not need to be split.
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        SplitSingleMessagePB msg;
        msg.set_other_fields(1);
        ASSERT_TRUE(versioned::document_put(txn.get(), "split_single_message_key", std::move(msg)));
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);

        // Read the message back.
        std::unique_ptr<Transaction> read_txn;
        ASSERT_EQ(txn_kv->create_txn(&read_txn), TxnErrorCode::TXN_OK);
        SplitSingleMessagePB read_msg;
        Versionstamp version;
        ASSERT_EQ(versioned::document_get(read_txn.get(), "split_single_message_key", &read_msg,
                                          &version),
                  TxnErrorCode::TXN_OK);
        ASSERT_EQ(read_msg.other_fields(), 1);

        ASSERT_EQ(count_range(txn_kv.get()), 1) << dump_range(txn_kv.get());

        // Remove the message.
        versioned::document_remove<SplitSingleMessagePB>(read_txn.get(), "split_single_message_key",
                                                         version);
        ASSERT_EQ(read_txn->commit(), TxnErrorCode::TXN_OK);
    }

    ASSERT_TRUE(is_empty_range(txn_kv.get())) << dump_range(txn_kv.get());

    {
        // Write a message that needs to be split.
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        SplitSingleMessagePB msg;
        msg.set_other_fields(2);
        auto* key_bounds = msg.mutable_segment_key_bounds();
        key_bounds->set_min_key("min_key");
        key_bounds->set_max_key("max_key");

        ASSERT_TRUE(versioned::document_put(txn.get(), "split_single_message_key_split",
                                            std::move(msg)));
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);

        // Read the message back.
        std::unique_ptr<Transaction> read_txn;
        ASSERT_EQ(txn_kv->create_txn(&read_txn), TxnErrorCode::TXN_OK);
        SplitSingleMessagePB read_msg;
        Versionstamp version;
        ASSERT_EQ(versioned::document_get(read_txn.get(), "split_single_message_key_split",
                                          &read_msg, &version),
                  TxnErrorCode::TXN_OK);
        ASSERT_EQ(read_msg.other_fields(), 2);
        ASSERT_EQ(read_msg.segment_key_bounds().min_key(), "min_key");
        ASSERT_EQ(read_msg.segment_key_bounds().max_key(), "max_key");
        ASSERT_EQ(count_range(txn_kv.get()), 2) << dump_range(txn_kv.get());

        // Remove the message.
        versioned::document_remove<SplitSingleMessagePB>(read_txn.get(),
                                                         "split_single_message_key_split", version);
        ASSERT_EQ(read_txn->commit(), TxnErrorCode::TXN_OK);
    }

    ASSERT_TRUE(is_empty_range(txn_kv.get())) << dump_range(txn_kv.get());
}

TEST(DocumentMessageTest, VersionedDocumentGetAllRowsetMeta) {
    std::unique_lock lock(config_mutex);
    config::enable_split_rowset_meta_pb = true;
    config::split_rowset_meta_pb_size = 0; // Always split the rowset meta pb.

    auto txn_kv = std::make_shared<MemTxnKv>();
    doris::RowsetMetaCloudPB meta;
    meta.set_rowset_id(123);
    meta.set_rowset_id_v2("document_put_rowset_meta");
    meta.set_start_version(10000);
    meta.set_end_version(10005);
    meta.set_num_rows(100);
    meta.set_num_segments(1);
    doris::KeyBoundsPB* key_bounds = meta.mutable_segments_key_bounds()->Add();
    key_bounds->set_min_key("min_key");
    key_bounds->set_max_key("max_key");
    key_bounds = meta.mutable_segments_key_bounds()->Add();
    key_bounds->set_min_key("min_key");
    key_bounds->set_max_key("max_key");

    std::string rowset_meta_key_prefix = "rowset_meta_key_";
    for (int i = 0; i < 10; ++i) {
        // create a txn , and put rowset meta
        std::string rowset_meta_key = rowset_meta_key_prefix + std::to_string(i);
        doris::RowsetMetaCloudPB meta_copy(meta);
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        ASSERT_TRUE(versioned::document_put(txn.get(), rowset_meta_key, std::move(meta_copy)));
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    {
        // scan all rowset meta keys
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);

        // [begin_key, end_key]
        std::string begin_key = rowset_meta_key_prefix + std::to_string(0);
        std::string end_key = rowset_meta_key_prefix + std::to_string(9);
        versioned::ReadDocumentMessagesOptions read_opts;
        read_opts.batch_limit = 2;
        read_opts.exclude_begin_key = false;
        read_opts.exclude_end_key = false;
        auto iter = versioned::document_get_range<doris::RowsetMetaCloudPB>(txn.get(), begin_key,
                                                                            end_key, read_opts);
        int count = 0;
        while (true) {
            auto&& kvp = iter->next();
            if (!kvp.has_value()) {
                break; // No more keys to read
            }
            auto [key, version, saved_meta] = kvp.value();
            ASSERT_EQ(saved_meta.rowset_id_v2(), meta.rowset_id_v2());
            ASSERT_EQ(saved_meta.end_version(), meta.end_version());
            ASSERT_EQ(saved_meta.start_version(), meta.start_version());
            ASSERT_EQ(saved_meta.num_rows(), meta.num_rows());
            ASSERT_EQ(saved_meta.num_segments(), meta.num_segments());
            ASSERT_EQ(saved_meta.segments_key_bounds_size(), 2);
            ASSERT_EQ(saved_meta.segments_key_bounds(0).min_key(), "min_key");
            ASSERT_EQ(saved_meta.segments_key_bounds(0).max_key(), "max_key");
            ASSERT_EQ(saved_meta.segments_key_bounds(1).min_key(), "min_key");
            ASSERT_EQ(saved_meta.segments_key_bounds(1).max_key(), "max_key");
            count += 1;
        }
        ASSERT_TRUE(iter->is_valid()); // The iterator should still be valid after the next call.
        ASSERT_EQ(count, 10) << dump_range(txn_kv.get());
    }
}

TEST(DocumentMessageTest, VersionedGetRangeWithVersionstamp) {
    std::unique_lock lock(config_mutex);
    config::enable_split_rowset_meta_pb = true;
    config::split_rowset_meta_pb_size = 0; // Always split the rowset meta pb.

    auto txn_kv = std::make_shared<MemTxnKv>();
    std::string key_prefix = "get_range_key_";

    doris::RowsetMetaCloudPB meta;
    meta.set_rowset_id(123);
    meta.set_rowset_id_v2("document_put_rowset_meta");
    meta.set_start_version(10000);
    meta.set_end_version(10005);
    meta.set_num_rows(100);
    meta.set_num_segments(1);
    doris::KeyBoundsPB* key_bounds = meta.mutable_segments_key_bounds()->Add();
    key_bounds->set_min_key("min_key");
    key_bounds->set_max_key("max_key");
    key_bounds = meta.mutable_segments_key_bounds()->Add();
    key_bounds->set_min_key("min_key");
    key_bounds->set_max_key("max_key");
    {
        // Put a series of versioned documents
        std::vector<std::pair<int, Versionstamp>> versions = {
                {10, Versionstamp(10, 0)}, {20, Versionstamp(20, 0)}, {30, Versionstamp(30, 0)},
                {40, Versionstamp(40, 0)}, {10, Versionstamp(40, 0)}, {50, Versionstamp(50, 0)},
                {30, Versionstamp(60, 0)}, {20, Versionstamp(70, 0)}, {10, Versionstamp(80, 0)},
                {60, Versionstamp(90, 0)}, {70, Versionstamp(90, 0)},
        };
        for (const auto& [suffix, versionstamp] : versions) {
            std::unique_ptr<Transaction> txn;
            ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
            std::string key = fmt::format("{}{:02}", key_prefix, suffix);

            doris::RowsetMetaCloudPB meta_copy(meta);
            ASSERT_TRUE(
                    versioned::document_put(txn.get(), key, versionstamp, std::move(meta_copy)));
            ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
        }
    }

    struct TestCase {
        Versionstamp snapshot_version;
        int begin, end;
        std::vector<std::pair<int, Versionstamp>> expected_results;
    };

    std::vector<TestCase> test_cases = {
            // Test case 1: Get all versions with max snapshot version
            // Results should be in reverse order by key (70, 60, 50, 40, 30, 20, 10)
            {
                    Versionstamp::max(),
                    0,
                    99,
                    {{70, Versionstamp(90, 0)},
                     {60, Versionstamp(90, 0)},
                     {50, Versionstamp(50, 0)},
                     {40, Versionstamp(40, 0)},
                     {30, Versionstamp(60, 0)},
                     {20, Versionstamp(70, 0)},
                     {10, Versionstamp(80, 0)}},
            },

            // Test case 2: Get versions with a specific snapshot version (50, 0)
            // Only keys with version < (50, 0) should be returned: 10->40, 20->20, 30->30, 40->40
            // Results should be in reverse order by key (40, 30, 20, 10)
            {
                    Versionstamp(50, 0),
                    10,
                    70,
                    {{40, Versionstamp(40, 0)},
                     {30, Versionstamp(30, 0)},
                     {20, Versionstamp(20, 0)},
                     {10, Versionstamp(40, 0)}},
            },

            // Test case 3: Get versions with a non-existing snapshot version
            {Versionstamp(5, 0), 10, 70, {}},

            // Test case 4: Get versions with a specific range [20, 60)
            // Results should be in reverse order by key
            {
                    Versionstamp::max(),
                    20,
                    60,
                    {{50, Versionstamp(50, 0)},
                     {40, Versionstamp(40, 0)},
                     {30, Versionstamp(60, 0)},
                     {20, Versionstamp(70, 0)}},
            },

            // Test case 5: Empty range - begin_key >= end_key
            {
                    Versionstamp::max(),
                    50,
                    30,
                    {},
            },

            // Test case 6: Single key range [30, 31)
            {
                    Versionstamp::max(),
                    30,
                    31,
                    {{30, Versionstamp(60, 0)}},
            },

            // Test case 7: Range with no matching keys [25, 30)
            {
                    Versionstamp::max(),
                    25,
                    30,
                    {},
            },

            // Test case 8: Exact boundary - key 20 included, key 60 excluded
            {
                    Versionstamp::max(),
                    20,
                    60,
                    {{50, Versionstamp(50, 0)},
                     {40, Versionstamp(40, 0)},
                     {30, Versionstamp(60, 0)},
                     {20, Versionstamp(70, 0)}},
            },

            // Test case 9: Version boundary test - snapshot at (45, 0)
            // Should include versions < 45: 10->40, 20->20, 30->30, 40->40
            {
                    Versionstamp(45, 0),
                    0,
                    99,
                    {{40, Versionstamp(40, 0)},
                     {30, Versionstamp(30, 0)},
                     {20, Versionstamp(20, 0)},
                     {10, Versionstamp(40, 0)}},
            },

            // Test case 10: Test with exact version boundary (40, 0)
            // Should include versions < 40: 10->10, 20->20, 30->30
            {
                    Versionstamp(40, 0),
                    0,
                    99,
                    {{30, Versionstamp(30, 0)},
                     {20, Versionstamp(20, 0)},
                     {10, Versionstamp(10, 0)}},
            },
    };

    size_t case_index = 0;
    for (auto&& tc : test_cases) {
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);

        // Get range with range [begin, end)
        versioned::ReadDocumentMessagesOptions opts;
        opts.snapshot_version = tc.snapshot_version;
        opts.exclude_begin_key = false;
        opts.exclude_end_key = true;
        std::string begin_key = fmt::format("{}{:02}", key_prefix, tc.begin);
        std::string end_key = fmt::format("{}{:02}", key_prefix, tc.end);
        auto iter = versioned::document_get_range<doris::RowsetMetaCloudPB>(txn.get(), begin_key,
                                                                            end_key, opts);
        size_t count = 0;
        for (auto&& kvp = iter->next(); kvp.has_value(); kvp = iter->next()) {
            auto [key, version, _value] = kvp.value();
            key.remove_prefix(key_prefix.size());
            int suffix = std::stoi(std::string(key));
            ASSERT_EQ(suffix, tc.expected_results[count].first) << " count=" << count;
            ASSERT_EQ(version, tc.expected_results[count].second)
                    << " count=" << count << ", key=" << escape_hex(key)
                    << ", version=" << version.version()
                    << ", expected=" << tc.expected_results[count].second.version();
            count += 1;
        }
        ASSERT_TRUE(iter->is_valid()); // The iterator should still be valid after the next call.
        ASSERT_EQ(count, tc.expected_results.size());
        case_index += 1;
        std::cout << "Test case " << case_index << " passed." << std::endl;
    }

    // Iterate cases via peek method
    case_index = 0;
    for (auto&& tc : test_cases) {
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);

        // Get range with range [begin, end)
        versioned::ReadDocumentMessagesOptions opts;
        opts.snapshot_version = tc.snapshot_version;
        opts.exclude_begin_key = false;
        opts.exclude_end_key = true;
        std::string begin_key = fmt::format("{}{:02}", key_prefix, tc.begin);
        std::string end_key = fmt::format("{}{:02}", key_prefix, tc.end);
        auto iter = versioned::document_get_range<doris::RowsetMetaCloudPB>(txn.get(), begin_key,
                                                                            end_key, opts);
        size_t count = 0;
        for (auto&& kvp = iter->peek(); kvp.has_value(); iter->next(), kvp = iter->peek()) {
            auto [key, version, _value] = kvp.value();
            key.remove_prefix(key_prefix.size());
            int suffix = std::stoi(std::string(key));
            ASSERT_EQ(suffix, tc.expected_results[count].first) << " count=" << count;
            ASSERT_EQ(version, tc.expected_results[count].second)
                    << " count=" << count << ", key=" << escape_hex(key)
                    << ", version=" << version.version()
                    << ", expected=" << tc.expected_results[count].second.version();
            count += 1;
        }
        ASSERT_TRUE(iter->is_valid()); // The iterator should still be valid after the next call.
        ASSERT_EQ(count, tc.expected_results.size());
        case_index += 1;
        std::cout << "Peek test case " << case_index << " passed." << std::endl;
    }
}

TEST(DocumentMessageTest, VersionedGetRangeWithVersionstamp2) {
    std::unique_lock lock(config_mutex);
    config::enable_split_rowset_meta_pb = true;
    config::split_rowset_meta_pb_size = 0; // Always split the rowset meta pb.

    auto txn_kv = std::make_shared<MemTxnKv>();
    std::string_view key_prefix = "get_range2_key_";

    doris::RowsetMetaCloudPB meta;
    meta.set_rowset_id(123);
    meta.set_rowset_id_v2("document_put_rowset_meta");
    meta.set_start_version(10000);
    meta.set_end_version(10005);
    meta.set_num_rows(100);
    meta.set_num_segments(1);
    doris::KeyBoundsPB* key_bounds = meta.mutable_segments_key_bounds()->Add();
    key_bounds->set_min_key("min_key");
    key_bounds->set_max_key("max_key");
    key_bounds = meta.mutable_segments_key_bounds()->Add();
    key_bounds->set_min_key("min_key");
    key_bounds->set_max_key("max_key");

    {
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        // Insert 1000 versioned documents with version 100
        for (int i = 0; i < 1000; i++) {
            std::string key = fmt::format("{}{:03}", key_prefix, i);
            Versionstamp version(100, 0);
            doris::RowsetMetaCloudPB meta_copy(meta);
            ASSERT_TRUE(versioned::document_put(txn.get(), key, version, std::move(meta_copy)));
            ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
        }
        // Insert some versioned documents, with version 200
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        for (int i = 0; i < 1000; i++) {
            std::string key = fmt::format("{}{:03}", key_prefix, i);
            Versionstamp version(200, 0);
            doris::RowsetMetaCloudPB meta_copy(meta);
            ASSERT_TRUE(versioned::document_put(txn.get(), key, version, std::move(meta_copy)));
            ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
        }
    }

    // Iterate [0, 999] with version 200
    {
        std::string begin_key = fmt::format("{}{:03}", key_prefix, 0);
        std::string end_key = fmt::format("{}{:03}", key_prefix, 999);
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);

        versioned::ReadDocumentMessagesOptions opts;
        opts.snapshot_version = Versionstamp::max();
        opts.exclude_begin_key = false;
        opts.exclude_end_key = false;
        opts.batch_limit = 11;
        auto iter = versioned::document_get_range<doris::RowsetMetaCloudPB>(txn.get(), begin_key,
                                                                            end_key, opts);
        size_t count = 0;
        for (auto&& kvp = iter->next(); kvp.has_value(); kvp = iter->next()) {
            auto [key, version, _value] = kvp.value();
            key.remove_prefix(key_prefix.size());
            int suffix = std::stoi(std::string(key));
            ASSERT_EQ(suffix, 999 - count) << " count=" << count << ", key=" << key;
            ASSERT_EQ(version.version(), 200)
                    << " count=" << count << ", key=" << key << ", version=" << version.version();
            count += 1;
        }
        ASSERT_TRUE(iter->is_valid()); // The iterator should still be valid after the next call.
        ASSERT_EQ(count, 1000) << dump_range(txn_kv.get());
    }

    // Iterate [0, 999] with 100
    {
        std::string begin_key = fmt::format("{}{:03}", key_prefix, 0);
        std::string end_key = fmt::format("{}{:03}", key_prefix, 999);
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        versioned::ReadDocumentMessagesOptions opts;
        opts.snapshot_version = Versionstamp(150, 0);
        opts.exclude_begin_key = false;
        opts.exclude_end_key = false;
        opts.batch_limit = 11; // Limit to 100 results per batch
        auto iter = versioned::document_get_range<doris::RowsetMetaCloudPB>(txn.get(), begin_key,
                                                                            end_key, opts);
        size_t count = 0;
        for (auto&& kvp = iter->next(); kvp.has_value(); kvp = iter->next()) {
            auto [key, version, _value] = kvp.value();
            key.remove_prefix(key_prefix.size());
            int suffix = std::stoi(std::string(key));
            ASSERT_EQ(suffix, 999 - count) << " count=" << count << ", key=" << key;
            ASSERT_EQ(version.version(), 100)
                    << " count=" << count << ", key=" << key << ", version=" << version.version();
            count += 1;
        }
        ASSERT_TRUE(iter->is_valid()); // The iterator should still be valid after the next call.
        ASSERT_EQ(count, 1000) << dump_range(txn_kv.get());
    }
}

TEST(DocumentMessageTest, VersionedGetRangeWithRangeKeySelector) {
    std::unique_lock lock(config_mutex);
    config::enable_split_rowset_meta_pb = true;
    config::split_rowset_meta_pb_size = 0; // Always split the rowset meta pb.

    auto txn_kv = std::make_shared<MemTxnKv>();
    std::string_view key_prefix = "get_range_key_selector_";

    doris::RowsetMetaCloudPB meta;
    meta.set_rowset_id(123);
    meta.set_rowset_id_v2("document_put_rowset_meta");
    meta.set_start_version(10000);
    meta.set_end_version(10005);
    meta.set_num_rows(100);
    meta.set_num_segments(1);
    doris::KeyBoundsPB* key_bounds = meta.mutable_segments_key_bounds()->Add();
    key_bounds->set_min_key("min_key");
    key_bounds->set_max_key("max_key");
    key_bounds = meta.mutable_segments_key_bounds()->Add();
    key_bounds->set_min_key("min_key");
    key_bounds->set_max_key("max_key");

    // Insert 9 versioned documents with version 100
    for (int i = 0; i < 10; i++) {
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        std::string key = fmt::format("{}{:03}", key_prefix, i);
        Versionstamp version(100, 0);
        doris::RowsetMetaCloudPB meta_copy(meta);
        ASSERT_TRUE(versioned::document_put(txn.get(), key, version, std::move(meta_copy)));
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    struct TestCase {
        std::string begin_key, end_key;
        bool exclude_begin_key, exclude_end_key;
        size_t expected_count;
    };

    std::vector<TestCase> test_cases = {
            // Test case 1: Range [0, 9]
            {fmt::format("{}{:03}", key_prefix, 0), fmt::format("{}{:03}", key_prefix, 9), false,
             false, 10},

            // Test case 2: Range [0, 9)
            {fmt::format("{}{:03}", key_prefix, 0), fmt::format("{}{:03}", key_prefix, 9), false,
             true, 9},

            // Test case 3: Range (0, 9]
            {fmt::format("{}{:03}", key_prefix, 0), fmt::format("{}{:03}", key_prefix, 9), true,
             false, 9},

            // Test case 4: Range (0, 9)
            {fmt::format("{}{:03}", key_prefix, 0), fmt::format("{}{:03}", key_prefix, 9), true,
             true, 8},
    };

    size_t case_index = 0;
    for (const auto& tc : test_cases) {
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        versioned::ReadDocumentMessagesOptions opts;
        opts.snapshot_version = Versionstamp::max();
        opts.exclude_begin_key = tc.exclude_begin_key;
        opts.exclude_end_key = tc.exclude_end_key;
        opts.batch_limit = 11; // Limit to 100 results per batch
        auto iter = versioned::document_get_range<doris::RowsetMetaCloudPB>(txn.get(), tc.begin_key,
                                                                            tc.end_key, opts);
        size_t count = 0;
        std::string keys;
        for (auto&& kvp = iter->next(); kvp.has_value(); kvp = iter->next()) {
            auto [key, version, _value] = kvp.value();
            keys += fmt::format("{} -> {}\n", key, version.version());
            count += 1;
        }
        // The iterator should still be valid after the next call.
        ASSERT_TRUE(iter->is_valid())
                << "Iterator should be valid after next call"
                << ", count=" << count << ", begin_key=" << escape_hex(tc.begin_key)
                << ", end_key=" << escape_hex(tc.end_key) << ", case_index=" << case_index
                << ", exclude_begin_key=" << tc.exclude_begin_key
                << ", exclude_end_key=" << tc.exclude_end_key
                << ", error_code=" << iter->error_code();
        ASSERT_EQ(count, tc.expected_count) << keys << ", case_index=" << case_index
                                            << ", exclude_begin_key=" << tc.exclude_begin_key
                                            << ", exclude_end_key=" << tc.exclude_end_key
                                            << ", begin_key=" << escape_hex(tc.begin_key)
                                            << ", end_key=" << escape_hex(tc.end_key);
        case_index += 1;
    }
}
