// 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/meta_reader.h"

#include <gen_cpp/cloud.pb.h>
#include <gen_cpp/olap_file.pb.h>
#include <gtest/gtest-death-test.h>
#include <gtest/gtest.h>

#include <memory>
#include <tuple>

#include "common/config.h"
#include "common/logging.h"
#include "common/util.h"
#include "meta-store/document_message.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/versioned_value.h"

using namespace doris::cloud;

int main(int argc, char** argv) {
    config::log_dir = "./log/";
    if (!doris::cloud::init_glog("meta_reader_test")) {
        std::cerr << "failed to init glog" << std::endl;
        return -1;
    }
    ::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 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(MetaReaderTest, GetTableVersion) {
    auto txn_kv = std::make_shared<MemTxnKv>();
    ASSERT_EQ(txn_kv->init(), 0);

    std::string instance_id = "test_instance";
    int64_t table_id = 1001;
    {
        // NOT FOUND
        MetaReader meta_reader(instance_id, txn_kv.get());
        Versionstamp table_version;
        TxnErrorCode err = meta_reader.get_table_version(table_id, &table_version);
        ASSERT_EQ(err, TxnErrorCode::TXN_KEY_NOT_FOUND);
    }

    {
        // Put a table version
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        std::string table_version_key = versioned::table_version_key({instance_id, table_id});
        versioned_put(txn.get(), table_version_key, "");
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    Versionstamp version1;
    {
        MetaReader meta_reader(instance_id, txn_kv.get());
        TxnErrorCode err = meta_reader.get_table_version(table_id, &version1);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_EQ(meta_reader.min_read_versionstamp(), version1);
    }

    {
        // Put a table version
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        std::string table_version_key = versioned::table_version_key({instance_id, table_id});
        versioned_put(txn.get(), table_version_key, "");
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    Versionstamp version2;
    {
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        MetaReader meta_reader(instance_id, txn_kv.get());
        TxnErrorCode err = meta_reader.get_table_version(txn.get(), table_id, &version2);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_EQ(meta_reader.min_read_versionstamp(), version2);
    }

    ASSERT_LT(version1, version2);

    {
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        std::string begin_key = versioned::table_version_key({instance_id, table_id});
        std::string end_key = versioned::table_version_key({instance_id, table_id + 1});
        FullRangeGetOptions options;
        std::unique_ptr<FullRangeGetIterator> iter =
                txn->full_range_get(begin_key, end_key, std::move(options));
        int num = 1;
        for (auto kvp = iter->next(); kvp.has_value(); kvp = iter->next()) {
            auto&& [key, _] = *kvp;
            int64_t decoded_id;
            Versionstamp decoded_version;
            std::string_view key_view(key);
            ASSERT_TRUE(
                    versioned::decode_table_version_key(&key_view, &decoded_id, &decoded_version));
            ASSERT_EQ(decoded_id, table_id);
            ASSERT_EQ(decoded_version, num == 1 ? version1 : version2);
            num++;
        }
    }
}

TEST(MetaReaderTest, GetTableStreamOffset) {
    auto txn_kv = std::make_shared<MemTxnKv>();
    ASSERT_EQ(txn_kv->init(), 0);

    std::string instance_id = "table_stream_instance";
    TableStreamIdentityPB identity;
    identity.set_base_db_id(1001);
    identity.set_base_table_id(1002);
    identity.set_stream_db_id(1003);
    identity.set_stream_id(1004);
    int64_t partition_id = 1005;
    std::string key = versioned::table_stream_offset_key(
            {instance_id, identity.base_db_id(), identity.base_table_id(), identity.stream_db_id(),
             identity.stream_id(), partition_id});

    TableStreamOffsetPB offset;
    Versionstamp versionstamp;
    MetaReader latest_reader(instance_id, txn_kv.get());
    std::unique_ptr<Transaction> missing_read_txn;
    ASSERT_EQ(txn_kv->create_txn(&missing_read_txn), TxnErrorCode::TXN_OK);
    ASSERT_EQ(latest_reader.get_table_stream_offset(missing_read_txn.get(), identity, partition_id,
                                                    &offset, &versionstamp),
              TxnErrorCode::TXN_KEY_NOT_FOUND);

    {
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        TableStreamOffsetPB first;
        first.set_partition_id(partition_id);
        first.set_state(TABLE_STREAM_OFFSET_CONSUMED);
        first.set_offset_tso(101);
        versioned_put(txn.get(), key, Versionstamp(100, 1), first.SerializeAsString());

        TableStreamOffsetPB second = first;
        second.set_offset_tso(202);
        versioned_put(txn.get(), key, Versionstamp(200, 1), second.SerializeAsString());
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    std::unique_ptr<Transaction> latest_read_txn;
    ASSERT_EQ(txn_kv->create_txn(&latest_read_txn), TxnErrorCode::TXN_OK);
    ASSERT_EQ(latest_reader.get_table_stream_offset(latest_read_txn.get(), identity, partition_id,
                                                    &offset, &versionstamp),
              TxnErrorCode::TXN_OK);
    EXPECT_EQ(offset.offset_tso(), 202);
    EXPECT_EQ(versionstamp, Versionstamp(200, 1));

    MetaReader snapshot_reader(instance_id, txn_kv.get(), Versionstamp(150, 0));
    std::unique_ptr<Transaction> snapshot_read_txn;
    ASSERT_EQ(txn_kv->create_txn(&snapshot_read_txn), TxnErrorCode::TXN_OK);
    ASSERT_EQ(snapshot_reader.get_table_stream_offset(snapshot_read_txn.get(), identity,
                                                      partition_id, &offset, &versionstamp),
              TxnErrorCode::TXN_OK);
    EXPECT_EQ(offset.offset_tso(), 101);
    EXPECT_EQ(versionstamp, Versionstamp(100, 1));

    TableStreamPartitionSetPB binding;
    binding.mutable_identity()->CopyFrom(identity);
    binding.add_partition_ids(partition_id);
    binding.add_partition_ids(partition_id + 1);
    TableStreamOffsetMap offsets;
    TableStreamOffsetVersionstampMap versionstamps;
    ASSERT_EQ(snapshot_reader.get_table_stream_offsets(snapshot_read_txn.get(), {binding}, &offsets,
                                                       &versionstamps, true),
              TxnErrorCode::TXN_OK);
    ASSERT_EQ(offsets.at(identity.stream_id()).size(), 1);
    EXPECT_EQ(offsets.at(identity.stream_id()).at(partition_id).offset_tso(), 101);
    EXPECT_EQ(versionstamps.at(identity.stream_id()).at(partition_id), Versionstamp(100, 1));
    EXPECT_FALSE(offsets.at(identity.stream_id()).contains(partition_id + 1));
}

TEST(MetaReaderTest, BatchGetTableVersion) {
    auto txn_kv = std::make_shared<MemTxnKv>();
    ASSERT_EQ(txn_kv->init(), 0);

    std::string instance_id = "test_instance";
    std::vector<int64_t> table_ids = {1001, 1002, 1003, 1004};

    {
        // Test empty input
        MetaReader meta_reader(instance_id, txn_kv.get());
        std::vector<int64_t> empty_ids;
        std::unordered_map<int64_t, Versionstamp> table_versions;
        TxnErrorCode err = meta_reader.get_table_versions(empty_ids, &table_versions);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_TRUE(table_versions.empty());
    }

    {
        // Test all keys not found
        MetaReader meta_reader(instance_id, txn_kv.get());
        std::unordered_map<int64_t, Versionstamp> table_versions;
        TxnErrorCode err = meta_reader.get_table_versions(table_ids, &table_versions);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_TRUE(table_versions.empty());
    }

    {
        // Put some table versions (skip table_ids[1] to test partial results)
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);

        for (size_t i = 0; i < table_ids.size(); ++i) {
            if (i == 1) continue; // Skip table_ids[1]
            std::string table_version_key =
                    versioned::table_version_key({instance_id, table_ids[i]});
            versioned_put(txn.get(), table_version_key, "");
        }
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    {
        // Test partial results
        MetaReader meta_reader(instance_id, txn_kv.get());
        std::unordered_map<int64_t, Versionstamp> table_versions;
        TxnErrorCode err = meta_reader.get_table_versions(table_ids, &table_versions);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_EQ(table_versions.size(), 3); // All except table_ids[1]

        // Check min_read_version
        Versionstamp min_expected = Versionstamp::max();
        for (const auto& [table_id, version] : table_versions) {
            min_expected = std::min(min_expected, version);
        }
        ASSERT_EQ(meta_reader.min_read_versionstamp(), min_expected);

        for (size_t i = 0; i < table_ids.size(); ++i) {
            if (i == 1) {
                ASSERT_EQ(table_versions.find(table_ids[i]), table_versions.end());
            } else {
                ASSERT_NE(table_versions.find(table_ids[i]), table_versions.end());
            }
        }
    }

    {
        // Put the missing table version
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        std::string table_version_key = versioned::table_version_key({instance_id, table_ids[1]});
        versioned_put(txn.get(), table_version_key, "");
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    {
        // Test all keys found
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        MetaReader meta_reader(instance_id, txn_kv.get());
        std::unordered_map<int64_t, Versionstamp> table_versions;
        TxnErrorCode err = meta_reader.get_table_versions(txn.get(), table_ids, &table_versions);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_EQ(table_versions.size(), table_ids.size());

        // Check min_read_version
        Versionstamp min_expected = Versionstamp::max();
        for (const auto& [table_id, version] : table_versions) {
            min_expected = std::min(min_expected, version);
        }
        ASSERT_EQ(meta_reader.min_read_versionstamp(), min_expected);

        for (int64_t table_id : table_ids) {
            ASSERT_NE(table_versions.find(table_id), table_versions.end());
        }
    }
}

TEST(MetaReaderTest, GetPartitionVersion) {
    auto txn_kv = std::make_shared<MemTxnKv>();
    ASSERT_EQ(txn_kv->init(), 0);

    std::string instance_id = "test_instance";
    int64_t partition_id = 2001;
    {
        // NOT FOUND
        MetaReader meta_reader(instance_id, txn_kv.get());
        VersionPB version_pb;
        Versionstamp partition_version;
        TxnErrorCode err =
                meta_reader.get_partition_version(partition_id, &version_pb, &partition_version);
        ASSERT_EQ(err, TxnErrorCode::TXN_KEY_NOT_FOUND);
    }

    {
        // Put a partition version
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        std::string partition_version_key =
                versioned::partition_version_key({instance_id, partition_id});
        VersionPB version_pb;
        version_pb.set_version(100);
        versioned_put(txn.get(), partition_version_key, version_pb.SerializeAsString());
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    VersionPB version_pb1;
    Versionstamp partition_version1;
    {
        MetaReader meta_reader(instance_id, txn_kv.get());
        TxnErrorCode err =
                meta_reader.get_partition_version(partition_id, &version_pb1, &partition_version1);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_EQ(version_pb1.version(), 100);
        ASSERT_EQ(meta_reader.min_read_versionstamp(), partition_version1);
    }

    {
        // Put another partition version
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        std::string partition_version_key =
                versioned::partition_version_key({instance_id, partition_id});
        VersionPB version_pb;
        version_pb.set_version(200);
        versioned_put(txn.get(), partition_version_key, version_pb.SerializeAsString());
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    VersionPB version_pb2;
    Versionstamp partition_version2;
    {
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        MetaReader meta_reader(instance_id, txn_kv.get());
        TxnErrorCode err = meta_reader.get_partition_version(txn.get(), partition_id, &version_pb2,
                                                             &partition_version2);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_EQ(version_pb2.version(), 200);
        ASSERT_EQ(meta_reader.min_read_versionstamp(), partition_version2);
    }

    ASSERT_LT(partition_version1, partition_version2);
}

TEST(MetaReaderTest, BatchGetPartitionVersion) {
    auto txn_kv = std::make_shared<MemTxnKv>();
    ASSERT_EQ(txn_kv->init(), 0);

    std::string instance_id = "test_instance";
    std::vector<int64_t> partition_ids = {2001, 2002, 2003, 2004};

    {
        // Test empty input
        MetaReader meta_reader(instance_id, txn_kv.get());
        std::vector<int64_t> empty_ids;
        std::unordered_map<int64_t, VersionPB> versions;
        std::unordered_map<int64_t, Versionstamp> versionstamps;
        TxnErrorCode err = meta_reader.get_partition_versions(empty_ids, &versions, &versionstamps);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_TRUE(versions.empty());
        ASSERT_TRUE(versionstamps.empty());
    }

    {
        // Put some partition versions (skip partition_ids[1] to test partial results)
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);

        for (size_t i = 0; i < partition_ids.size(); ++i) {
            if (i == 1) continue; // Skip partition_ids[1]
            std::string partition_version_key =
                    versioned::partition_version_key({instance_id, partition_ids[i]});
            VersionPB version_pb;
            version_pb.set_version(100 + i * 10); // Different versions: 100, 120, 130
            versioned_put(txn.get(), partition_version_key, version_pb.SerializeAsString());
        }
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    {
        // Test partial results
        MetaReader meta_reader(instance_id, txn_kv.get());
        std::unordered_map<int64_t, VersionPB> versions;
        std::unordered_map<int64_t, Versionstamp> versionstamps;
        TxnErrorCode err =
                meta_reader.get_partition_versions(partition_ids, &versions, &versionstamps);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_EQ(versions.size(), 3); // All except partition_ids[1]
        ASSERT_EQ(versionstamps.size(), 3);

        // Check min_read_version
        Versionstamp min_expected = Versionstamp::max();
        for (const auto& [partition_id, version] : versionstamps) {
            min_expected = std::min(min_expected, version);
        }
        ASSERT_EQ(meta_reader.min_read_versionstamp(), min_expected);

        for (size_t i = 0; i < partition_ids.size(); ++i) {
            if (i == 1) {
                ASSERT_EQ(versions.find(partition_ids[i]), versions.end());
                ASSERT_EQ(versionstamps.find(partition_ids[i]), versionstamps.end());
            } else {
                ASSERT_NE(versions.find(partition_ids[i]), versions.end());
                ASSERT_NE(versionstamps.find(partition_ids[i]), versionstamps.end());
                ASSERT_EQ(versions[partition_ids[i]].version(), 100 + i * 10);
            }
        }
    }

    {
        // Put the missing partition version
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        std::string partition_version_key =
                versioned::partition_version_key({instance_id, partition_ids[1]});
        VersionPB version_pb;
        version_pb.set_version(110);
        versioned_put(txn.get(), partition_version_key, version_pb.SerializeAsString());
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    {
        // Test all keys found
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        MetaReader meta_reader(instance_id, txn_kv.get());
        std::unordered_map<int64_t, VersionPB> versions;
        std::unordered_map<int64_t, Versionstamp> versionstamps;
        TxnErrorCode err = meta_reader.get_partition_versions(txn.get(), partition_ids, &versions,
                                                              &versionstamps);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_EQ(versions.size(), partition_ids.size());
        ASSERT_EQ(versionstamps.size(), partition_ids.size());

        // Check min_read_version
        Versionstamp min_expected = Versionstamp::max();
        for (const auto& [partition_id, version] : versionstamps) {
            min_expected = std::min(min_expected, version);
        }
        ASSERT_EQ(meta_reader.min_read_versionstamp(), min_expected);

        for (size_t i = 0; i < partition_ids.size(); ++i) {
            int64_t partition_id = partition_ids[i];
            ASSERT_NE(versions.find(partition_id), versions.end());
            ASSERT_NE(versionstamps.find(partition_id), versionstamps.end());
            int32_t expected_version = (i == 1) ? 110 : 100 + i * 10;
            ASSERT_EQ(versions[partition_id].version(), expected_version);
        }
    }

    {
        // Test only versionstamps (versions = nullptr)
        MetaReader meta_reader(instance_id, txn_kv.get());
        std::unordered_map<int64_t, Versionstamp> versionstamps;
        TxnErrorCode err =
                meta_reader.get_partition_versions(partition_ids, nullptr, &versionstamps);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_EQ(versionstamps.size(), partition_ids.size());

        // Check min_read_version
        Versionstamp min_expected = Versionstamp::max();
        for (const auto& [partition_id, version] : versionstamps) {
            min_expected = std::min(min_expected, version);
        }
        ASSERT_EQ(meta_reader.min_read_versionstamp(), min_expected);
    }

    {
        // Test only versions (versionstamps = nullptr)
        MetaReader meta_reader(instance_id, txn_kv.get());
        std::unordered_map<int64_t, VersionPB> versions;
        TxnErrorCode err = meta_reader.get_partition_versions(partition_ids, &versions, nullptr);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_EQ(versions.size(), partition_ids.size());
        // For this case, min_read_version should still be updated even though versionstamps is nullptr
        ASSERT_NE(meta_reader.min_read_versionstamp(), Versionstamp::max());
    }
}

TEST(MetaReaderTest, GetPartitionVersionsWithPendingTxn) {
    auto txn_kv = std::make_shared<MemTxnKv>();
    ASSERT_EQ(txn_kv->init(), 0);

    std::string instance_id = "test_instance";
    std::vector<int64_t> partition_ids = {2101, 2102, 2103, 2104};

    {
        // Test empty input
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        MetaReader meta_reader(instance_id, txn_kv.get());
        std::vector<int64_t> empty_ids;
        std::unordered_map<int64_t, int64_t> versions;
        int64_t last_pending_txn_id = -1;
        TxnErrorCode err = meta_reader.get_partition_versions(txn.get(), empty_ids, &versions,
                                                              &last_pending_txn_id);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_TRUE(versions.empty());
        ASSERT_EQ(last_pending_txn_id, -1);
    }

    {
        // Put some partition versions (skip partition_ids[1] to test partial results)
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);

        for (size_t i = 0; i < partition_ids.size(); ++i) {
            if (i == 1) continue; // Skip partition_ids[1]
            std::string partition_version_key =
                    versioned::partition_version_key({instance_id, partition_ids[i]});
            VersionPB version_pb;
            version_pb.set_version(100 + i * 10); // Different versions: 100, 120, 130
            // Add pending transaction for partition_ids[2]
            if (i == 2) {
                version_pb.add_pending_txn_ids(3001);
                version_pb.add_pending_txn_ids(3002);
            }
            versioned_put(txn.get(), partition_version_key, version_pb.SerializeAsString());
        }
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    {
        // Test partial results - partition not found should be set to 1
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        MetaReader meta_reader(instance_id, txn_kv.get());
        std::unordered_map<int64_t, int64_t> versions;
        int64_t last_pending_txn_id = -1;
        TxnErrorCode err = meta_reader.get_partition_versions(txn.get(), partition_ids, &versions,
                                                              &last_pending_txn_id);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_EQ(versions.size(), 4); // All partition_ids, missing one should be set to 1

        for (size_t i = 0; i < partition_ids.size(); ++i) {
            int64_t partition_id = partition_ids[i];
            ASSERT_NE(versions.find(partition_id), versions.end());
            if (i == 1) {
                // Missing partition should be set to 1
                ASSERT_EQ(versions[partition_id], 1);
            } else {
                ASSERT_EQ(versions[partition_id], 100 + i * 10);
            }
        }
        // Should return first pending transaction ID from partition_ids[2]
        ASSERT_EQ(last_pending_txn_id, 3001);
    }

    {
        // Put the missing partition version without pending transaction
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        std::string partition_version_key =
                versioned::partition_version_key({instance_id, partition_ids[1]});
        VersionPB version_pb;
        version_pb.set_version(110);
        versioned_put(txn.get(), partition_version_key, version_pb.SerializeAsString());
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    {
        // Test all keys found with no pending transactions
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        MetaReader meta_reader(instance_id, txn_kv.get());
        std::unordered_map<int64_t, int64_t> versions;
        int64_t last_pending_txn_id = -1;
        TxnErrorCode err = meta_reader.get_partition_versions(txn.get(), partition_ids, &versions,
                                                              &last_pending_txn_id);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_EQ(versions.size(), partition_ids.size());

        for (size_t i = 0; i < partition_ids.size(); ++i) {
            int64_t partition_id = partition_ids[i];
            ASSERT_NE(versions.find(partition_id), versions.end());
            int32_t expected_version = (i == 1) ? 110 : 100 + i * 10;
            ASSERT_EQ(versions[partition_id], expected_version);
        }
        // Should still return first pending transaction ID from partition_ids[2]
        ASSERT_EQ(last_pending_txn_id, 3001);
    }

    {
        // Remove pending transactions from partition_ids[2]
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        std::string partition_version_key =
                versioned::partition_version_key({instance_id, partition_ids[2]});
        VersionPB version_pb;
        version_pb.set_version(120);
        // No pending transactions this time
        versioned_put(txn.get(), partition_version_key, version_pb.SerializeAsString());
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    {
        // Test with no pending transactions
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        MetaReader meta_reader(instance_id, txn_kv.get());
        std::unordered_map<int64_t, int64_t> versions;
        int64_t last_pending_txn_id = -1;
        TxnErrorCode err = meta_reader.get_partition_versions(txn.get(), partition_ids, &versions,
                                                              &last_pending_txn_id);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_EQ(versions.size(), partition_ids.size());

        for (size_t i = 0; i < partition_ids.size(); ++i) {
            int64_t partition_id = partition_ids[i];
            ASSERT_NE(versions.find(partition_id), versions.end());
            int32_t expected_version = (i == 1) ? 110 : (i == 2) ? 120 : 100 + i * 10;
            ASSERT_EQ(versions[partition_id], expected_version);
        }
        // No pending transactions, so last_pending_txn_id should remain -1
        ASSERT_EQ(last_pending_txn_id, -1);
    }

    {
        // Test using the convenience method (without snapshot parameter)
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        MetaReader meta_reader(instance_id, txn_kv.get());
        std::unordered_map<int64_t, int64_t> versions;
        int64_t last_pending_txn_id = -1;
        TxnErrorCode err = meta_reader.get_partition_versions(txn.get(), partition_ids, &versions,
                                                              &last_pending_txn_id);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_EQ(versions.size(), partition_ids.size());
        // Verify same results as the explicit snapshot=false test
        for (size_t i = 0; i < partition_ids.size(); ++i) {
            int64_t partition_id = partition_ids[i];
            ASSERT_NE(versions.find(partition_id), versions.end());
            int32_t expected_version = (i == 1) ? 110 : (i == 2) ? 120 : 100 + i * 10;
            ASSERT_EQ(versions[partition_id], expected_version);
        }
        ASSERT_EQ(last_pending_txn_id, -1);
    }
}

TEST(MetaReaderTest, GetTabletLoadStats) {
    auto txn_kv = std::make_shared<MemTxnKv>();
    ASSERT_EQ(txn_kv->init(), 0);

    std::string instance_id = "test_instance";
    int64_t tablet_id = 3001;
    {
        // NOT FOUND
        MetaReader meta_reader(instance_id, txn_kv.get());
        TabletStatsPB tablet_stats;
        Versionstamp tablet_stats_version;
        TxnErrorCode err =
                meta_reader.get_tablet_load_stats(tablet_id, &tablet_stats, &tablet_stats_version);
        ASSERT_EQ(err, TxnErrorCode::TXN_KEY_NOT_FOUND);
    }

    {
        // Put a tablet load stats
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        std::string tablet_load_stats_key =
                versioned::tablet_load_stats_key({instance_id, tablet_id});
        TabletStatsPB tablet_stats;
        tablet_stats.set_num_rows(1000);
        tablet_stats.set_data_size(500000);
        versioned_put(txn.get(), tablet_load_stats_key, tablet_stats.SerializeAsString());
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    TabletStatsPB tablet_stats1;
    Versionstamp tablet_stats_version1;
    {
        MetaReader meta_reader(instance_id, txn_kv.get());
        TxnErrorCode err = meta_reader.get_tablet_load_stats(tablet_id, &tablet_stats1,
                                                             &tablet_stats_version1);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_EQ(tablet_stats1.num_rows(), 1000);
        ASSERT_EQ(tablet_stats1.data_size(), 500000);
        ASSERT_EQ(meta_reader.min_read_versionstamp(), tablet_stats_version1);
    }

    {
        // Put another tablet load stats
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        std::string tablet_load_stats_key =
                versioned::tablet_load_stats_key({instance_id, tablet_id});
        TabletStatsPB tablet_stats;
        tablet_stats.set_num_rows(2000);
        tablet_stats.set_data_size(1000000);
        versioned_put(txn.get(), tablet_load_stats_key, tablet_stats.SerializeAsString());
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    TabletStatsPB tablet_stats2;
    Versionstamp tablet_stats_version2;
    {
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        MetaReader meta_reader(instance_id, txn_kv.get());
        TxnErrorCode err = meta_reader.get_tablet_load_stats(txn.get(), tablet_id, &tablet_stats2,
                                                             &tablet_stats_version2);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_EQ(tablet_stats2.num_rows(), 2000);
        ASSERT_EQ(tablet_stats2.data_size(), 1000000);
        ASSERT_EQ(meta_reader.min_read_versionstamp(), tablet_stats_version2);
    }

    ASSERT_LT(tablet_stats_version1, tablet_stats_version2);
}

TEST(MetaReaderTest, BatchGetTabletLoadStats) {
    auto txn_kv = std::make_shared<MemTxnKv>();
    ASSERT_EQ(txn_kv->init(), 0);

    std::string instance_id = "test_instance";
    std::vector<int64_t> tablet_ids = {3001, 3002, 3003, 3004};

    {
        // Test empty input
        MetaReader meta_reader(instance_id, txn_kv.get());
        std::vector<int64_t> empty_ids;
        std::unordered_map<int64_t, TabletStatsPB> tablet_stats;
        std::unordered_map<int64_t, Versionstamp> versionstamps;
        TxnErrorCode err =
                meta_reader.get_tablet_load_stats(empty_ids, &tablet_stats, &versionstamps);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_TRUE(tablet_stats.empty());
        ASSERT_TRUE(versionstamps.empty());
    }

    {
        // Test all keys not found
        MetaReader meta_reader(instance_id, txn_kv.get());
        std::unordered_map<int64_t, TabletStatsPB> tablet_stats;
        std::unordered_map<int64_t, Versionstamp> versionstamps;
        TxnErrorCode err =
                meta_reader.get_tablet_load_stats(tablet_ids, &tablet_stats, &versionstamps);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_TRUE(tablet_stats.empty());
        ASSERT_TRUE(versionstamps.empty());
    }

    {
        // Put some tablet load stats (skip tablet_ids[1] to test partial results)
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);

        for (size_t i = 0; i < tablet_ids.size(); ++i) {
            if (i == 1) continue; // Skip tablet_ids[1]
            std::string tablet_load_stats_key =
                    versioned::tablet_load_stats_key({instance_id, tablet_ids[i]});
            TabletStatsPB tablet_stats;
            tablet_stats.set_num_rows(1000 * (i + 1));
            tablet_stats.set_data_size(500000 * (i + 1));
            versioned_put(txn.get(), tablet_load_stats_key, tablet_stats.SerializeAsString());
        }
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    {
        // Test partial results
        MetaReader meta_reader(instance_id, txn_kv.get());
        std::unordered_map<int64_t, TabletStatsPB> tablet_stats;
        std::unordered_map<int64_t, Versionstamp> versionstamps;
        TxnErrorCode err =
                meta_reader.get_tablet_load_stats(tablet_ids, &tablet_stats, &versionstamps);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_EQ(tablet_stats.size(), 3); // All except tablet_ids[1]
        ASSERT_EQ(versionstamps.size(), 3);

        // Check min_read_version
        Versionstamp min_expected = Versionstamp::max();
        for (const auto& [tablet_id, versionstamp] : versionstamps) {
            min_expected = std::min(min_expected, versionstamp);
        }
        ASSERT_EQ(meta_reader.min_read_versionstamp(), min_expected);

        for (size_t i = 0; i < tablet_ids.size(); ++i) {
            if (i == 1) {
                ASSERT_EQ(tablet_stats.count(tablet_ids[i]), 0);
                ASSERT_EQ(versionstamps.count(tablet_ids[i]), 0);
            } else {
                ASSERT_EQ(tablet_stats.count(tablet_ids[i]), 1);
                ASSERT_EQ(versionstamps.count(tablet_ids[i]), 1);
                ASSERT_EQ(tablet_stats.at(tablet_ids[i]).num_rows(), 1000 * (i + 1));
                ASSERT_EQ(tablet_stats.at(tablet_ids[i]).data_size(), 500000 * (i + 1));
            }
        }
    }

    {
        // Put the missing tablet load stats
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        std::string tablet_load_stats_key =
                versioned::tablet_load_stats_key({instance_id, tablet_ids[1]});
        TabletStatsPB tablet_stats;
        tablet_stats.set_num_rows(2000);
        tablet_stats.set_data_size(1000000);
        versioned_put(txn.get(), tablet_load_stats_key, tablet_stats.SerializeAsString());
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    {
        // Test all keys found
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        MetaReader meta_reader(instance_id, txn_kv.get());
        std::unordered_map<int64_t, TabletStatsPB> tablet_stats;
        std::unordered_map<int64_t, Versionstamp> versionstamps;
        TxnErrorCode err = meta_reader.get_tablet_load_stats(txn.get(), tablet_ids, &tablet_stats,
                                                             &versionstamps);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_EQ(tablet_stats.size(), tablet_ids.size());
        ASSERT_EQ(versionstamps.size(), tablet_ids.size());

        // Check min_read_version
        Versionstamp min_expected = Versionstamp::max();
        for (const auto& [tablet_id, versionstamp] : versionstamps) {
            min_expected = std::min(min_expected, versionstamp);
        }
        ASSERT_EQ(meta_reader.min_read_versionstamp(), min_expected);

        for (size_t i = 0; i < tablet_ids.size(); ++i) {
            ASSERT_EQ(tablet_stats.count(tablet_ids[i]), 1);
            ASSERT_EQ(versionstamps.count(tablet_ids[i]), 1);
            if (i == 1) {
                ASSERT_EQ(tablet_stats.at(tablet_ids[i]).num_rows(), 2000);
                ASSERT_EQ(tablet_stats.at(tablet_ids[i]).data_size(), 1000000);
            } else {
                ASSERT_EQ(tablet_stats.at(tablet_ids[i]).num_rows(), 1000 * (i + 1));
                ASSERT_EQ(tablet_stats.at(tablet_ids[i]).data_size(), 500000 * (i + 1));
            }
        }
    }
}

TEST(MetaReaderTest, GetTabletCompactStats) {
    auto txn_kv = std::make_shared<MemTxnKv>();
    ASSERT_EQ(txn_kv->init(), 0);

    std::string instance_id = "test_instance";
    int64_t tablet_id = 3001;

    {
        // Test key not found when no compact stats exist
        MetaReader meta_reader(instance_id, txn_kv.get());
        TabletStatsPB tablet_stats;
        Versionstamp tablet_stats_version;
        TxnErrorCode err = meta_reader.get_tablet_compact_stats(tablet_id, &tablet_stats,
                                                                &tablet_stats_version);
        ASSERT_EQ(err, TxnErrorCode::TXN_KEY_NOT_FOUND);
    }

    {
        // Put a comprehensive tablet compact stats
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        std::string tablet_compact_stats_key =
                versioned::tablet_compact_stats_key({instance_id, tablet_id});
        TabletStatsPB tablet_stats;

        // Set all compaction-related fields
        tablet_stats.set_base_compaction_cnt(5);
        tablet_stats.set_cumulative_compaction_cnt(10);
        tablet_stats.set_cumulative_point(100);
        tablet_stats.set_last_base_compaction_time_ms(1234567890);
        tablet_stats.set_last_cumu_compaction_time_ms(2345678901);
        tablet_stats.set_full_compaction_cnt(2);
        tablet_stats.set_last_full_compaction_time_ms(3456789012);

        // Set data-related fields
        tablet_stats.set_num_rows(500);
        tablet_stats.set_num_rowsets(8);
        tablet_stats.set_num_segments(25);
        tablet_stats.set_data_size(250000);
        tablet_stats.set_index_size(25000);
        tablet_stats.set_segment_size(300000);

        versioned_put(txn.get(), tablet_compact_stats_key, tablet_stats.SerializeAsString());
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    TabletStatsPB tablet_stats1;
    Versionstamp tablet_stats_version1;
    {
        // Test successful get with created transaction
        MetaReader meta_reader(instance_id, txn_kv.get());
        TxnErrorCode err = meta_reader.get_tablet_compact_stats(tablet_id, &tablet_stats1,
                                                                &tablet_stats_version1);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);

        // Verify compaction-related fields
        ASSERT_EQ(tablet_stats1.base_compaction_cnt(), 5);
        ASSERT_EQ(tablet_stats1.cumulative_compaction_cnt(), 10);
        ASSERT_EQ(tablet_stats1.cumulative_point(), 100);
        ASSERT_EQ(tablet_stats1.last_base_compaction_time_ms(), 1234567890);
        ASSERT_EQ(tablet_stats1.last_cumu_compaction_time_ms(), 2345678901);
        ASSERT_EQ(tablet_stats1.full_compaction_cnt(), 2);
        ASSERT_EQ(tablet_stats1.last_full_compaction_time_ms(), 3456789012);

        // Verify data-related fields
        ASSERT_EQ(tablet_stats1.num_rows(), 500);
        ASSERT_EQ(tablet_stats1.num_rowsets(), 8);
        ASSERT_EQ(tablet_stats1.num_segments(), 25);
        ASSERT_EQ(tablet_stats1.data_size(), 250000);
        ASSERT_EQ(tablet_stats1.index_size(), 25000);
        ASSERT_EQ(tablet_stats1.segment_size(), 300000);

        ASSERT_EQ(meta_reader.min_read_versionstamp(), tablet_stats_version1);
    }

    {
        // Update tablet compact stats with new values
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        std::string tablet_compact_stats_key =
                versioned::tablet_compact_stats_key({instance_id, tablet_id});
        TabletStatsPB tablet_stats;

        // Update compaction-related fields
        tablet_stats.set_base_compaction_cnt(8);
        tablet_stats.set_cumulative_compaction_cnt(15);
        tablet_stats.set_cumulative_point(200);
        tablet_stats.set_last_base_compaction_time_ms(1234567890 + 10000);
        tablet_stats.set_last_cumu_compaction_time_ms(2345678901 + 10000);
        tablet_stats.set_full_compaction_cnt(3);
        tablet_stats.set_last_full_compaction_time_ms(3456789012 + 10000);

        // Update data-related fields
        tablet_stats.set_num_rows(1000);
        tablet_stats.set_num_rowsets(12);
        tablet_stats.set_num_segments(40);
        tablet_stats.set_data_size(500000);
        tablet_stats.set_index_size(50000);
        tablet_stats.set_segment_size(600000);

        versioned_put(txn.get(), tablet_compact_stats_key, tablet_stats.SerializeAsString());
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    TabletStatsPB tablet_stats2;
    Versionstamp tablet_stats_version2;
    {
        // Test successful get with provided transaction
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        MetaReader meta_reader(instance_id, txn_kv.get());
        TxnErrorCode err = meta_reader.get_tablet_compact_stats(
                txn.get(), tablet_id, &tablet_stats2, &tablet_stats_version2);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);

        // Verify updated compaction-related fields
        ASSERT_EQ(tablet_stats2.base_compaction_cnt(), 8);
        ASSERT_EQ(tablet_stats2.cumulative_compaction_cnt(), 15);
        ASSERT_EQ(tablet_stats2.cumulative_point(), 200);
        ASSERT_EQ(tablet_stats2.last_base_compaction_time_ms(), 1234567890 + 10000);
        ASSERT_EQ(tablet_stats2.last_cumu_compaction_time_ms(), 2345678901 + 10000);
        ASSERT_EQ(tablet_stats2.full_compaction_cnt(), 3);
        ASSERT_EQ(tablet_stats2.last_full_compaction_time_ms(), 3456789012 + 10000);

        // Verify updated data-related fields
        ASSERT_EQ(tablet_stats2.num_rows(), 1000);
        ASSERT_EQ(tablet_stats2.num_rowsets(), 12);
        ASSERT_EQ(tablet_stats2.num_segments(), 40);
        ASSERT_EQ(tablet_stats2.data_size(), 500000);
        ASSERT_EQ(tablet_stats2.index_size(), 50000);
        ASSERT_EQ(tablet_stats2.segment_size(), 600000);

        ASSERT_EQ(meta_reader.min_read_versionstamp(), tablet_stats_version2);
    }

    // Verify version ordering
    ASSERT_LT(tablet_stats_version1, tablet_stats_version2);

    // Test with snapshot version functionality
    Versionstamp snapshot_version;
    {
        // Get current snapshot version
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        int64_t version = 0;
        ASSERT_EQ(txn->get_read_version(&version), TxnErrorCode::TXN_OK);
        snapshot_version = Versionstamp(version, 1);
    }

    {
        // Update compact stats again
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        std::string tablet_compact_stats_key =
                versioned::tablet_compact_stats_key({instance_id, tablet_id});
        TabletStatsPB tablet_stats;
        tablet_stats.set_num_rows(2000);          // New value
        tablet_stats.set_data_size(1000000);      // New value
        tablet_stats.set_base_compaction_cnt(10); // New value
        versioned_put(txn.get(), tablet_compact_stats_key, tablet_stats.SerializeAsString());
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    {
        // Test reading with snapshot version - should get old data
        MetaReader meta_reader(instance_id, txn_kv.get(), snapshot_version);
        TabletStatsPB tablet_stats;
        Versionstamp tablet_stats_version;
        TxnErrorCode err = meta_reader.get_tablet_compact_stats(tablet_id, &tablet_stats,
                                                                &tablet_stats_version, true);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);

        // Should get previous values (before the latest update)
        ASSERT_EQ(tablet_stats.num_rows(), 1000);         // Old value, not 2000
        ASSERT_EQ(tablet_stats.data_size(), 500000);      // Old value, not 1000000
        ASSERT_EQ(tablet_stats.base_compaction_cnt(), 8); // Old value, not 10
    }

    {
        // Test reading without snapshot - should get new data
        MetaReader meta_reader(instance_id, txn_kv.get());
        TabletStatsPB tablet_stats;
        Versionstamp tablet_stats_version;
        TxnErrorCode err = meta_reader.get_tablet_compact_stats(tablet_id, &tablet_stats,
                                                                &tablet_stats_version);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);

        // Should get latest values
        ASSERT_EQ(tablet_stats.num_rows(), 2000);          // Updated value
        ASSERT_EQ(tablet_stats.data_size(), 1000000);      // Updated value
        ASSERT_EQ(tablet_stats.base_compaction_cnt(), 10); // Updated value
    }

    {
        // Test with snapshot flag but no snapshot version
        MetaReader meta_reader(instance_id, txn_kv.get());
        TabletStatsPB tablet_stats;
        Versionstamp tablet_stats_version;
        TxnErrorCode err = meta_reader.get_tablet_compact_stats(tablet_id, &tablet_stats,
                                                                &tablet_stats_version, true);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);

        // Should get current values since snapshot flag is set but no snapshot version
        ASSERT_EQ(tablet_stats.num_rows(), 2000);
        ASSERT_EQ(tablet_stats.data_size(), 1000000);
    }

    {
        // Test with nullptr parameters
        MetaReader meta_reader(instance_id, txn_kv.get());
        TxnErrorCode err = meta_reader.get_tablet_compact_stats(tablet_id, nullptr, nullptr);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
    }

    {
        // Test getting non-existent tablet
        MetaReader meta_reader(instance_id, txn_kv.get());
        TabletStatsPB tablet_stats;
        Versionstamp tablet_stats_version;
        TxnErrorCode err = meta_reader.get_tablet_compact_stats(tablet_id + 1, &tablet_stats,
                                                                &tablet_stats_version);
        ASSERT_EQ(err, TxnErrorCode::TXN_KEY_NOT_FOUND);
    }
}

TEST(MetaReaderTest, GetTabletMergedStats) {
    auto txn_kv = std::make_shared<MemTxnKv>();
    ASSERT_EQ(txn_kv->init(), 0);

    std::string instance_id = "test_instance";
    int64_t tablet_id = 3001;

    {
        // Test when both load and compact stats are not found
        MetaReader meta_reader(instance_id, txn_kv.get());
        TabletStatsPB tablet_stats;
        Versionstamp tablet_stats_version;
        TxnErrorCode err = meta_reader.get_tablet_merged_stats(tablet_id, &tablet_stats,
                                                               &tablet_stats_version);
        ASSERT_EQ(err, TxnErrorCode::TXN_KEY_NOT_FOUND);
    }

    {
        // Put tablet load stats
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        std::string tablet_load_stats_key =
                versioned::tablet_load_stats_key({instance_id, tablet_id});
        TabletStatsPB load_stats;
        load_stats.set_num_rows(1000);
        load_stats.set_num_rowsets(10);
        load_stats.set_num_segments(20);
        load_stats.set_data_size(500000);
        load_stats.set_index_size(50000);
        load_stats.set_segment_size(600000);
        versioned_put(txn.get(), tablet_load_stats_key, load_stats.SerializeAsString());
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    {
        // Test when only load stats exist (compact stats not found)
        MetaReader meta_reader(instance_id, txn_kv.get());
        TabletStatsPB tablet_stats;
        Versionstamp tablet_stats_version;
        TxnErrorCode err = meta_reader.get_tablet_merged_stats(tablet_id, &tablet_stats,
                                                               &tablet_stats_version);
        ASSERT_EQ(err, TxnErrorCode::TXN_KEY_NOT_FOUND);
    }

    Versionstamp load_version, compact_version;
    {
        // Put tablet compact stats
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        std::string tablet_compact_stats_key =
                versioned::tablet_compact_stats_key({instance_id, tablet_id});
        TabletStatsPB compact_stats;
        compact_stats.set_base_compaction_cnt(5);
        compact_stats.set_cumulative_compaction_cnt(10);
        compact_stats.set_cumulative_point(100);
        compact_stats.set_last_base_compaction_time_ms(1234567890);
        compact_stats.set_last_cumu_compaction_time_ms(2345678901);
        compact_stats.set_full_compaction_cnt(2);
        compact_stats.set_last_full_compaction_time_ms(3456789012);
        compact_stats.set_num_rows(500);
        compact_stats.set_num_rowsets(5);
        compact_stats.set_num_segments(15);
        compact_stats.set_data_size(250000);
        compact_stats.set_index_size(25000);
        compact_stats.set_segment_size(300000);
        versioned_put(txn.get(), tablet_compact_stats_key, compact_stats.SerializeAsString());
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    TabletStatsPB merged_stats;
    Versionstamp merged_version;
    {
        // Test merged stats
        MetaReader meta_reader(instance_id, txn_kv.get());
        TxnErrorCode err =
                meta_reader.get_tablet_merged_stats(tablet_id, &merged_stats, &merged_version);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);

        // Check compaction-related fields (copied from compact stats)
        EXPECT_EQ(merged_stats.base_compaction_cnt(), 5);
        EXPECT_EQ(merged_stats.cumulative_compaction_cnt(), 10);
        EXPECT_EQ(merged_stats.cumulative_point(), 100);
        EXPECT_EQ(merged_stats.last_base_compaction_time_ms(), 1234567890);
        EXPECT_EQ(merged_stats.last_cumu_compaction_time_ms(), 2345678901);
        EXPECT_EQ(merged_stats.full_compaction_cnt(), 2);
        EXPECT_EQ(merged_stats.last_full_compaction_time_ms(), 3456789012);

        // Check data-related fields (sum of load stats and compact stats)
        EXPECT_EQ(merged_stats.num_rows(), 1500);       // 1000 + 500
        EXPECT_EQ(merged_stats.num_rowsets(), 15);      // 10 + 5
        EXPECT_EQ(merged_stats.num_segments(), 35);     // 20 + 15
        EXPECT_EQ(merged_stats.data_size(), 750000);    // 500000 + 250000
        EXPECT_EQ(merged_stats.index_size(), 75000);    // 50000 + 25000
        EXPECT_EQ(merged_stats.segment_size(), 900000); // 600000 + 300000

        // Check min_read_version - should be updated after reading both load and compact stats
        ASSERT_NE(meta_reader.min_read_versionstamp(), Versionstamp::max());
    }

    {
        // Get individual versions for comparison
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        MetaReader meta_reader(instance_id, txn_kv.get());

        TabletStatsPB load_stats, compact_stats;
        TxnErrorCode err1 =
                meta_reader.get_tablet_load_stats(txn.get(), tablet_id, &load_stats, &load_version);
        TxnErrorCode err2 = meta_reader.get_tablet_compact_stats(txn.get(), tablet_id,
                                                                 &compact_stats, &compact_version);
        ASSERT_EQ(err1, TxnErrorCode::TXN_OK);
        ASSERT_EQ(err2, TxnErrorCode::TXN_OK);

        // Merged version should be the min of load and compact versions
        if (load_version < compact_version) {
            ASSERT_EQ(merged_version, load_version);
        } else {
            ASSERT_EQ(merged_version, compact_version);
        }
    }

    {
        // Update load stats and test version update
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        std::string tablet_load_stats_key =
                versioned::tablet_load_stats_key({instance_id, tablet_id});
        TabletStatsPB updated_load_stats;
        updated_load_stats.set_num_rows(2000);
        updated_load_stats.set_num_rowsets(20);
        updated_load_stats.set_num_segments(40);
        updated_load_stats.set_data_size(1000000);
        updated_load_stats.set_index_size(100000);
        updated_load_stats.set_segment_size(1200000);
        versioned_put(txn.get(), tablet_load_stats_key, updated_load_stats.SerializeAsString());
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    TabletStatsPB updated_merged_stats;
    Versionstamp updated_merged_version;
    {
        // Test updated merged stats
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        MetaReader meta_reader(instance_id, txn_kv.get());
        TxnErrorCode err = meta_reader.get_tablet_merged_stats(
                txn.get(), tablet_id, &updated_merged_stats, &updated_merged_version);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);

        // Check updated data-related fields (sum of updated load stats and compact stats)
        EXPECT_EQ(updated_merged_stats.num_rows(), 2500);        // 2000 + 500
        EXPECT_EQ(updated_merged_stats.num_rowsets(), 25);       // 20 + 5
        EXPECT_EQ(updated_merged_stats.num_segments(), 55);      // 40 + 15
        EXPECT_EQ(updated_merged_stats.data_size(), 1250000);    // 1000000 + 250000
        EXPECT_EQ(updated_merged_stats.index_size(), 125000);    // 100000 + 25000
        EXPECT_EQ(updated_merged_stats.segment_size(), 1500000); // 1200000 + 300000

        // Compaction fields should remain the same
        EXPECT_EQ(updated_merged_stats.base_compaction_cnt(), 5);
        EXPECT_EQ(updated_merged_stats.cumulative_compaction_cnt(), 10);
    }

    // Merged version should be updated
    ASSERT_LT(merged_version, updated_merged_version);
}

TEST(MetaReaderTest, GetTabletIndex) {
    auto txn_kv = std::make_shared<MemTxnKv>();
    ASSERT_EQ(txn_kv->init(), 0);

    std::string instance_id = "test_instance";
    int64_t tablet_id = 5001;
    {
        // NOT FOUND
        MetaReader meta_reader(instance_id, txn_kv.get());
        TabletIndexPB tablet_index;
        TxnErrorCode err = meta_reader.get_tablet_index(tablet_id, &tablet_index);
        ASSERT_EQ(err, TxnErrorCode::TXN_KEY_NOT_FOUND);
    }

    {
        // Put a tablet index
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        std::string tablet_index_key = versioned::tablet_index_key({instance_id, tablet_id});
        TabletIndexPB tablet_index;
        tablet_index.set_db_id(1001);
        tablet_index.set_table_id(2001);
        tablet_index.set_index_id(3001);
        tablet_index.set_partition_id(4001);
        tablet_index.set_tablet_id(tablet_id);
        txn->put(tablet_index_key, tablet_index.SerializeAsString());
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    TabletIndexPB tablet_index1;
    {
        MetaReader meta_reader(instance_id, txn_kv.get());
        TxnErrorCode err = meta_reader.get_tablet_index(tablet_id, &tablet_index1);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_EQ(tablet_index1.db_id(), 1001);
        ASSERT_EQ(tablet_index1.table_id(), 2001);
        ASSERT_EQ(tablet_index1.index_id(), 3001);
        ASSERT_EQ(tablet_index1.partition_id(), 4001);
        ASSERT_EQ(tablet_index1.tablet_id(), tablet_id);
    }

    {
        // Put another tablet index (update)
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        std::string tablet_index_key = versioned::tablet_index_key({instance_id, tablet_id});
        TabletIndexPB tablet_index;
        tablet_index.set_db_id(1002);
        tablet_index.set_table_id(2002);
        tablet_index.set_index_id(3002);
        tablet_index.set_partition_id(4002);
        tablet_index.set_tablet_id(tablet_id);
        txn->put(tablet_index_key, tablet_index.SerializeAsString());
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    TabletIndexPB tablet_index2;
    {
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        MetaReader meta_reader(instance_id, txn_kv.get());
        TxnErrorCode err = meta_reader.get_tablet_index(txn.get(), tablet_id, &tablet_index2);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_EQ(tablet_index2.db_id(), 1002);
        ASSERT_EQ(tablet_index2.table_id(), 2002);
        ASSERT_EQ(tablet_index2.index_id(), 3002);
        ASSERT_EQ(tablet_index2.partition_id(), 4002);
        ASSERT_EQ(tablet_index2.tablet_id(), tablet_id);
    }
}

TEST(MetaReaderTest, BatchGetTabletIndexes) {
    auto txn_kv = std::make_shared<MemTxnKv>();
    ASSERT_EQ(txn_kv->init(), 0);

    std::string instance_id = "test_instance";
    std::vector<int64_t> tablet_ids = {5001, 5002, 5003, 5004};

    {
        // Test empty input
        MetaReader meta_reader(instance_id, txn_kv.get());
        std::vector<int64_t> empty_ids;
        std::unordered_map<int64_t, TabletIndexPB> tablet_indexes;
        TxnErrorCode err = meta_reader.get_tablet_indexes(empty_ids, &tablet_indexes);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_TRUE(tablet_indexes.empty());
    }

    {
        // Put some tablet indexes (skip tablet_ids[1] to test partial results)
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);

        for (size_t i = 0; i < tablet_ids.size(); ++i) {
            if (i == 1) continue; // Skip tablet_ids[1]
            std::string tablet_index_key =
                    versioned::tablet_index_key({instance_id, tablet_ids[i]});
            TabletIndexPB tablet_index;
            tablet_index.set_db_id(1000 + i);
            tablet_index.set_table_id(2000 + i);
            tablet_index.set_index_id(3000 + i);
            tablet_index.set_partition_id(4000 + i);
            tablet_index.set_tablet_id(tablet_ids[i]);
            txn->put(tablet_index_key, tablet_index.SerializeAsString());
        }
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    {
        // Test partial results
        MetaReader meta_reader(instance_id, txn_kv.get());
        std::unordered_map<int64_t, TabletIndexPB> tablet_indexes;
        TxnErrorCode err = meta_reader.get_tablet_indexes(tablet_ids, &tablet_indexes);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_EQ(tablet_indexes.size(), 3); // All except tablet_ids[1]

        for (size_t i = 0; i < tablet_ids.size(); ++i) {
            if (i == 1) {
                ASSERT_EQ(tablet_indexes.find(tablet_ids[i]), tablet_indexes.end());
            } else {
                ASSERT_NE(tablet_indexes.find(tablet_ids[i]), tablet_indexes.end());
                ASSERT_EQ(tablet_indexes[tablet_ids[i]].db_id(), 1000 + i);
                ASSERT_EQ(tablet_indexes[tablet_ids[i]].table_id(), 2000 + i);
                ASSERT_EQ(tablet_indexes[tablet_ids[i]].index_id(), 3000 + i);
                ASSERT_EQ(tablet_indexes[tablet_ids[i]].partition_id(), 4000 + i);
                ASSERT_EQ(tablet_indexes[tablet_ids[i]].tablet_id(), tablet_ids[i]);
            }
        }
    }

    {
        // Put the missing tablet index
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        std::string tablet_index_key = versioned::tablet_index_key({instance_id, tablet_ids[1]});
        TabletIndexPB tablet_index;
        tablet_index.set_db_id(1001);
        tablet_index.set_table_id(2001);
        tablet_index.set_index_id(3001);
        tablet_index.set_partition_id(4001);
        tablet_index.set_tablet_id(tablet_ids[1]);
        txn->put(tablet_index_key, tablet_index.SerializeAsString());
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    {
        // Test all keys found
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        MetaReader meta_reader(instance_id, txn_kv.get());
        std::unordered_map<int64_t, TabletIndexPB> tablet_indexes;
        TxnErrorCode err = meta_reader.get_tablet_indexes(txn.get(), tablet_ids, &tablet_indexes);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_EQ(tablet_indexes.size(), tablet_ids.size());

        for (size_t i = 0; i < tablet_ids.size(); ++i) {
            int64_t tablet_id = tablet_ids[i];
            ASSERT_NE(tablet_indexes.find(tablet_id), tablet_indexes.end());
            int64_t expected_db_id = (i == 1) ? 1001 : 1000 + i;
            int64_t expected_table_id = (i == 1) ? 2001 : 2000 + i;
            int64_t expected_index_id = (i == 1) ? 3001 : 3000 + i;
            int64_t expected_partition_id = (i == 1) ? 4001 : 4000 + i;
            ASSERT_EQ(tablet_indexes[tablet_id].db_id(), expected_db_id);
            ASSERT_EQ(tablet_indexes[tablet_id].table_id(), expected_table_id);
            ASSERT_EQ(tablet_indexes[tablet_id].index_id(), expected_index_id);
            ASSERT_EQ(tablet_indexes[tablet_id].partition_id(), expected_partition_id);
            ASSERT_EQ(tablet_indexes[tablet_id].tablet_id(), tablet_id);
        }
    }
}

TEST(MetaReaderTest, GetRowsetMetas) {
    using doris::RowsetMetaCloudPB;

    auto txn_kv = std::make_shared<MemTxnKv>();
    ASSERT_EQ(txn_kv->init(), 0);

    std::string instance_id = "test_instance";
    int64_t tablet_id = 4001;
    int64_t start_version = 1;
    int64_t end_version = 10;

    {
        // Test empty result when no rowsets exist
        MetaReader meta_reader(instance_id, txn_kv.get());
        std::vector<RowsetMetaCloudPB> rowset_metas;
        TxnErrorCode err =
                meta_reader.get_rowset_metas(tablet_id, start_version, end_version, &rowset_metas);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_TRUE(rowset_metas.empty());
    }

    // Create some load rowsets (import scenario)
    {
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);

        // Create load rowsets with versions 2, 3, 4, 5
        for (int64_t version = 2; version <= 5; ++version) {
            std::string load_key =
                    versioned::meta_rowset_load_key({instance_id, tablet_id, version});
            RowsetMetaCloudPB rowset_meta;
            rowset_meta.set_rowset_id(0);
            rowset_meta.set_rowset_id_v2(fmt::format("load_rowset_{}", version));
            rowset_meta.set_start_version(version);
            rowset_meta.set_end_version(version);
            rowset_meta.set_num_rows(100 * version);
            rowset_meta.set_tablet_id(tablet_id);
            ASSERT_TRUE(versioned::document_put(txn.get(), load_key, std::move(rowset_meta)));
        }
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    {
        // Test getting load rowsets
        MetaReader meta_reader(instance_id, txn_kv.get());
        std::vector<RowsetMetaCloudPB> rowset_metas;
        TxnErrorCode err = meta_reader.get_rowset_metas(tablet_id, 2, 5, &rowset_metas);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK) << dump_range(txn_kv.get());
        ASSERT_EQ(rowset_metas.size(), 4) << [&] {
            std::ostringstream oss;
            for (const auto& meta : rowset_metas) {
                oss << meta.rowset_id_v2() << "[" << meta.start_version() << ", "
                    << meta.end_version() << "]\n";
            }
            return oss.str();
        }() << dump_range(txn_kv.get());

        // Verify rowsets are sorted by end_version
        for (size_t i = 0; i < rowset_metas.size(); ++i) {
            ASSERT_EQ(rowset_metas[i].end_version(), 2 + i);
            ASSERT_EQ(rowset_metas[i].start_version(), 2 + i);
            ASSERT_EQ(rowset_metas[i].num_rows(), 100 * (2 + i));
        }
    }

    // Create compact rowset that covers versions 3-4
    {
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);

        std::string compact_key = versioned::meta_rowset_compact_key({instance_id, tablet_id, 4});
        RowsetMetaCloudPB compact_rowset;
        compact_rowset.set_rowset_id(0);
        compact_rowset.set_rowset_id_v2("compact_rowset_3_4");
        compact_rowset.set_start_version(3);
        compact_rowset.set_end_version(4);
        compact_rowset.set_num_rows(700); // 300 + 400 = 700
        compact_rowset.set_tablet_id(tablet_id);
        ASSERT_TRUE(versioned::document_put(txn.get(), compact_key, std::move(compact_rowset)));

        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    {
        // Test getting rowsets after compaction - compact should override load rowsets
        MetaReader meta_reader(instance_id, txn_kv.get());
        std::vector<RowsetMetaCloudPB> rowset_metas;
        TxnErrorCode err = meta_reader.get_rowset_metas(tablet_id, 2, 5, &rowset_metas);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_EQ(rowset_metas.size(), 3); // version 2, compact(3-4), version 5

        // Check first rowset (version 2)
        ASSERT_EQ(rowset_metas[0].end_version(), 2);
        ASSERT_EQ(rowset_metas[0].start_version(), 2);
        ASSERT_EQ(rowset_metas[0].rowset_id_v2(), "load_rowset_2");

        // Check compact rowset (versions 3-4)
        ASSERT_EQ(rowset_metas[1].end_version(), 4);
        ASSERT_EQ(rowset_metas[1].start_version(), 3);
        ASSERT_EQ(rowset_metas[1].rowset_id_v2(), "compact_rowset_3_4");
        ASSERT_EQ(rowset_metas[1].num_rows(), 700);

        // Check last rowset (version 5)
        ASSERT_EQ(rowset_metas[2].end_version(), 5);
        ASSERT_EQ(rowset_metas[2].start_version(), 5);
        ASSERT_EQ(rowset_metas[2].rowset_id_v2(), "load_rowset_5");
    }

    // Test range query that only includes part of the rowsets
    {
        MetaReader meta_reader(instance_id, txn_kv.get());
        std::vector<RowsetMetaCloudPB> rowset_metas;
        TxnErrorCode err = meta_reader.get_rowset_metas(tablet_id, 3, 4, &rowset_metas);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_EQ(rowset_metas.size(), 1); // Only the compact rowset
        ASSERT_EQ(rowset_metas[0].rowset_id_v2(), "compact_rowset_3_4");
    }

    // Test with snapshot version functionality
    Versionstamp snapshot_version;
    {
        // Get current snapshot version
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        MetaReader meta_reader(instance_id, txn_kv.get());
        std::vector<RowsetMetaCloudPB> rowset_metas;
        TxnErrorCode err = meta_reader.get_rowset_metas(txn.get(), tablet_id, 2, 5, &rowset_metas);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);

        // Get version from the transaction's read version
        int64_t version = 0;
        ASSERT_EQ(txn->get_read_version(&version), TxnErrorCode::TXN_OK);
        snapshot_version = Versionstamp(version, 1);
        LOG(INFO) << "Snapshot version: " << snapshot_version.version();
        LOG(INFO) << "Snapshot version: " << snapshot_version.to_string();
    }

    // Add another compact rowset that covers version 5
    {
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);

        std::string compact_key = versioned::meta_rowset_compact_key({instance_id, tablet_id, 5});
        RowsetMetaCloudPB compact_rowset;
        compact_rowset.set_rowset_id(0);
        compact_rowset.set_rowset_id_v2("compact_rowset_5");
        compact_rowset.set_start_version(5);
        compact_rowset.set_end_version(5);
        compact_rowset.set_num_rows(500);
        compact_rowset.set_tablet_id(tablet_id);
        ASSERT_TRUE(versioned::document_put(txn.get(), compact_key, std::move(compact_rowset)));

        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    {
        // Test reading with snapshot version - should get old data
        LOG(INFO) << "Reading with snapshot version: " << snapshot_version.version();
        MetaReader meta_reader(instance_id, txn_kv.get(), snapshot_version);
        std::vector<RowsetMetaCloudPB> rowset_metas;
        TxnErrorCode err = meta_reader.get_rowset_metas(tablet_id, 2, 5, &rowset_metas);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_EQ(rowset_metas.size(), 3) << [&]() {
            std::ostringstream oss;
            for (const auto& meta : rowset_metas) {
                oss << meta.rowset_id_v2() << "[" << meta.start_version() << ", "
                    << meta.end_version() << "]\n";
            }
            return oss.str();
        }() << dump_range(txn_kv.get()); // Should still see load_rowset_5, not compact_rowset_5
        ASSERT_EQ(rowset_metas[2].rowset_id_v2(), "load_rowset_5") << dump_range(txn_kv.get());
    }

    {
        // Test reading without snapshot - should get new data
        LOG(INFO) << "Reading without snapshot version";
        MetaReader meta_reader(instance_id, txn_kv.get());
        std::vector<RowsetMetaCloudPB> rowset_metas;
        TxnErrorCode err = meta_reader.get_rowset_metas(tablet_id, 2, 5, &rowset_metas);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_EQ(rowset_metas.size(), 3); // version 2, compact(3-4), compact(5)
        ASSERT_EQ(rowset_metas[2].rowset_id_v2(), "compact_rowset_5");
    }

    // Add a compact rowset cover [3-5]
    {
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);

        std::string compact_key = versioned::meta_rowset_compact_key({instance_id, tablet_id, 5});
        RowsetMetaCloudPB compact_rowset;
        compact_rowset.set_rowset_id(0);
        compact_rowset.set_rowset_id_v2("compact_rowset_3_5");
        compact_rowset.set_start_version(3);
        compact_rowset.set_end_version(5);
        compact_rowset.set_num_rows(1200); // 300 + 400 + 500
        compact_rowset.set_tablet_id(tablet_id);
        ASSERT_TRUE(versioned::document_put(txn.get(), compact_key, std::move(compact_rowset)));

        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    {
        // Test getting rowsets after new compaction
        MetaReader meta_reader(instance_id, txn_kv.get());
        std::vector<RowsetMetaCloudPB> rowset_metas;
        TxnErrorCode err = meta_reader.get_rowset_metas(tablet_id, 2, 5, &rowset_metas);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_EQ(rowset_metas.size(), 2); // version 2, compact(3-5)

        // Check first rowset (version 2)
        ASSERT_EQ(rowset_metas[0].end_version(), 2);
        ASSERT_EQ(rowset_metas[0].start_version(), 2);
        ASSERT_EQ(rowset_metas[0].rowset_id_v2(), "load_rowset_2");

        // Check new compact rowset (versions 3-5)
        ASSERT_EQ(rowset_metas[1].end_version(), 5);
        ASSERT_EQ(rowset_metas[1].start_version(), 3);
        ASSERT_EQ(rowset_metas[1].rowset_id_v2(), "compact_rowset_3_5");
    }

    {
        // Test getting rowset with old snapshot version
        LOG(INFO) << "Reading with old snapshot version: " << snapshot_version.version();
        MetaReader meta_reader(instance_id, txn_kv.get(), snapshot_version);
        std::vector<RowsetMetaCloudPB> rowset_metas;
        TxnErrorCode err = meta_reader.get_rowset_metas(tablet_id, 2, 5, &rowset_metas);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_EQ(rowset_metas.size(), 3) << [&]() {
            std::ostringstream oss;
            for (const auto& meta : rowset_metas) {
                oss << meta.rowset_id_v2() << "[" << meta.start_version() << ", "
                    << meta.end_version() << "]\n";
            }
            return oss.str();
        }() << dump_range(txn_kv.get());
        ASSERT_EQ(rowset_metas[2].rowset_id_v2(), "load_rowset_5") << dump_range(txn_kv.get());
        // Should still see load_rowset_5, not compact_rowset_3_5
        ASSERT_EQ(rowset_metas[2].start_version(), 5);
        ASSERT_EQ(rowset_metas[2].end_version(), 5);
        ASSERT_EQ(rowset_metas[2].num_rows(), 500) << dump_range(txn_kv.get());
    }
}

TEST(MetaReaderTest, GetRowsetMetasMinReadVersionstamp) {
    auto txn_kv = std::make_shared<MemTxnKv>();
    ASSERT_EQ(txn_kv->init(), 0);
    const std::string instance_id = "rowset_min_version";
    constexpr int64_t tablet_id = 4001;

    std::unique_ptr<Transaction> txn;
    ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
    auto put_rowset = [&](const std::string& id, int64_t start, int64_t end, Versionstamp version,
                          bool compact) {
        doris::RowsetMetaCloudPB rowset;
        rowset.set_rowset_id(0);
        rowset.set_rowset_id_v2(id);
        rowset.set_tablet_id(tablet_id);
        rowset.set_start_version(start);
        rowset.set_end_version(end);
        auto key = compact ? versioned::meta_rowset_compact_key({instance_id, tablet_id, end})
                           : versioned::meta_rowset_load_key({instance_id, tablet_id, end});
        ASSERT_TRUE(versioned::document_put(txn.get(), key, version, std::move(rowset)));
    };
    put_rowset("L1", 1, 1, Versionstamp(70, 1), false);
    put_rowset("L2", 2, 2, Versionstamp(80, 1), false);
    put_rowset("L3", 3, 3, Versionstamp(90, 1), false);
    put_rowset("A", 2, 3, Versionstamp(150, 2), true);
    put_rowset("L4", 4, 4, Versionstamp(170, 1), false);
    // Compact keys are scanned by descending end version: A also hides this older compact.
    put_rowset("old_compact", 2, 2, Versionstamp(110, 1), true);
    put_rowset("old_A", 2, 3, Versionstamp(120, 1), true);
    TabletStatsPB stats;
    stats.set_num_rowsets(1);
    versioned_put(txn.get(), versioned::tablet_load_stats_key({instance_id, tablet_id}),
                  Versionstamp(70, 2), stats.SerializeAsString());
    versioned_put(txn.get(), versioned::tablet_compact_stats_key({instance_id, tablet_id}),
                  Versionstamp(75, 1), stats.SerializeAsString());
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);

    using Rowset = std::tuple<std::string, int64_t, int64_t>;
    auto check_rowsets = [&](MetaReader& reader, int64_t start, int64_t end,
                             const std::vector<Rowset>& expected, Versionstamp expected_min) {
        SCOPED_TRACE(fmt::format("rowset range [{}, {}]", start, end));
        std::vector<doris::RowsetMetaCloudPB> rowsets;
        ASSERT_EQ(reader.get_rowset_metas(tablet_id, start, end, &rowsets), TxnErrorCode::TXN_OK);
        std::vector<Rowset> actual;
        for (const auto& rowset : rowsets) {
            EXPECT_EQ(rowset.tablet_id(), tablet_id);
            actual.emplace_back(rowset.rowset_id_v2(), rowset.start_version(),
                                rowset.end_version());
        }
        EXPECT_EQ(actual, expected);
        EXPECT_EQ(reader.min_read_versionstamp(), expected_min)
                << "actual metadata version: " << reader.min_read_version()
                << ", expected: " << expected_min.version();
    };
    {
        MetaReader reader(instance_id, txn_kv.get());
        // Covered L2@80/L3@90 must not lower the minimum of A@150/L4@170.
        check_rowsets(reader, 2, 4, {{"A", 2, 3}, {"L4", 4, 4}}, Versionstamp(150, 2));
    }
    {
        MetaReader reader(instance_id, txn_kv.get());
        check_rowsets(reader, 2, 3, {{"A", 2, 3}}, Versionstamp(150, 2));
    }
    {
        MetaReader reader(instance_id, txn_kv.get());
        // A selected old load still contributes its full metadata versionstamp.
        check_rowsets(reader, 1, 4, {{"L1", 1, 1}, {"A", 2, 3}, {"L4", 4, 4}}, Versionstamp(70, 1));
    }
    {
        MetaReader reader(instance_id, txn_kv.get(), Versionstamp(100, 0));
        check_rowsets(reader, 2, 3, {{"L2", 2, 2}, {"L3", 3, 3}}, Versionstamp(80, 1));
    }
    for (bool load_stats : {true, false}) {
        SCOPED_TRACE(load_stats ? "prior load stats" : "prior compact stats");
        MetaReader reader(instance_id, txn_kv.get());
        auto err = load_stats ? reader.get_tablet_load_stats(tablet_id, &stats, nullptr)
                              : reader.get_tablet_compact_stats(tablet_id, &stats, nullptr);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        auto previous_min = load_stats ? Versionstamp(70, 2) : Versionstamp(75, 1);
        EXPECT_EQ(reader.min_read_versionstamp(), previous_min);
        check_rowsets(reader, 2, 4, {{"A", 2, 3}, {"L4", 4, 4}}, previous_min);
        check_rowsets(reader, 5, 6, {}, previous_min);
    }
    {
        MetaReader reader(instance_id, txn_kv.get());
        check_rowsets(reader, 5, 6, {}, Versionstamp::max());
        check_rowsets(reader, 2, 3, {{"A", 2, 3}}, Versionstamp(150, 2));
        check_rowsets(reader, 4, 4, {{"L4", 4, 4}}, Versionstamp(150, 2));
        check_rowsets(reader, 1, 1, {{"L1", 1, 1}}, Versionstamp(70, 1));
        check_rowsets(reader, 2, 4, {{"A", 2, 3}, {"L4", 4, 4}}, Versionstamp(70, 1));
        check_rowsets(reader, 5, 6, {}, Versionstamp(70, 1));
    }
    {
        // Equal transaction versions must still compare the two-byte order component.
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        put_rowset("L5", 5, 5, Versionstamp(150, 1), false);
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
        MetaReader reader(instance_id, txn_kv.get());
        check_rowsets(reader, 2, 5, {{"A", 2, 3}, {"L4", 4, 4}, {"L5", 5, 5}},
                      Versionstamp(150, 1));
    }
}

TEST(MetaReaderTest, GetRowsetMetasScanFailure) {
    auto txn_kv = std::make_shared<MemTxnKv>();
    ASSERT_EQ(txn_kv->init(), 0);
    const std::string instance_id = "rowset_scan_failure";
    constexpr int64_t tablet_id = 4001;
    std::unique_ptr<Transaction> txn;
    ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
    doris::RowsetMetaCloudPB load;
    load.set_rowset_id(0);
    load.set_start_version(2);
    load.set_end_version(2);
    ASSERT_TRUE(versioned::document_put(
            txn.get(), versioned::meta_rowset_load_key({instance_id, tablet_id, 2}),
            Versionstamp(80, 1), std::move(load)));
    // A malformed compact document fails after the load scan has succeeded.
    versioned_put(txn.get(), versioned::meta_rowset_compact_key({instance_id, tablet_id, 3}),
                  Versionstamp(150, 1), "invalid protobuf");
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    MetaReader reader(instance_id, txn_kv.get());
    std::vector<doris::RowsetMetaCloudPB> rowsets(1);
    rowsets[0].set_rowset_id_v2("unchanged");
    ASSERT_EQ(reader.get_rowset_metas(tablet_id, 2, 3, &rowsets), TxnErrorCode::TXN_INVALID_DATA);
    ASSERT_EQ(rowsets.size(), 1);
    EXPECT_EQ(rowsets[0].rowset_id_v2(), "unchanged");
    EXPECT_EQ(reader.min_read_versionstamp(), Versionstamp::max());
}

TEST(MetaReaderTest, GetPartitionPendingTxnId) {
    auto txn_kv = std::make_shared<MemTxnKv>();
    ASSERT_EQ(txn_kv->init(), 0);

    std::string instance_id = "test_instance";
    int64_t partition_id = 3001;

    {
        // Test with non-existent partition
        MetaReader meta_reader(instance_id, txn_kv.get());
        int64_t first_txn_id;
        TxnErrorCode err = meta_reader.get_partition_pending_txn_id(partition_id, &first_txn_id);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        EXPECT_EQ(first_txn_id, -1) << "Expected -1 for non-existent partition";
    }

    {
        // Put a partition version without pending transactions
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        std::string partition_version_key =
                versioned::partition_version_key({instance_id, partition_id});
        VersionPB version_pb;
        version_pb.set_version(100);
        versioned_put(txn.get(), partition_version_key, version_pb.SerializeAsString());
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    {
        // Test with no pending transactions - should return -1
        MetaReader meta_reader(instance_id, txn_kv.get());
        int64_t first_txn_id;
        TxnErrorCode err = meta_reader.get_partition_pending_txn_id(partition_id, &first_txn_id);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_EQ(first_txn_id, -1);
    }

    {
        // Put a partition version with pending transactions
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        std::string partition_version_key =
                versioned::partition_version_key({instance_id, partition_id});
        VersionPB version_pb;
        version_pb.set_version(200);
        version_pb.add_pending_txn_ids(1001);
        version_pb.add_pending_txn_ids(1002);
        version_pb.add_pending_txn_ids(1003);
        versioned_put(txn.get(), partition_version_key, version_pb.SerializeAsString());
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    {
        // Test with pending transactions - should return first txn_id
        MetaReader meta_reader(instance_id, txn_kv.get());
        int64_t first_txn_id;
        TxnErrorCode err = meta_reader.get_partition_pending_txn_id(partition_id, &first_txn_id);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_EQ(first_txn_id, 1001);
    }

    {
        // Test with transaction parameter
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        MetaReader meta_reader(instance_id, txn_kv.get());
        int64_t first_txn_id;
        TxnErrorCode err =
                meta_reader.get_partition_pending_txn_id(txn.get(), partition_id, &first_txn_id);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_EQ(first_txn_id, 1001);
    }

    {
        // Put a partition version with single pending transaction
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        std::string partition_version_key =
                versioned::partition_version_key({instance_id, partition_id});
        VersionPB version_pb;
        version_pb.set_version(300);
        version_pb.add_pending_txn_ids(2001);
        versioned_put(txn.get(), partition_version_key, version_pb.SerializeAsString());
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    {
        // Test with single pending transaction
        MetaReader meta_reader(instance_id, txn_kv.get());
        int64_t first_txn_id;
        TxnErrorCode err = meta_reader.get_partition_pending_txn_id(partition_id, &first_txn_id);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_EQ(first_txn_id, 2001);
    }

    {
        // Test with snapshot functionality
        // First get the current snapshot version
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        VersionPB current_version;
        Versionstamp current_versionstamp;
        MetaReader current_reader(instance_id, txn_kv.get());
        TxnErrorCode err = current_reader.get_partition_version(
                txn.get(), partition_id, &current_version, &current_versionstamp);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);

        // Create a MetaReader with snapshot
        Versionstamp snapshot_version(current_version.version() + 1, 0);
        MetaReader snapshot_reader(instance_id, txn_kv.get(), snapshot_version);
        int64_t first_txn_id;
        err = snapshot_reader.get_partition_pending_txn_id(partition_id, &first_txn_id, true);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_EQ(first_txn_id, 2001);
    }
}

TEST(MetaReaderTest, GetIndexIndex) {
    auto txn_kv = std::make_shared<MemTxnKv>();
    ASSERT_EQ(txn_kv->init(), 0);

    std::string instance_id = "test_instance";
    int64_t index_id = 3001;

    {
        // NOT FOUND
        MetaReader meta_reader(instance_id, txn_kv.get());
        IndexIndexPB index;
        TxnErrorCode err = meta_reader.get_index_index(index_id, &index);
        ASSERT_EQ(err, TxnErrorCode::TXN_KEY_NOT_FOUND);
    }

    {
        // Put an index index
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        std::string index_index_key = versioned::index_index_key({instance_id, index_id});
        IndexIndexPB index_index;
        index_index.set_db_id(1001);
        index_index.set_table_id(2001);
        txn->put(index_index_key, index_index.SerializeAsString());
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    {
        MetaReader meta_reader(instance_id, txn_kv.get());
        IndexIndexPB index;
        TxnErrorCode err = meta_reader.get_index_index(index_id, &index);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_EQ(index.db_id(), 1001);
        ASSERT_EQ(index.table_id(), 2001);
    }
}

TEST(MetaReaderTest, GetPartitionIndex) {
    auto txn_kv = std::make_shared<MemTxnKv>();
    ASSERT_EQ(txn_kv->init(), 0);

    std::string instance_id = "test_instance";
    int64_t partition_id = 4001;

    {
        // NOT FOUND
        MetaReader meta_reader(instance_id, txn_kv.get());
        PartitionIndexPB partition_index;
        TxnErrorCode err = meta_reader.get_partition_index(partition_id, &partition_index);
        ASSERT_EQ(err, TxnErrorCode::TXN_KEY_NOT_FOUND);
    }

    {
        // Put a partition index
        PartitionIndexPB partition_index_pb;
        partition_index_pb.set_db_id(100);
        partition_index_pb.set_table_id(200);

        std::string partition_index_value;
        ASSERT_TRUE(partition_index_pb.SerializeToString(&partition_index_value));

        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        std::string partition_index_key =
                versioned::partition_index_key({instance_id, partition_id});
        txn->put(partition_index_key, partition_index_value);
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    {
        MetaReader meta_reader(instance_id, txn_kv.get());
        PartitionIndexPB partition_index;
        TxnErrorCode err = meta_reader.get_partition_index(partition_id, &partition_index);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_EQ(partition_index.db_id(), 100);
        ASSERT_EQ(partition_index.table_id(), 200);
    }
}

TEST(MetaReaderTest, GetLoadRowsetMeta) {
    using doris::RowsetMetaCloudPB;

    auto txn_kv = std::make_shared<MemTxnKv>();
    ASSERT_EQ(txn_kv->init(), 0);

    std::string instance_id = "test_instance";
    int64_t tablet_id = 5001;
    int64_t version = 10;

    {
        // Test key not found when no rowset exists
        MetaReader meta_reader(instance_id, txn_kv.get());
        RowsetMetaCloudPB rowset_meta;
        TxnErrorCode err = meta_reader.get_load_rowset_meta(tablet_id, version, &rowset_meta);
        ASSERT_EQ(err, TxnErrorCode::TXN_KEY_NOT_FOUND);
    }

    // Create a load rowset
    RowsetMetaCloudPB expected_rowset_meta;
    {
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);

        std::string load_key = versioned::meta_rowset_load_key({instance_id, tablet_id, version});
        expected_rowset_meta.set_rowset_id(0);
        expected_rowset_meta.set_rowset_id_v2(fmt::format("test_load_rowset_{}", version));
        expected_rowset_meta.set_start_version(version);
        expected_rowset_meta.set_end_version(version);
        expected_rowset_meta.set_num_rows(1000);
        expected_rowset_meta.set_tablet_id(tablet_id);

        ASSERT_TRUE(versioned::document_put(txn.get(), load_key, std::move(expected_rowset_meta)));
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    {
        // Test successful get with created transaction
        MetaReader meta_reader(instance_id, txn_kv.get());
        RowsetMetaCloudPB rowset_meta;
        TxnErrorCode err = meta_reader.get_load_rowset_meta(tablet_id, version, &rowset_meta);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);

        // Verify fields match
        ASSERT_EQ(rowset_meta.rowset_id_v2(), expected_rowset_meta.rowset_id_v2());
        ASSERT_EQ(rowset_meta.start_version(), expected_rowset_meta.start_version());
        ASSERT_EQ(rowset_meta.end_version(), expected_rowset_meta.end_version());
        ASSERT_EQ(rowset_meta.num_rows(), expected_rowset_meta.num_rows());
        ASSERT_EQ(rowset_meta.tablet_id(), expected_rowset_meta.tablet_id());
    }

    {
        // Test successful get with provided transaction
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);

        MetaReader meta_reader(instance_id, txn_kv.get());
        RowsetMetaCloudPB rowset_meta;
        TxnErrorCode err =
                meta_reader.get_load_rowset_meta(txn.get(), tablet_id, version, &rowset_meta);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);

        // Verify key fields match
        ASSERT_EQ(rowset_meta.rowset_id_v2(), expected_rowset_meta.rowset_id_v2());
        ASSERT_EQ(rowset_meta.start_version(), expected_rowset_meta.start_version());
        ASSERT_EQ(rowset_meta.end_version(), expected_rowset_meta.end_version());
        ASSERT_EQ(rowset_meta.tablet_id(), expected_rowset_meta.tablet_id());
    }

    // Test with snapshot version functionality
    Versionstamp snapshot_version;
    {
        // Get current snapshot version
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);

        int64_t version_value = 0;
        ASSERT_EQ(txn->get_read_version(&version_value), TxnErrorCode::TXN_OK);
        snapshot_version = Versionstamp(version_value, 1);
    }

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

        std::string load_key = versioned::meta_rowset_load_key({instance_id, tablet_id, version});
        RowsetMetaCloudPB updated_rowset_meta = expected_rowset_meta;
        updated_rowset_meta.set_num_rows(2000); // Update row count

        ASSERT_TRUE(versioned::document_put(txn.get(), load_key, std::move(updated_rowset_meta)));
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    {
        // Test reading with snapshot version - should get old data
        MetaReader meta_reader(instance_id, txn_kv.get(), snapshot_version);
        RowsetMetaCloudPB rowset_meta;
        TxnErrorCode err = meta_reader.get_load_rowset_meta(tablet_id, version, &rowset_meta);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);

        // Should get original values
        ASSERT_EQ(rowset_meta.num_rows(), 1000);
    }

    {
        // Test reading without snapshot - should get new data
        MetaReader meta_reader(instance_id, txn_kv.get());
        RowsetMetaCloudPB rowset_meta;
        TxnErrorCode err = meta_reader.get_load_rowset_meta(tablet_id, version, &rowset_meta);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);

        // Should get updated values
        ASSERT_EQ(rowset_meta.num_rows(), 2000);
    }

    {
        // Test with snapshot flag
        MetaReader meta_reader(instance_id, txn_kv.get());
        RowsetMetaCloudPB rowset_meta;
        TxnErrorCode err = meta_reader.get_load_rowset_meta(tablet_id, version, &rowset_meta, true);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);

        // Should get current values since snapshot flag is set but no snapshot version
        ASSERT_EQ(rowset_meta.num_rows(), 2000);
    }

    {
        // Test getting non-existent version
        MetaReader meta_reader(instance_id, txn_kv.get());
        RowsetMetaCloudPB rowset_meta;
        TxnErrorCode err = meta_reader.get_load_rowset_meta(tablet_id, version + 1, &rowset_meta);
        ASSERT_EQ(err, TxnErrorCode::TXN_KEY_NOT_FOUND);
    }
}

TEST(MetaReaderTest, GetCompactRowsetMeta) {
    using doris::RowsetMetaCloudPB;

    auto txn_kv = std::make_shared<MemTxnKv>();
    ASSERT_EQ(txn_kv->init(), 0);

    std::string instance_id = "test_instance";
    int64_t tablet_id = 5001;
    int64_t version = 10;

    {
        // Test key not found when no rowset exists
        MetaReader meta_reader(instance_id, txn_kv.get());
        RowsetMetaCloudPB rowset_meta;
        TxnErrorCode err = meta_reader.get_compact_rowset_meta(tablet_id, version, &rowset_meta);
        ASSERT_EQ(err, TxnErrorCode::TXN_KEY_NOT_FOUND);
    }

    // Create a load rowset
    RowsetMetaCloudPB expected_rowset_meta;
    {
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);

        std::string load_key =
                versioned::meta_rowset_compact_key({instance_id, tablet_id, version});
        expected_rowset_meta.set_rowset_id(0);
        expected_rowset_meta.set_rowset_id_v2(fmt::format("test_compact_rowset_{}", version));
        expected_rowset_meta.set_start_version(version);
        expected_rowset_meta.set_end_version(version);
        expected_rowset_meta.set_num_rows(1000);
        expected_rowset_meta.set_tablet_id(tablet_id);

        ASSERT_TRUE(versioned::document_put(txn.get(), load_key, std::move(expected_rowset_meta)));
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    {
        // Test successful get with created transaction
        MetaReader meta_reader(instance_id, txn_kv.get());
        RowsetMetaCloudPB rowset_meta;
        TxnErrorCode err = meta_reader.get_compact_rowset_meta(tablet_id, version, &rowset_meta);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);

        // Verify fields match
        ASSERT_EQ(rowset_meta.rowset_id_v2(), expected_rowset_meta.rowset_id_v2());
        ASSERT_EQ(rowset_meta.start_version(), expected_rowset_meta.start_version());
        ASSERT_EQ(rowset_meta.end_version(), expected_rowset_meta.end_version());
        ASSERT_EQ(rowset_meta.num_rows(), expected_rowset_meta.num_rows());
        ASSERT_EQ(rowset_meta.tablet_id(), expected_rowset_meta.tablet_id());
    }

    {
        // Test successful get with provided transaction
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);

        MetaReader meta_reader(instance_id, txn_kv.get());
        RowsetMetaCloudPB rowset_meta;
        TxnErrorCode err =
                meta_reader.get_compact_rowset_meta(txn.get(), tablet_id, version, &rowset_meta);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);

        // Verify key fields match
        ASSERT_EQ(rowset_meta.rowset_id_v2(), expected_rowset_meta.rowset_id_v2());
        ASSERT_EQ(rowset_meta.start_version(), expected_rowset_meta.start_version());
        ASSERT_EQ(rowset_meta.end_version(), expected_rowset_meta.end_version());
        ASSERT_EQ(rowset_meta.tablet_id(), expected_rowset_meta.tablet_id());
    }

    // Test with snapshot version functionality
    Versionstamp snapshot_version;
    {
        // Get current snapshot version
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);

        int64_t version_value = 0;
        ASSERT_EQ(txn->get_read_version(&version_value), TxnErrorCode::TXN_OK);
        snapshot_version = Versionstamp(version_value, 1);
    }

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

        std::string load_key =
                versioned::meta_rowset_compact_key({instance_id, tablet_id, version});
        RowsetMetaCloudPB updated_rowset_meta = expected_rowset_meta;
        updated_rowset_meta.set_num_rows(2000); // Update row count

        ASSERT_TRUE(versioned::document_put(txn.get(), load_key, std::move(updated_rowset_meta)));
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    {
        // Test reading with snapshot version - should get old data
        MetaReader meta_reader(instance_id, txn_kv.get(), snapshot_version);
        RowsetMetaCloudPB rowset_meta;
        TxnErrorCode err = meta_reader.get_compact_rowset_meta(tablet_id, version, &rowset_meta);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);

        // Should get original values
        ASSERT_EQ(rowset_meta.num_rows(), 1000);
    }

    {
        // Test reading without snapshot - should get new data
        MetaReader meta_reader(instance_id, txn_kv.get());
        RowsetMetaCloudPB rowset_meta;
        TxnErrorCode err = meta_reader.get_compact_rowset_meta(tablet_id, version, &rowset_meta);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);

        // Should get updated values
        ASSERT_EQ(rowset_meta.num_rows(), 2000);
    }

    {
        // Test with snapshot flag
        MetaReader meta_reader(instance_id, txn_kv.get());
        RowsetMetaCloudPB rowset_meta;
        TxnErrorCode err =
                meta_reader.get_compact_rowset_meta(tablet_id, version, &rowset_meta, true);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);

        // Should get current values since snapshot flag is set but no snapshot version
        ASSERT_EQ(rowset_meta.num_rows(), 2000);
    }

    {
        // Test getting non-existent version
        MetaReader meta_reader(instance_id, txn_kv.get());
        RowsetMetaCloudPB rowset_meta;
        TxnErrorCode err =
                meta_reader.get_compact_rowset_meta(tablet_id, version + 1, &rowset_meta);
        ASSERT_EQ(err, TxnErrorCode::TXN_KEY_NOT_FOUND);
    }
}

TEST(MetaReaderTest, BatchGetTabletCompactStats) {
    auto txn_kv = std::make_shared<MemTxnKv>();
    ASSERT_EQ(txn_kv->init(), 0);

    std::string instance_id = "test_instance";
    std::vector<int64_t> tablet_ids = {4001, 4002, 4003, 4004};

    {
        // Test empty input
        MetaReader meta_reader(instance_id, txn_kv.get());
        std::vector<int64_t> empty_ids;
        std::unordered_map<int64_t, TabletStatsPB> tablet_stats;
        std::unordered_map<int64_t, Versionstamp> versionstamps;
        TxnErrorCode err =
                meta_reader.get_tablet_compact_stats(empty_ids, &tablet_stats, &versionstamps);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_TRUE(tablet_stats.empty());
        ASSERT_TRUE(versionstamps.empty());
    }

    {
        // Test all keys not found
        MetaReader meta_reader(instance_id, txn_kv.get());
        std::unordered_map<int64_t, TabletStatsPB> tablet_stats;
        std::unordered_map<int64_t, Versionstamp> versionstamps;
        TxnErrorCode err =
                meta_reader.get_tablet_compact_stats(tablet_ids, &tablet_stats, &versionstamps);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_TRUE(tablet_stats.empty());
        ASSERT_TRUE(versionstamps.empty());
    }

    {
        // Put some tablet compact stats (skip tablet_ids[1] to test partial results)
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);

        for (size_t i = 0; i < tablet_ids.size(); ++i) {
            if (i == 1) continue; // Skip tablet_ids[1]

            std::string tablet_compact_stats_key =
                    versioned::tablet_compact_stats_key({instance_id, tablet_ids[i]});
            TabletStatsPB tablet_stats;
            tablet_stats.set_num_rows(1000 * (i + 1));
            tablet_stats.set_data_size(500000 * (i + 1));
            tablet_stats.set_base_compaction_cnt(5 * (i + 1));
            tablet_stats.set_cumulative_compaction_cnt(10 * (i + 1));
            tablet_stats.set_cumulative_point(100 * (i + 1));
            tablet_stats.set_last_base_compaction_time_ms(1234567890 + i * 1000);
            tablet_stats.set_last_cumu_compaction_time_ms(2345678901 + i * 1000);
            tablet_stats.set_full_compaction_cnt(2 * (i + 1));
            tablet_stats.set_last_full_compaction_time_ms(3456789012 + i * 1000);
            tablet_stats.set_num_rowsets(20 * (i + 1));
            tablet_stats.set_num_segments(50 * (i + 1));
            tablet_stats.set_index_size(50000 * (i + 1));
            tablet_stats.set_segment_size(600000 * (i + 1));

            versioned_put(txn.get(), tablet_compact_stats_key, tablet_stats.SerializeAsString());
        }
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    {
        // Test partial results
        MetaReader meta_reader(instance_id, txn_kv.get());
        std::unordered_map<int64_t, TabletStatsPB> tablet_stats;
        std::unordered_map<int64_t, Versionstamp> versionstamps;
        TxnErrorCode err =
                meta_reader.get_tablet_compact_stats(tablet_ids, &tablet_stats, &versionstamps);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_EQ(tablet_stats.size(), 3);  // All except tablet_ids[1]
        ASSERT_EQ(versionstamps.size(), 3); // All except tablet_ids[1]

        for (size_t i = 0; i < tablet_ids.size(); ++i) {
            int64_t tablet_id = tablet_ids[i];
            if (i == 1) {
                ASSERT_EQ(tablet_stats.find(tablet_id), tablet_stats.end());
                ASSERT_EQ(versionstamps.find(tablet_id), versionstamps.end());
            } else {
                ASSERT_NE(tablet_stats.find(tablet_id), tablet_stats.end());
                ASSERT_NE(versionstamps.find(tablet_id), versionstamps.end());

                // Verify stats data
                const TabletStatsPB& stats = tablet_stats[tablet_id];
                ASSERT_EQ(stats.num_rows(), 1000 * (i + 1));
                ASSERT_EQ(stats.data_size(), 500000 * (i + 1));
                ASSERT_EQ(stats.base_compaction_cnt(), 5 * (i + 1));
                ASSERT_EQ(stats.cumulative_compaction_cnt(), 10 * (i + 1));
                ASSERT_EQ(stats.cumulative_point(), 100 * (i + 1));
                ASSERT_EQ(stats.last_base_compaction_time_ms(), 1234567890 + i * 1000);
                ASSERT_EQ(stats.last_cumu_compaction_time_ms(), 2345678901 + i * 1000);
                ASSERT_EQ(stats.full_compaction_cnt(), 2 * (i + 1));
                ASSERT_EQ(stats.last_full_compaction_time_ms(), 3456789012 + i * 1000);
                ASSERT_EQ(stats.num_rowsets(), 20 * (i + 1));
                ASSERT_EQ(stats.num_segments(), 50 * (i + 1));
                ASSERT_EQ(stats.index_size(), 50000 * (i + 1));
                ASSERT_EQ(stats.segment_size(), 600000 * (i + 1));
            }
        }
    }

    {
        // Put the missing tablet compact stats
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);

        std::string tablet_compact_stats_key =
                versioned::tablet_compact_stats_key({instance_id, tablet_ids[1]});
        TabletStatsPB tablet_stats;
        tablet_stats.set_num_rows(2000);
        tablet_stats.set_data_size(1000000);
        tablet_stats.set_base_compaction_cnt(10);
        tablet_stats.set_cumulative_compaction_cnt(20);
        tablet_stats.set_cumulative_point(200);
        tablet_stats.set_last_base_compaction_time_ms(1234567890 + 1000);
        tablet_stats.set_last_cumu_compaction_time_ms(2345678901 + 1000);
        tablet_stats.set_full_compaction_cnt(4);
        tablet_stats.set_last_full_compaction_time_ms(3456789012 + 1000);
        tablet_stats.set_num_rowsets(40);
        tablet_stats.set_num_segments(100);
        tablet_stats.set_index_size(100000);
        tablet_stats.set_segment_size(1200000);

        versioned_put(txn.get(), tablet_compact_stats_key, tablet_stats.SerializeAsString());
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    {
        // Test all keys found
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        MetaReader meta_reader(instance_id, txn_kv.get());
        std::unordered_map<int64_t, TabletStatsPB> tablet_stats;
        std::unordered_map<int64_t, Versionstamp> versionstamps;
        TxnErrorCode err = meta_reader.get_tablet_compact_stats(txn.get(), tablet_ids,
                                                                &tablet_stats, &versionstamps);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_EQ(tablet_stats.size(), tablet_ids.size());
        ASSERT_EQ(versionstamps.size(), tablet_ids.size());

        for (size_t i = 0; i < tablet_ids.size(); ++i) {
            int64_t tablet_id = tablet_ids[i];
            ASSERT_NE(tablet_stats.find(tablet_id), tablet_stats.end());
            ASSERT_NE(versionstamps.find(tablet_id), versionstamps.end());

            // Verify stats data for all tablets
            const TabletStatsPB& stats = tablet_stats[tablet_id];
            if (i == 1) {
                // Special case for the tablet we added later
                ASSERT_EQ(stats.num_rows(), 2000);
                ASSERT_EQ(stats.data_size(), 1000000);
                ASSERT_EQ(stats.base_compaction_cnt(), 10);
                ASSERT_EQ(stats.cumulative_compaction_cnt(), 20);
            } else {
                ASSERT_EQ(stats.num_rows(), 1000 * (i + 1));
                ASSERT_EQ(stats.data_size(), 500000 * (i + 1));
                ASSERT_EQ(stats.base_compaction_cnt(), 5 * (i + 1));
                ASSERT_EQ(stats.cumulative_compaction_cnt(), 10 * (i + 1));
            }
        }
    }

    {
        // Test with snapshot version functionality
        Versionstamp snapshot_version;
        {
            // Get current snapshot version
            std::unique_ptr<Transaction> txn;
            ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
            int64_t version = 0;
            ASSERT_EQ(txn->get_read_version(&version), TxnErrorCode::TXN_OK);
            snapshot_version = Versionstamp(version, 1);
        }

        // Update one of the tablet compact stats
        {
            std::unique_ptr<Transaction> txn;
            ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);

            std::string tablet_compact_stats_key =
                    versioned::tablet_compact_stats_key({instance_id, tablet_ids[0]});
            TabletStatsPB tablet_stats;
            tablet_stats.set_num_rows(9999);    // Updated value
            tablet_stats.set_data_size(999999); // Updated value
            tablet_stats.set_base_compaction_cnt(99);
            tablet_stats.set_cumulative_compaction_cnt(199);

            versioned_put(txn.get(), tablet_compact_stats_key, tablet_stats.SerializeAsString());
            ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
        }

        // Test reading with snapshot version - should get old data
        {
            MetaReader meta_reader(instance_id, txn_kv.get(), snapshot_version);
            std::unordered_map<int64_t, TabletStatsPB> tablet_stats;
            std::unordered_map<int64_t, Versionstamp> versionstamps;
            TxnErrorCode err = meta_reader.get_tablet_compact_stats(tablet_ids, &tablet_stats,
                                                                    &versionstamps, true);
            ASSERT_EQ(err, TxnErrorCode::TXN_OK);
            ASSERT_EQ(tablet_stats.size(), tablet_ids.size());

            // Should still see old data for tablet_ids[0]
            const TabletStatsPB& stats = tablet_stats[tablet_ids[0]];
            ASSERT_EQ(stats.num_rows(), 1000);    // Old value, not 9999
            ASSERT_EQ(stats.data_size(), 500000); // Old value, not 999999
        }

        // Test reading without snapshot - should get new data
        {
            MetaReader meta_reader(instance_id, txn_kv.get());
            std::unordered_map<int64_t, TabletStatsPB> tablet_stats;
            std::unordered_map<int64_t, Versionstamp> versionstamps;
            TxnErrorCode err =
                    meta_reader.get_tablet_compact_stats(tablet_ids, &tablet_stats, &versionstamps);
            ASSERT_EQ(err, TxnErrorCode::TXN_OK);
            ASSERT_EQ(tablet_stats.size(), tablet_ids.size());

            // Should see new data for tablet_ids[0]
            const TabletStatsPB& stats = tablet_stats[tablet_ids[0]];
            ASSERT_EQ(stats.num_rows(), 9999);    // Updated value
            ASSERT_EQ(stats.data_size(), 999999); // Updated value
        }
    }

    {
        // Test with nullptr parameters
        MetaReader meta_reader(instance_id, txn_kv.get());
        TxnErrorCode err = meta_reader.get_tablet_compact_stats(tablet_ids, nullptr, nullptr);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
    }

    {
        // Test with only tablet_stats parameter
        MetaReader meta_reader(instance_id, txn_kv.get());
        std::unordered_map<int64_t, TabletStatsPB> tablet_stats;
        TxnErrorCode err = meta_reader.get_tablet_compact_stats(tablet_ids, &tablet_stats, nullptr);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_EQ(tablet_stats.size(), tablet_ids.size());
    }

    {
        // Test with only versionstamps parameter
        MetaReader meta_reader(instance_id, txn_kv.get());
        std::unordered_map<int64_t, Versionstamp> versionstamps;
        TxnErrorCode err =
                meta_reader.get_tablet_compact_stats(tablet_ids, nullptr, &versionstamps);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_EQ(versionstamps.size(), tablet_ids.size());
    }
}

TEST(MetaReaderTest, GetSnapshots) {
    auto txn_kv = std::make_shared<MemTxnKv>();
    ASSERT_EQ(txn_kv->init(), 0);

    std::string instance_id = "test_instance";

    {
        // Test empty result when no snapshots exist
        MetaReader meta_reader(instance_id, txn_kv.get());
        std::vector<std::pair<SnapshotPB, Versionstamp>> snapshots;
        TxnErrorCode err = meta_reader.get_snapshots(&snapshots);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_TRUE(snapshots.empty());
    }

    // Create some snapshots
    std::vector<Versionstamp> expected_versionstamps;
    {
        // Create multiple snapshots with different timestamps
        for (int i = 1; i <= 3; ++i) {
            std::unique_ptr<Transaction> txn;
            ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);

            std::string snapshot_key = versioned::snapshot_full_key({instance_id});
            SnapshotPB snapshot_pb;
            snapshot_pb.set_label(fmt::format("snapshot_{}", i));
            snapshot_pb.set_instance_id(instance_id);

            std::string snapshot_value = snapshot_pb.SerializeAsString();
            versioned_put(txn.get(), snapshot_key, snapshot_value);
            ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
        }
    }

    {
        // Test getting snapshots with created transaction
        MetaReader meta_reader(instance_id, txn_kv.get());
        std::vector<std::pair<SnapshotPB, Versionstamp>> snapshots;
        TxnErrorCode err = meta_reader.get_snapshots(&snapshots);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_EQ(snapshots.size(), 3);

        // Verify snapshots are returned (order may vary due to versionstamp ordering)
        std::set<std::string> snapshot_ids;
        for (const auto& [snapshot_pb, versionstamp] : snapshots) {
            snapshot_ids.insert(snapshot_pb.label());
            ASSERT_EQ(snapshot_pb.instance_id(), instance_id);
        }
        ASSERT_EQ(snapshot_ids.size(), 3);
        ASSERT_TRUE(snapshot_ids.count("snapshot_1"));
        ASSERT_TRUE(snapshot_ids.count("snapshot_2"));
        ASSERT_TRUE(snapshot_ids.count("snapshot_3"));
    }
}

TEST(MetaReaderTest, GetLoadRowsetMetas) {
    using doris::RowsetMetaCloudPB;

    auto txn_kv = std::make_shared<MemTxnKv>();
    ASSERT_EQ(txn_kv->init(), 0);

    std::string instance_id = "test_instance";
    int64_t tablet_id = 5001;

    {
        // Test with no rowset metas
        MetaReader meta_reader(instance_id, txn_kv.get());
        std::vector<std::pair<RowsetMetaCloudPB, Versionstamp>> rowset_metas;
        TxnErrorCode err = meta_reader.get_load_rowset_metas(tablet_id, &rowset_metas);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_TRUE(rowset_metas.empty());
    }

    {
        // Put some load rowset metas
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);

        for (int64_t version = 1; version <= 3; ++version) {
            std::string load_rowset_key =
                    versioned::meta_rowset_load_key({instance_id, tablet_id, version});
            RowsetMetaCloudPB rowset_meta;
            rowset_meta.set_rowset_id(1);
            rowset_meta.set_rowset_id_v2("load_rowset_" + std::to_string(version));
            rowset_meta.set_start_version(version);
            rowset_meta.set_end_version(version);
            rowset_meta.set_num_rows(100 * version);
            rowset_meta.set_data_disk_size(1000 * version);

            ASSERT_TRUE(
                    versioned::document_put(txn.get(), load_rowset_key, std::move(rowset_meta)));
        }
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    {
        // Test getting load rowset metas
        MetaReader meta_reader(instance_id, txn_kv.get());
        std::vector<std::pair<RowsetMetaCloudPB, Versionstamp>> rowset_metas;
        TxnErrorCode err = meta_reader.get_load_rowset_metas(tablet_id, &rowset_metas);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_EQ(rowset_metas.size(), 3);

        // Verify the rowset metas are correct
        for (size_t i = 0; i < rowset_metas.size(); ++i) {
            const auto& [rowset_meta, versionstamp] = rowset_metas[i];
            int64_t expected_version = rowset_meta.start_version();
            ASSERT_EQ(rowset_meta.rowset_id_v2(),
                      "load_rowset_" + std::to_string(expected_version));
            ASSERT_EQ(rowset_meta.start_version(), expected_version);
            ASSERT_EQ(rowset_meta.end_version(), expected_version);
            ASSERT_EQ(rowset_meta.num_rows(), 100 * expected_version);
            ASSERT_EQ(rowset_meta.data_disk_size(), 1000 * expected_version);
        }

        // Check min_read_versionstamp is updated
        ASSERT_NE(meta_reader.min_read_versionstamp(), Versionstamp::max());
    }

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

        MetaReader meta_reader(instance_id, txn_kv.get());
        std::vector<std::pair<RowsetMetaCloudPB, Versionstamp>> rowset_metas;
        TxnErrorCode err = meta_reader.get_load_rowset_metas(txn.get(), tablet_id, &rowset_metas);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_EQ(rowset_metas.size(), 3);
    }
}

TEST(MetaReaderTest, GetCompactRowsetMetas) {
    using doris::RowsetMetaCloudPB;

    auto txn_kv = std::make_shared<MemTxnKv>();
    ASSERT_EQ(txn_kv->init(), 0);

    std::string instance_id = "test_instance";
    int64_t tablet_id = 5002;

    {
        // Test with no rowset metas
        MetaReader meta_reader(instance_id, txn_kv.get());
        std::vector<std::pair<RowsetMetaCloudPB, Versionstamp>> rowset_metas;
        TxnErrorCode err = meta_reader.get_compact_rowset_metas(tablet_id, &rowset_metas);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_TRUE(rowset_metas.empty());
    }

    {
        // Put some compact rowset metas
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);

        // Create compact rowsets with different version ranges
        std::vector<std::pair<int64_t, int64_t>> version_ranges = {{1, 3}, {4, 6}, {7, 9}};

        for (size_t i = 0; i < version_ranges.size(); ++i) {
            auto [start_version, end_version] = version_ranges[i];
            std::string compact_rowset_key =
                    versioned::meta_rowset_compact_key({instance_id, tablet_id, end_version});
            RowsetMetaCloudPB rowset_meta;
            rowset_meta.set_rowset_id(0);
            rowset_meta.set_rowset_id_v2("compact_rowset_" + std::to_string(i + 1));
            rowset_meta.set_start_version(start_version);
            rowset_meta.set_end_version(end_version);
            rowset_meta.set_num_rows(300 * (i + 1));
            rowset_meta.set_data_disk_size(3000 * (i + 1));

            ASSERT_TRUE(
                    versioned::document_put(txn.get(), compact_rowset_key, std::move(rowset_meta)));
        }
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    {
        // Test getting compact rowset metas
        MetaReader meta_reader(instance_id, txn_kv.get());
        std::vector<std::pair<RowsetMetaCloudPB, Versionstamp>> rowset_metas;
        TxnErrorCode err = meta_reader.get_compact_rowset_metas(tablet_id, &rowset_metas);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_EQ(rowset_metas.size(), 3);

        // Verify the rowset metas are correct
        std::vector<std::pair<int64_t, int64_t>> expected_ranges = {{1, 3}, {4, 6}, {7, 9}};

        // Sort by end_version for consistent comparison
        std::sort(rowset_metas.begin(), rowset_metas.end(), [](const auto& a, const auto& b) {
            return a.first.end_version() < b.first.end_version();
        });

        for (size_t i = 0; i < rowset_metas.size(); ++i) {
            const auto& [rowset_meta, versionstamp] = rowset_metas[i];
            auto [expected_start, expected_end] = expected_ranges[i];

            ASSERT_EQ(rowset_meta.rowset_id_v2(), "compact_rowset_" + std::to_string(i + 1));
            ASSERT_EQ(rowset_meta.start_version(), expected_start);
            ASSERT_EQ(rowset_meta.end_version(), expected_end);
            ASSERT_EQ(rowset_meta.num_rows(), 300 * (i + 1));
            ASSERT_EQ(rowset_meta.data_disk_size(), 3000 * (i + 1));
        }

        // Check min_read_versionstamp is updated
        ASSERT_NE(meta_reader.min_read_versionstamp(), Versionstamp::max());
    }

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

        MetaReader meta_reader(instance_id, txn_kv.get());
        std::vector<std::pair<RowsetMetaCloudPB, Versionstamp>> rowset_metas;
        TxnErrorCode err =
                meta_reader.get_compact_rowset_metas(txn.get(), tablet_id, &rowset_metas);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_EQ(rowset_metas.size(), 3);
    }
}

TEST(MetaReaderTest, HasSnapshot) {
    auto txn_kv = std::make_shared<MemTxnKv>();
    ASSERT_EQ(txn_kv->init(), 0);

    std::string instance_id = "test_instance";

    {
        // Test when snapshot does not exist
        MetaReader meta_reader(instance_id, txn_kv.get());
        bool has_snapshot = true; // Initialize to true to test the change
        TxnErrorCode err = meta_reader.has_snapshot(&has_snapshot);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_FALSE(has_snapshot);
    }

    {
        // Create a snapshot entry
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);

        std::string snapshot_key = versioned::snapshot_full_key({instance_id});
        snapshot_key = encode_versioned_key(snapshot_key, Versionstamp(1, 1));
        SnapshotPB snapshot_pb;
        snapshot_pb.set_label("test_snapshot");
        snapshot_pb.set_instance_id(instance_id);

        ASSERT_TRUE(versioned::document_put(txn.get(), snapshot_key, std::move(snapshot_pb)));
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    {
        // Test when snapshot exists
        MetaReader meta_reader(instance_id, txn_kv.get());
        bool has_snapshot = false; // Initialize to false to test the change
        TxnErrorCode err = meta_reader.has_snapshot(&has_snapshot);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_TRUE(has_snapshot);
    }
}

TEST(MetaReaderTest, HasSnapshotReferences) {
    auto txn_kv = std::make_shared<MemTxnKv>();
    ASSERT_EQ(txn_kv->init(), 0);

    std::string instance_id = "test_instance";
    Versionstamp snapshot_version(12345, 0);

    {
        // Test when no snapshot references exist - should return false
        MetaReader meta_reader(instance_id, txn_kv.get());
        bool has_references = true; // Initialize to true to test the change
        TxnErrorCode err = meta_reader.has_snapshot_references(snapshot_version, &has_references);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_FALSE(has_references);
    }

    {
        // Create some snapshot reference entries with empty values as specified
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);

        // Add snapshot reference entries
        std::string ref_key1 = versioned::snapshot_reference_key(
                {instance_id, snapshot_version, "ref_instance_1"});
        std::string ref_key2 = versioned::snapshot_reference_key(
                {instance_id, snapshot_version, "ref_instance_2"});
        std::string ref_key3 = versioned::snapshot_reference_key(
                {instance_id, snapshot_version, "ref_instance_3"});

        // Put empty values for snapshot_reference_key as specified in requirements
        txn->put(ref_key1, "");
        txn->put(ref_key2, "");
        txn->put(ref_key3, "");

        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    {
        // Test when snapshot references exist - should return true
        MetaReader meta_reader(instance_id, txn_kv.get());
        bool has_references = false; // Initialize to false to test the change
        TxnErrorCode err = meta_reader.has_snapshot_references(snapshot_version, &has_references);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_TRUE(has_references);
    }

    {
        // Test with transaction parameter
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);

        MetaReader meta_reader(instance_id, txn_kv.get());
        bool has_references = false;
        TxnErrorCode err =
                meta_reader.has_snapshot_references(txn.get(), snapshot_version, &has_references);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_TRUE(has_references);
    }

    {
        // Test with different snapshot version that has no references
        Versionstamp different_snapshot_version(54321, 0);
        MetaReader meta_reader(instance_id, txn_kv.get());
        bool has_references = true;
        TxnErrorCode err =
                meta_reader.has_snapshot_references(different_snapshot_version, &has_references);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_FALSE(has_references);
    }

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

        MetaReader meta_reader(instance_id, txn_kv.get());
        bool has_references = false;
        TxnErrorCode err = meta_reader.has_snapshot_references(txn.get(), snapshot_version,
                                                               &has_references, true);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_TRUE(has_references);
    }

    {
        // Test with a range of snapshot references
        // Create additional references with different versions to test prefix matching
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);

        Versionstamp nearby_version1(12344, 0); // One less
        Versionstamp nearby_version2(12346, 0); // One more

        std::string ref_key_before =
                versioned::snapshot_reference_key({instance_id, nearby_version1, "ref_before"});
        std::string ref_key_after =
                versioned::snapshot_reference_key({instance_id, nearby_version2, "ref_after"});

        txn->put(ref_key_before, "");
        txn->put(ref_key_after, "");

        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    {
        // Test that the method only finds references for the exact snapshot version
        MetaReader meta_reader(instance_id, txn_kv.get());
        bool has_references = false;
        TxnErrorCode err = meta_reader.has_snapshot_references(snapshot_version, &has_references);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_TRUE(has_references); // Should still find the original references

        // Test nearby versions
        Versionstamp nearby_version1(12344, 0);
        has_references = false;
        err = meta_reader.has_snapshot_references(nearby_version1, &has_references);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_TRUE(has_references); // Should find the reference for this version

        Versionstamp nearby_version2(12346, 0);
        has_references = false;
        err = meta_reader.has_snapshot_references(nearby_version2, &has_references);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_TRUE(has_references); // Should find the reference for this version

        // Test a version with no references
        Versionstamp no_ref_version(99999, 0);
        has_references = true;
        err = meta_reader.has_snapshot_references(no_ref_version, &has_references);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_FALSE(has_references); // Should not find any references
    }
}

TEST(MetaReaderTest, HasNoIndexes) {
    auto txn_kv = std::make_shared<MemTxnKv>();
    ASSERT_EQ(txn_kv->init(), 0);

    std::string instance_id = "test_instance";
    int64_t db_id = 1001;
    int64_t table_id = 2001;

    {
        // Test when no indexes exist - should return true
        MetaReader meta_reader(instance_id, txn_kv.get());
        bool no_indexes = false;
        TxnErrorCode err = meta_reader.has_no_indexes(db_id, table_id, &no_indexes);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_TRUE(no_indexes);
    }

    {
        // Insert some index_inverted_key entries with empty values
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);

        // Add index entries for the table
        std::string index_key1 = versioned::index_inverted_key({instance_id, db_id, table_id, 1});
        std::string index_key2 = versioned::index_inverted_key({instance_id, db_id, table_id, 2});
        std::string index_key3 = versioned::index_inverted_key({instance_id, db_id, table_id, 3});

        // Put empty values for index_inverted_key as specified in requirements
        txn->put(index_key1, "");
        txn->put(index_key2, "");
        txn->put(index_key3, "");

        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    {
        // Test when indexes exist - should return false
        MetaReader meta_reader(instance_id, txn_kv.get());
        bool no_indexes = true;
        TxnErrorCode err = meta_reader.has_no_indexes(db_id, table_id, &no_indexes);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_FALSE(no_indexes);
    }

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

        MetaReader meta_reader(instance_id, txn_kv.get());
        bool no_indexes = true;
        TxnErrorCode err = meta_reader.has_no_indexes(txn.get(), db_id, table_id, &no_indexes);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_FALSE(no_indexes);
    }

    {
        // Test with different table_id that has no indexes
        int64_t empty_table_id = 3001;
        MetaReader meta_reader(instance_id, txn_kv.get());
        bool no_indexes = false;
        TxnErrorCode err = meta_reader.has_no_indexes(db_id, empty_table_id, &no_indexes);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_TRUE(no_indexes);
    }

    {
        // Test with different db_id that has no indexes
        int64_t empty_db_id = 2001;
        MetaReader meta_reader(instance_id, txn_kv.get());
        bool no_indexes = false;
        TxnErrorCode err = meta_reader.has_no_indexes(empty_db_id, table_id, &no_indexes);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_TRUE(no_indexes);
    }

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

        MetaReader meta_reader(instance_id, txn_kv.get());
        bool no_indexes = true;
        TxnErrorCode err =
                meta_reader.has_no_indexes(txn.get(), db_id, table_id, &no_indexes, true);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_FALSE(no_indexes);
    }
}

TEST(MetaReaderTest, GetAllTabletIds) {
    auto txn_kv = std::make_shared<MemTxnKv>();
    ASSERT_EQ(txn_kv->init(), 0);

    std::string instance_id = "test_instance";

    // Prepare test data - multiple tablet metas
    struct TestTabletMeta {
        int64_t tablet_id;
        int64_t table_id;
        int64_t partition_id;
        int64_t index_id;
    };

    std::vector<TestTabletMeta> test_tablets = {
            {.tablet_id = 1001, .table_id = 2001, .partition_id = 3001, .index_id = 4001},
            {.tablet_id = 1002, .table_id = 2001, .partition_id = 3001, .index_id = 4001},
            {.tablet_id = 1003, .table_id = 2002, .partition_id = 3002, .index_id = 4002},
            {.tablet_id = 1004, .table_id = 2002, .partition_id = 3003, .index_id = 4003},
            {.tablet_id = 1005, .table_id = 2003, .partition_id = 3004, .index_id = 4004},
    };

    // Store original tablet metas for comparison
    std::map<int64_t, TabletIndexPB> original_metas;

    {
        // Create and insert tablet metas
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);

        for (const auto& test_tablet : test_tablets) {
            TabletIndexPB tablet_idx;
            tablet_idx.set_tablet_id(test_tablet.tablet_id);
            tablet_idx.set_table_id(test_tablet.table_id);
            tablet_idx.set_partition_id(test_tablet.partition_id);
            tablet_idx.set_index_id(test_tablet.index_id);

            std::string tablet_key =
                    versioned::tablet_index_key({instance_id, test_tablet.tablet_id});

            // Store original for comparison
            original_metas[test_tablet.tablet_id] = tablet_idx;

            txn->put(tablet_key, tablet_idx.SerializeAsString());
        }

        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    {
        MetaReader meta_reader(instance_id, txn_kv.get());

        std::vector<int64_t> tablet_ids;
        TxnErrorCode err = meta_reader.get_all_tablet_ids(&tablet_ids, false);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_EQ(tablet_ids.size(), test_tablets.size());

        for (const auto& tablet_id : tablet_ids) {
            TabletIndexPB tablet_idx;
            std::string tablet_key = versioned::tablet_index_key({instance_id, tablet_id});
            std::unique_ptr<Transaction> txn;
            ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
            std::string value;
            ASSERT_EQ(txn->get(tablet_key, &value), TxnErrorCode::TXN_OK);
            ASSERT_TRUE(tablet_idx.ParseFromString(value));
            ASSERT_EQ(original_metas[tablet_id].table_id(), tablet_idx.table_id());
            ASSERT_EQ(original_metas[tablet_id].partition_id(), tablet_idx.partition_id());
            ASSERT_EQ(original_metas[tablet_id].index_id(), tablet_idx.index_id());
            ASSERT_EQ(original_metas[tablet_id].tablet_id(), tablet_idx.tablet_id());
        }
    }
}

TEST(MetaReaderTest, FindDerivedInstanceIdsTest) {
    auto txn_kv = std::make_shared<MemTxnKv>();
    std::string instance_id = "test_instance";
    Versionstamp snapshot_version(0x0102030405060708ULL, 0x090a);

    // Create snapshot reference keys for multiple derived instances
    std::vector<std::string> expected_derived_ids = {
            "derived_instance_1",
            "derived_instance_2",
            "derived_instance_3",
            "derived_instance_4",
    };

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

        for (const auto& derived_id : expected_derived_ids) {
            versioned::SnapshotReferenceKeyInfo ref_key_info {instance_id, snapshot_version,
                                                              derived_id};
            std::string ref_key = versioned::snapshot_reference_key(ref_key_info);
            txn->put(ref_key, ""); // Value is empty for reference keys
        }

        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    // Test find_derived_instance_ids
    {
        MetaReader reader(instance_id, txn_kv.get());
        std::vector<std::string> derived_ids;

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

        TxnErrorCode err =
                reader.find_derived_instance_ids(txn.get(), snapshot_version, &derived_ids, false);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_EQ(derived_ids.size(), expected_derived_ids.size());

        // Convert to set for comparison (order doesn't matter)
        std::unordered_set<std::string> derived_set(derived_ids.begin(), derived_ids.end());
        std::unordered_set<std::string> expected_set(expected_derived_ids.begin(),
                                                     expected_derived_ids.end());
        ASSERT_EQ(derived_set, expected_set);
    }

    // Test with no references
    {
        Versionstamp empty_snapshot_version(0x0a0b0c0d0e0f1011ULL, 0x1213);
        MetaReader reader(instance_id, txn_kv.get());
        std::vector<std::string> derived_ids;

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

        TxnErrorCode err = reader.find_derived_instance_ids(txn.get(), empty_snapshot_version,
                                                            &derived_ids, false);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_TRUE(derived_ids.empty());
    }

    // Test with duplicate instance IDs (should be deduplicated)
    {
        Versionstamp dup_snapshot_version(0x1112131415161718ULL, 0x191a);
        std::string dup_instance_id = "duplicate_instance";

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

            // Create multiple references with the same derived instance ID
            // This simulates multiple tables/databases referencing the same snapshot
            for (int i = 0; i < 5; ++i) {
                versioned::SnapshotReferenceKeyInfo ref_key_info {instance_id, dup_snapshot_version,
                                                                  dup_instance_id};
                std::string ref_key = versioned::snapshot_reference_key(ref_key_info);
                txn->put(ref_key, "");
            }

            ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
        }

        MetaReader reader(instance_id, txn_kv.get());
        std::vector<std::string> derived_ids;

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

        TxnErrorCode err = reader.find_derived_instance_ids(txn.get(), dup_snapshot_version,
                                                            &derived_ids, false);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_EQ(derived_ids.size(), 1); // Should be deduplicated
        ASSERT_EQ(derived_ids[0], dup_instance_id);
    }
}
