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

#include <bvar/bvar.h>
#include <bvar/latency_recorder.h>
#include <gen_cpp/Types_types.h>
#include <gen_cpp/olap_file.pb.h>
#include <rapidjson/document.h>
#include <rapidjson/encodings.h>
#include <rapidjson/prettywriter.h>
#include <rapidjson/rapidjson.h>
#include <rapidjson/stringbuffer.h>

#include <algorithm>
#include <atomic>
#include <chrono>
#include <cstdint>
#include <memory>
#include <ranges>
#include <ratio>
#include <shared_mutex>
#include <unordered_map>
#include <vector>

#include "cloud/cloud_meta_mgr.h"
#include "cloud/cloud_storage_engine.h"
#include "cloud/cloud_tablet_mgr.h"
#include "cloud/cloud_warm_up_manager.h"
#include "cloud/config.h"
#include "common/cast_set.h"
#include "common/config.h"
#include "common/logging.h"
#include "cpp/sync_point.h"
#include "io/cache/block_file_cache_downloader.h"
#include "io/cache/block_file_cache_factory.h"
#include "storage/compaction/compaction.h"
#include "storage/compaction/cumulative_compaction_time_series_policy.h"
#include "storage/index/inverted/inverted_index_desc.h"
#include "storage/olap_define.h"
#include "storage/rowset/beta_rowset.h"
#include "storage/rowset/rowset.h"
#include "storage/rowset/rowset_factory.h"
#include "storage/rowset/rowset_fwd.h"
#include "storage/rowset/rowset_writer.h"
#include "storage/storage_policy.h"
#include "storage/tablet/base_tablet.h"
#include "storage/tablet/tablet_schema.h"
#include "storage/txn/txn_manager.h"
#include "util/debug_points.h"
#include "util/stack_util.h"

namespace doris {
#include "common/compile_check_begin.h"
using namespace ErrorCode;

bvar::LatencyRecorder g_cu_compaction_get_delete_bitmap_lock_time_ms(
        "cu_compaction_get_delete_bitmap_lock_time_ms");
bvar::LatencyRecorder g_base_compaction_get_delete_bitmap_lock_time_ms(
        "base_compaction_get_delete_bitmap_lock_time_ms");

bvar::Adder<int64_t> g_unused_rowsets_count("unused_rowsets_count");
bvar::Adder<int64_t> g_unused_rowsets_bytes("unused_rowsets_bytes");

bvar::Adder<int64_t> g_capture_prefer_cache_count("capture_prefer_cache_count");
bvar::Adder<int64_t> g_capture_with_freshness_tolerance_count(
        "capture_with_freshness_tolerance_count");
bvar::Adder<int64_t> g_capture_with_freshness_tolerance_fallback_count(
        "capture_with_freshness_tolerance_fallback_count");
bvar::Adder<int64_t> g_rowset_warmup_state_missing_count("rowset_warmup_state_missing_count");
bvar::Window<bvar::Adder<int64_t>> g_capture_prefer_cache_count_window(
        "capture_prefer_cache_count_window", &g_capture_prefer_cache_count, 30);
bvar::Window<bvar::Adder<int64_t>> g_capture_with_freshness_tolerance_count_window(
        "capture_with_freshness_tolerance_count_window", &g_capture_with_freshness_tolerance_count,
        30);
bvar::Window<bvar::Adder<int64_t>> g_capture_with_freshness_tolerance_fallback_count_window(
        "capture_with_freshness_tolerance_fallback_count_window",
        &g_capture_with_freshness_tolerance_fallback_count, 30);

static constexpr int LOAD_INITIATOR_ID = -1;

bvar::Adder<uint64_t> g_file_cache_cloud_tablet_submitted_segment_size(
        "file_cache_cloud_tablet_submitted_segment_size");
bvar::Adder<uint64_t> g_file_cache_cloud_tablet_submitted_segment_num(
        "file_cache_cloud_tablet_submitted_segment_num");
bvar::Adder<uint64_t> g_file_cache_cloud_tablet_submitted_index_size(
        "file_cache_cloud_tablet_submitted_index_size");
bvar::Adder<uint64_t> g_file_cache_cloud_tablet_submitted_index_num(
        "file_cache_cloud_tablet_submitted_index_num");
bvar::Adder<uint64_t> g_file_cache_cloud_tablet_finished_segment_size(
        "file_cache_cloud_tablet_finished_segment_size");
bvar::Adder<uint64_t> g_file_cache_cloud_tablet_finished_segment_num(
        "file_cache_cloud_tablet_finished_segment_num");
bvar::Adder<uint64_t> g_file_cache_cloud_tablet_finished_index_size(
        "file_cache_cloud_tablet_finished_index_size");
bvar::Adder<uint64_t> g_file_cache_cloud_tablet_finished_index_num(
        "file_cache_cloud_tablet_finished_index_num");

bvar::Adder<uint64_t> g_file_cache_recycle_cached_data_segment_num(
        "file_cache_recycle_cached_data_segment_num");
bvar::Adder<uint64_t> g_file_cache_recycle_cached_data_segment_size(
        "file_cache_recycle_cached_data_segment_size");
bvar::Adder<uint64_t> g_file_cache_recycle_cached_data_index_num(
        "file_cache_recycle_cached_data_index_num");

bvar::Adder<uint64_t> g_file_cache_warm_up_segment_complete_num(
        "file_cache_warm_up_segment_complete_num");
bvar::Adder<uint64_t> g_file_cache_warm_up_segment_failed_num(
        "file_cache_warm_up_segment_failed_num");
bvar::Adder<uint64_t> g_file_cache_warm_up_inverted_idx_complete_num(
        "file_cache_warm_up_inverted_idx_complete_num");
bvar::Adder<uint64_t> g_file_cache_warm_up_inverted_idx_failed_num(
        "file_cache_warm_up_inverted_idx_failed_num");
bvar::Adder<uint64_t> g_file_cache_warm_up_rowset_complete_num(
        "file_cache_warm_up_rowset_complete_num");
bvar::Adder<uint64_t> g_file_cache_warm_up_rowset_triggered_by_job_num(
        "file_cache_warm_up_rowset_triggered_by_job_num");
bvar::Adder<uint64_t> g_file_cache_warm_up_rowset_triggered_by_sync_rowset_num(
        "file_cache_warm_up_rowset_triggered_by_sync_rowset_num");
bvar::Adder<uint64_t> g_file_cache_warm_up_rowset_triggered_by_event_driven_num(
        "file_cache_warm_up_rowset_triggered_by_event_driven_num");
bvar::LatencyRecorder g_file_cache_warm_up_rowset_all_segments_latency(
        "file_cache_warm_up_rowset_all_segments_latency");

CloudTablet::CloudTablet(CloudStorageEngine& engine, TabletMetaSharedPtr tablet_meta)
        : BaseTablet(std::move(tablet_meta)), _engine(engine) {}

CloudTablet::~CloudTablet() = default;

bool CloudTablet::exceed_version_limit(int32_t limit) {
    return _approximate_num_rowsets.load(std::memory_order_relaxed) > limit;
}

std::string CloudTablet::tablet_path() const {
    return "";
}

Status CloudTablet::capture_rs_readers(const Version& spec_version,
                                       std::vector<RowSetSplits>* rs_splits,
                                       const CaptureRowsetOps& opts) {
    DBUG_EXECUTE_IF("CloudTablet.capture_rs_readers.return.e-230", {
        LOG_WARNING("CloudTablet.capture_rs_readers.return e-230").tag("tablet_id", tablet_id());
        return Status::Error<false>(-230, "injected error");
    });
    std::shared_lock rlock(_meta_lock);
    *rs_splits = DORIS_TRY(capture_rs_readers_unlocked(
            spec_version, CaptureRowsetOps {.skip_missing_versions = opts.skip_missing_versions}));
    return Status::OK();
}

[[nodiscard]] Result<std::vector<Version>> CloudTablet::capture_consistent_versions_unlocked(
        const Version& version_range, const CaptureRowsetOps& options) const {
    if (options.query_freshness_tolerance_ms > 0) {
        return capture_versions_with_freshness_tolerance(version_range, options);
    } else if (options.enable_prefer_cached_rowset && !enable_unique_key_merge_on_write()) {
        return capture_versions_prefer_cache(version_range);
    }
    return BaseTablet::capture_consistent_versions_unlocked(version_range, options);
}

Result<std::vector<Version>> CloudTablet::capture_versions_prefer_cache(
        const Version& spec_version) const {
    g_capture_prefer_cache_count << 1;
    Versions version_path;
    std::shared_lock rlock(_meta_lock);
    auto st = _timestamped_version_tracker.capture_consistent_versions_prefer_cache(
            spec_version, version_path,
            [&](int64_t start, int64_t end) { return rowset_is_warmed_up_unlocked(start, end); });
    if (!st.ok()) {
        return ResultError(st);
    }
    int64_t path_max_version = version_path.back().second;
    VLOG_DEBUG << fmt::format(
            "[verbose] CloudTablet::capture_versions_prefer_cache, capture path: {}, "
            "tablet_id={}, spec_version={}, path_max_version={}",
            fmt::join(version_path | std::views::transform([](const auto& version) {
                          return fmt::format("{}", version.to_string());
                      }),
                      ", "),
            tablet_id(), spec_version.to_string(), path_max_version);
    return version_path;
}

bool CloudTablet::rowset_is_warmed_up_unlocked(int64_t start_version, int64_t end_version) const {
    if (start_version > end_version) {
        return false;
    }
    Version version {start_version, end_version};
    auto it = _rs_version_map.find(version);
    if (it == _rs_version_map.end()) {
        it = _stale_rs_version_map.find(version);
        if (it == _stale_rs_version_map.end()) {
            LOG_WARNING(
                    "fail to find Rowset in rs_version or stale_rs_version for version. "
                    "tablet={}, version={}",
                    tablet_id(), version.to_string());
            return false;
        }
    }
    const auto& rs = it->second;
    if (rs->visible_timestamp() < _engine.startup_timepoint()) {
        // We only care about rowsets that are created after startup time point. For other rowsets,
        // we assume they are warmed up.
        return true;
    }
    return is_rowset_warmed_up(rs->rowset_id());
};

Result<std::vector<Version>> CloudTablet::capture_versions_with_freshness_tolerance(
        const Version& spec_version, const CaptureRowsetOps& options) const {
    g_capture_with_freshness_tolerance_count << 1;
    using namespace std::chrono;
    auto query_freshness_tolerance_ms = options.query_freshness_tolerance_ms;
    auto freshness_limit_tp = system_clock::now() - milliseconds(query_freshness_tolerance_ms);
    // find a version path where every edge(rowset) has been warmuped
    Versions version_path;
    std::shared_lock rlock(_meta_lock);
    if (enable_unique_key_merge_on_write()) {
        // For merge-on-write table, newly generated delete bitmap marks will be on the rowsets which are in newest layout.
        // So we can ony capture rowsets which are in newest data layout. Otherwise there may be data correctness issue.
        RETURN_IF_ERROR_RESULT(
                _timestamped_version_tracker.capture_consistent_versions_with_validator_mow(
                        spec_version, version_path, [&](int64_t start, int64_t end) {
                            return rowset_is_warmed_up_unlocked(start, end);
                        }));
    } else {
        RETURN_IF_ERROR_RESULT(
                _timestamped_version_tracker.capture_consistent_versions_with_validator(
                        spec_version, version_path, [&](int64_t start, int64_t end) {
                            return rowset_is_warmed_up_unlocked(start, end);
                        }));
    }
    int64_t path_max_version = version_path.back().second;
    // use std::views::concat after C++26
    auto check_fn = [this, path_max_version, freshness_limit_tp](const auto& rs_meta) {
        return _check_rowset_should_be_visible_but_not_warmed_up(rs_meta, path_max_version,
                                                                 freshness_limit_tp);
    };
    bool should_fallback =
            std::ranges::any_of(std::views::values(_tablet_meta->all_rs_metas()), check_fn) ||
            std::ranges::any_of(std::views::values(_tablet_meta->all_stale_rs_metas()), check_fn);
    if (should_fallback) {
        rlock.unlock();
        g_capture_with_freshness_tolerance_fallback_count << 1;
        // if there exists a rowset which satisfies freshness tolerance and its start version is larger than the path max version
        // but has not been warmuped up yet, fallback to capture rowsets as usual
        return BaseTablet::capture_consistent_versions_unlocked(spec_version, options);
    }
    VLOG_DEBUG << fmt::format(
            "[verbose] CloudTablet::capture_versions_with_freshness_tolerance, capture path: {}, "
            "tablet_id={}, spec_version={}, path_max_version={}",
            fmt::join(version_path | std::views::transform([](const auto& version) {
                          return fmt::format("{}", version.to_string());
                      }),
                      ", "),
            tablet_id(), spec_version.to_string(), path_max_version);
    return version_path;
}

// There are only two tablet_states RUNNING and NOT_READY in cloud mode
// This function will erase the tablet from `CloudTabletMgr` when it can't find this tablet in MS.
Status CloudTablet::sync_rowsets(const SyncOptions& options, SyncRowsetStats* stats) {
    RETURN_IF_ERROR(sync_if_not_running(stats));

    if (options.query_version > 0) {
        auto lock_start = std::chrono::steady_clock::now();
        std::shared_lock rlock(_meta_lock);
        if (stats) {
            stats->meta_lock_wait_ns += std::chrono::duration_cast<std::chrono::nanoseconds>(
                                                std::chrono::steady_clock::now() - lock_start)
                                                .count();
        }
        if (_max_version >= options.query_version) {
            return Status::OK();
        }
    }

    // serially execute sync to reduce unnecessary network overhead
    auto sync_lock_start = std::chrono::steady_clock::now();
    std::unique_lock lock(_sync_meta_lock);
    if (stats) {
        stats->sync_meta_lock_wait_ns += std::chrono::duration_cast<std::chrono::nanoseconds>(
                                                 std::chrono::steady_clock::now() - sync_lock_start)
                                                 .count();
    }
    if (options.query_version > 0) {
        auto lock_start = std::chrono::steady_clock::now();
        std::shared_lock rlock(_meta_lock);
        if (stats) {
            stats->meta_lock_wait_ns += std::chrono::duration_cast<std::chrono::nanoseconds>(
                                                std::chrono::steady_clock::now() - lock_start)
                                                .count();
        }
        if (_max_version >= options.query_version) {
            return Status::OK();
        }
    }

    auto st = _engine.meta_mgr().sync_tablet_rowsets_unlocked(this, lock, options, stats);
    if (st.is<ErrorCode::NOT_FOUND>()) {
        clear_cache();
    }

    return st;
}

// Sync tablet meta and all rowset meta if not running.
// This could happen when BE didn't finish schema change job and another BE committed this schema change job.
// It should be a quite rare situation.
Status CloudTablet::sync_if_not_running(SyncRowsetStats* stats) {
    if (tablet_state() == TABLET_RUNNING) {
        return Status::OK();
    }

    // Serially execute sync to reduce unnecessary network overhead
    auto sync_lock_start = std::chrono::steady_clock::now();
    std::unique_lock lock(_sync_meta_lock);
    if (stats) {
        stats->sync_meta_lock_wait_ns += std::chrono::duration_cast<std::chrono::nanoseconds>(
                                                 std::chrono::steady_clock::now() - sync_lock_start)
                                                 .count();
    }

    {
        auto lock_start = std::chrono::steady_clock::now();
        std::shared_lock rlock(_meta_lock);
        if (stats) {
            stats->meta_lock_wait_ns += std::chrono::duration_cast<std::chrono::nanoseconds>(
                                                std::chrono::steady_clock::now() - lock_start)
                                                .count();
        }
        if (tablet_state() == TABLET_RUNNING) {
            return Status::OK();
        }
    }

    TabletMetaSharedPtr tablet_meta;
    auto st = _engine.meta_mgr().get_tablet_meta(tablet_id(), &tablet_meta);
    if (!st.ok()) {
        if (st.is<ErrorCode::NOT_FOUND>()) {
            clear_cache();
        }
        return st;
    }

    if (tablet_meta->tablet_state() != TABLET_RUNNING) [[unlikely]] {
        // MoW may go to here when load while schema change
        return Status::OK();
    }

    TimestampedVersionTracker empty_tracker;
    {
        auto lock_start = std::chrono::steady_clock::now();
        std::lock_guard wlock(_meta_lock);
        if (stats) {
            stats->meta_lock_wait_ns += std::chrono::duration_cast<std::chrono::nanoseconds>(
                                                std::chrono::steady_clock::now() - lock_start)
                                                .count();
        }
        RETURN_IF_ERROR(set_tablet_state(TABLET_RUNNING));
        _rs_version_map.clear();
        _stale_rs_version_map.clear();
        std::swap(_timestamped_version_tracker, empty_tracker);
        _tablet_meta->clear_rowsets();
        _tablet_meta->clear_stale_rowset();
        _max_version = -1;
    }

    st = _engine.meta_mgr().sync_tablet_rowsets_unlocked(this, lock, {}, stats);
    if (st.is<ErrorCode::NOT_FOUND>()) {
        clear_cache();
    }
    return st;
}

void CloudTablet::add_rowsets(std::vector<RowsetSharedPtr> to_add, bool version_overlap,
                              std::unique_lock<std::shared_mutex>& meta_lock,
                              bool warmup_delta_data) {
    if (to_add.empty()) {
        return;
    }

    VLOG_DEBUG << "add_rowsets tablet_id=" << tablet_id() << " stack: " << get_stack_trace();

    if (!version_overlap) {
        _add_rowsets_directly(to_add, warmup_delta_data);
        return;
    }

    // Filter out existed rowsets
    auto remove_it =
            std::remove_if(to_add.begin(), to_add.end(), [this](const RowsetSharedPtr& rs) {
                if (auto find_it = _rs_version_map.find(rs->version());
                    find_it == _rs_version_map.end()) {
                    return false;
                } else if (find_it->second->rowset_id() == rs->rowset_id()) {
                    return true; // Same rowset
                }

                // If version of rowset in `to_add` is equal to rowset in tablet but rowset_id is not equal,
                // replace existed rowset with `to_add` rowset. This may occur when:
                //  1. schema change converts rowsets which have been double written to new tablet
                //  2. cumu compaction picks single overlapping input rowset to perform compaction

                // add existed rowset to unused_rowsets to remove delete bitmap and recycle cached data

                std::vector<RowsetSharedPtr> unused_rowsets;
                if (auto find_it = _rs_version_map.find(rs->version());
                    find_it != _rs_version_map.end()) {
                    if (find_it->second->rowset_id() == rs->rowset_id()) {
                        LOG(WARNING) << "tablet_id=" << tablet_id()
                                     << ", rowset_id=" << rs->rowset_id().to_string()
                                     << ", existed rowset_id="
                                     << find_it->second->rowset_id().to_string();
                        DCHECK(find_it->second->rowset_id() != rs->rowset_id())
                                << "tablet_id=" << tablet_id()
                                << ", rowset_id=" << rs->rowset_id().to_string()
                                << ", existed rowset_id="
                                << find_it->second->rowset_id().to_string();
                    }
                    unused_rowsets.push_back(find_it->second);
                }
                add_unused_rowsets(unused_rowsets);

                _tablet_meta->delete_rs_meta_by_version(rs->version(), nullptr);
                _rs_version_map[rs->version()] = rs;
                _tablet_meta->add_rowsets_unchecked({rs});
                update_base_size(*rs);
                return true;
            });

    to_add.erase(remove_it, to_add.end());

    // delete rowsets with overlapped version
    std::vector<RowsetSharedPtr> to_add_directly;
    for (auto& to_add_rs : to_add) {
        // delete rowsets with overlapped version
        std::vector<RowsetSharedPtr> to_delete;
        Version to_add_v = to_add_rs->version();
        // if start_version  > max_version, we can skip checking overlap here.
        if (to_add_v.first > _max_version) {
            // if start_version  > max_version, we can skip checking overlap here.
            to_add_directly.push_back(to_add_rs);
        } else {
            to_add_directly.push_back(to_add_rs);
            for (auto& [v, rs] : _rs_version_map) {
                if (to_add_v.contains(v)) {
                    to_delete.push_back(rs);
                }
            }
            delete_rowsets(to_delete, meta_lock);
        }
    }

    _add_rowsets_directly(to_add_directly, warmup_delta_data);
}

void CloudTablet::delete_rowsets(const std::vector<RowsetSharedPtr>& to_delete,
                                 std::unique_lock<std::shared_mutex>&) {
    if (to_delete.empty()) {
        return;
    }
    std::vector<RowsetMetaSharedPtr> rs_metas;
    rs_metas.reserve(to_delete.size());
    int64_t now = ::time(nullptr);
    for (auto&& rs : to_delete) {
        rs->rowset_meta()->set_stale_at(now);
        rs_metas.push_back(rs->rowset_meta());
        _stale_rs_version_map[rs->version()] = rs;
    }
    _timestamped_version_tracker.add_stale_path_version(rs_metas);
    for (auto&& rs : to_delete) {
        _rs_version_map.erase(rs->version());
    }

    _tablet_meta->modify_rs_metas({}, rs_metas, false);
}

uint64_t CloudTablet::delete_expired_stale_rowsets() {
    if (config::enable_mow_verbose_log) {
        LOG_INFO("begin delete_expired_stale_rowset for tablet={}", tablet_id());
    }
    std::vector<RowsetSharedPtr> expired_rowsets;
    // ATTN: trick, Use stale_rowsets to temporarily increase the reference count of the rowset shared pointer in _stale_rs_version_map so that in the recycle_cached_data function, it checks if the reference count is 2.
    std::vector<std::pair<Version, std::vector<RowsetSharedPtr>>> deleted_stale_rowsets;
    int64_t expired_stale_sweep_endtime =
            ::time(nullptr) - config::tablet_rowset_stale_sweep_time_sec;
    {
        std::unique_lock wlock(_meta_lock);

        std::vector<int64_t> path_ids;
        // capture the path version to delete
        _timestamped_version_tracker.capture_expired_paths(expired_stale_sweep_endtime, &path_ids);

        if (path_ids.empty()) {
            return 0;
        }

        for (int64_t path_id : path_ids) {
            int64_t start_version = -1;
            int64_t end_version = -1;
            std::vector<RowsetSharedPtr> stale_rowsets;
            // delete stale versions in version graph
            auto version_path = _timestamped_version_tracker.fetch_and_delete_path_by_id(path_id);
            for (auto& v_ts : version_path->timestamped_versions()) {
                auto rs_it = _stale_rs_version_map.find(v_ts->version());
                if (rs_it != _stale_rs_version_map.end()) {
                    expired_rowsets.push_back(rs_it->second);
                    stale_rowsets.push_back(rs_it->second);
                    VLOG_DEBUG << "erase stale rowset, tablet_id=" << tablet_id()
                               << " rowset_id=" << rs_it->second->rowset_id().to_string()
                               << " version=" << rs_it->first.to_string();
                    _stale_rs_version_map.erase(rs_it);
                } else {
                    LOG(WARNING) << "cannot find stale rowset " << v_ts->version() << " in tablet "
                                 << tablet_id();
                    // clang-format off
                    DCHECK(false) << [this, &wlock]() { wlock.unlock(); std::string json; get_compaction_status(&json); return json; }();
                    // clang-format on
                }
                if (start_version < 0) {
                    start_version = v_ts->version().first;
                }
                end_version = v_ts->version().second;
                _tablet_meta->delete_stale_rs_meta_by_version(v_ts->version());
            }
            Version version(start_version, end_version);
            if (!stale_rowsets.empty()) {
                deleted_stale_rowsets.emplace_back(version, std::move(stale_rowsets));
            }
        }
        _reconstruct_version_tracker_if_necessary();
    }

    // if the rowset is not used by any query, we can recycle its cached data early.
    auto recycled_rowsets = recycle_cached_data(expired_rowsets);
    if (!recycled_rowsets.empty()) {
        auto& manager = ExecEnv::GetInstance()->storage_engine().to_cloud().cloud_warm_up_manager();
        manager.recycle_cache(tablet_id(), recycled_rowsets);
    }
    if (config::enable_mow_verbose_log) {
        LOG_INFO("finish delete_expired_stale_rowset for tablet={}", tablet_id());
    }

    add_unused_rowsets(expired_rowsets);
    if (config::enable_agg_and_remove_pre_rowsets_delete_bitmap && keys_type() == UNIQUE_KEYS &&
        enable_unique_key_merge_on_write() && !deleted_stale_rowsets.empty()) {
        // agg delete bitmap for pre rowsets; record unused delete bitmap key ranges
        OlapStopWatch watch;
        for (const auto& [version, unused_rowsets] : deleted_stale_rowsets) {
            // agg delete bitmap for pre rowset
            DeleteBitmapKeyRanges remove_delete_bitmap_key_ranges;
            agg_delete_bitmap_for_stale_rowsets(version, remove_delete_bitmap_key_ranges);
            // add remove delete bitmap
            if (!remove_delete_bitmap_key_ranges.empty()) {
                std::vector<RowsetId> rowset_ids;
                for (const auto& rs : unused_rowsets) {
                    rowset_ids.push_back(rs->rowset_id());
                }
                std::lock_guard<std::mutex> lock(_gc_mutex);
                _unused_delete_bitmap.push_back(
                        std::make_pair(rowset_ids, remove_delete_bitmap_key_ranges));
            }
        }
        LOG(INFO) << "agg pre rowsets delete bitmap. tablet_id=" << tablet_id()
                  << ", size=" << deleted_stale_rowsets.size()
                  << ", cost(us)=" << watch.get_elapse_time_us();
    }
    return expired_rowsets.size();
}

bool CloudTablet::need_remove_unused_rowsets() {
    std::lock_guard<std::mutex> lock(_gc_mutex);
    return !_unused_rowsets.empty() || !_unused_delete_bitmap.empty();
}

void CloudTablet::add_unused_rowsets(const std::vector<RowsetSharedPtr>& rowsets) {
    std::lock_guard<std::mutex> lock(_gc_mutex);
    for (const auto& rowset : rowsets) {
        _unused_rowsets[rowset->rowset_id()] = rowset;
        g_unused_rowsets_bytes << rowset->total_disk_size();
    }
    g_unused_rowsets_count << rowsets.size();
}

void CloudTablet::remove_unused_rowsets() {
    std::vector<std::shared_ptr<Rowset>> removed_rowsets;
    int64_t removed_delete_bitmap_num = 0;
    OlapStopWatch watch;
    {
        std::lock_guard<std::mutex> lock(_gc_mutex);
        // 1. remove unused rowsets's cache data and delete bitmap
        for (auto it = _unused_rowsets.begin(); it != _unused_rowsets.end();) {
            auto& rs = it->second;
            if (rs.use_count() > 1) {
                LOG(WARNING) << "tablet_id:" << tablet_id() << " rowset: " << rs->rowset_id()
                             << " has " << rs.use_count() << " references, it cannot be removed";
                ++it;
                continue;
            }
            tablet_meta()->remove_rowset_delete_bitmap(rs->rowset_id(), rs->version());
            _rowset_warm_up_states.erase(rs->rowset_id());
            rs->clear_cache();
            g_unused_rowsets_count << -1;
            g_unused_rowsets_bytes << -rs->total_disk_size();
            removed_rowsets.push_back(std::move(rs));
            it = _unused_rowsets.erase(it);
        }
    }

    {
        std::vector<RecycledRowsets> recycled_rowsets;

        for (auto& rs : removed_rowsets) {
            auto index_names = rs->get_index_file_names();
            recycled_rowsets.emplace_back(rs->rowset_id(), rs->num_segments(), index_names);
            int64_t segment_size_sum = 0;
            for (int32_t i = 0; i < rs->num_segments(); i++) {
                segment_size_sum += rs->rowset_meta()->segment_file_size(i);
            }
            g_file_cache_recycle_cached_data_segment_num << rs->num_segments();
            g_file_cache_recycle_cached_data_segment_size << segment_size_sum;
            g_file_cache_recycle_cached_data_index_num << index_names.size();
        }

        if (recycled_rowsets.size() > 0) {
            auto& manager =
                    ExecEnv::GetInstance()->storage_engine().to_cloud().cloud_warm_up_manager();
            manager.recycle_cache(tablet_id(), recycled_rowsets);
        }
    }

    {
        std::lock_guard<std::mutex> lock(_gc_mutex);
        // 2. remove delete bitmap of pre rowsets
        for (auto it = _unused_delete_bitmap.begin(); it != _unused_delete_bitmap.end();) {
            auto& rowset_ids = std::get<0>(*it);
            bool find_unused_rowset = false;
            for (const auto& rowset_id : rowset_ids) {
                if (_unused_rowsets.find(rowset_id) != _unused_rowsets.end()) {
                    LOG(INFO) << "can not remove pre rowset delete bitmap because rowset is in use"
                              << ", tablet_id=" << tablet_id() << ", rowset_id=" << rowset_id;
                    find_unused_rowset = true;
                    break;
                }
            }
            if (find_unused_rowset) {
                ++it;
                continue;
            }
            auto& key_ranges = std::get<1>(*it);
            tablet_meta()->delete_bitmap().remove(key_ranges);
            it = _unused_delete_bitmap.erase(it);
            removed_delete_bitmap_num++;
            // TODO(kaijie): recycle cache for unused delete bitmap
        }
    }

    LOG(INFO) << "tablet_id=" << tablet_id() << ", unused_rowset size=" << _unused_rowsets.size()
              << ", unused_delete_bitmap size=" << _unused_delete_bitmap.size()
              << ", removed_rowsets_num=" << removed_rowsets.size()
              << ", removed_delete_bitmap_num=" << removed_delete_bitmap_num
              << ", cost(us)=" << watch.get_elapse_time_us();
}

void CloudTablet::update_base_size(const Rowset& rs) {
    // Define base rowset as the rowset of version [2-x]
    if (rs.start_version() == 2) {
        _base_size = rs.total_disk_size();
    }
}

void CloudTablet::clear_cache() {
    auto recycled_rowsets = CloudTablet::recycle_cached_data(get_snapshot_rowset(true));
    if (!recycled_rowsets.empty()) {
        auto& manager = ExecEnv::GetInstance()->storage_engine().to_cloud().cloud_warm_up_manager();
        manager.recycle_cache(tablet_id(), recycled_rowsets);
    }
    _engine.tablet_mgr().erase_tablet(tablet_id());
}

std::vector<RecycledRowsets> CloudTablet::recycle_cached_data(
        const std::vector<RowsetSharedPtr>& rowsets) {
    std::vector<RecycledRowsets> recycled_rowsets;
    for (const auto& rs : rowsets) {
        // rowsets and tablet._rs_version_map each hold a rowset shared_ptr, so at this point, the reference count of the shared_ptr is at least 2.
        if (rs.use_count() > 2) {
            LOG(WARNING) << "Rowset " << rs->rowset_id().to_string() << " has " << rs.use_count()
                         << " references. File Cache won't be recycled when query is using it.";
            continue;
        }
        rs->clear_cache();
        auto index_names = rs->get_index_file_names();
        recycled_rowsets.emplace_back(rs->rowset_id(), rs->num_segments(), index_names);

        int64_t segment_size_sum = 0;
        for (int32_t i = 0; i < rs->num_segments(); i++) {
            segment_size_sum += rs->rowset_meta()->segment_file_size(i);
        }
        g_file_cache_recycle_cached_data_segment_num << rs->num_segments();
        g_file_cache_recycle_cached_data_segment_size << segment_size_sum;
        g_file_cache_recycle_cached_data_index_num << index_names.size();
    }
    return recycled_rowsets;
}

void CloudTablet::reset_approximate_stats(int64_t num_rowsets, int64_t num_segments,
                                          int64_t num_rows, int64_t data_size) {
    _approximate_num_segments.store(num_segments, std::memory_order_relaxed);
    _approximate_num_rows.store(num_rows, std::memory_order_relaxed);
    _approximate_data_size.store(data_size, std::memory_order_relaxed);
    int64_t cumu_num_deltas = 0;
    int64_t cumu_num_rowsets = 0;
    auto cp = _cumulative_point.load(std::memory_order_relaxed);
    for (auto& [v, r] : _rs_version_map) {
        if (v.second < cp) {
            continue;
        }
        cumu_num_deltas += r->is_segments_overlapping() ? r->num_segments() : 1;
        ++cumu_num_rowsets;
    }
    // num_rowsets may be less than the size of _rs_version_map when there are some hole rowsets
    // in the version map, so we use the max value to ensure that the approximate number
    // of rowsets is at least the size of _rs_version_map.
    // Note that this is not the exact number of rowsets, but an approximate number.
    int64_t approximate_num_rowsets =
            std::max(num_rowsets, static_cast<int64_t>(_rs_version_map.size()));
    _approximate_num_rowsets.store(approximate_num_rowsets, std::memory_order_relaxed);
    _approximate_cumu_num_rowsets.store(cumu_num_rowsets, std::memory_order_relaxed);
    _approximate_cumu_num_deltas.store(cumu_num_deltas, std::memory_order_relaxed);
}

Result<std::unique_ptr<RowsetWriter>> CloudTablet::create_rowset_writer(
        RowsetWriterContext& context, bool vertical) {
    context.rowset_id = _engine.next_rowset_id();
    // FIXME(plat1ko): Seems `tablet_id` and `index_id` has been set repeatedly
    context.tablet_id = tablet_id();
    context.index_id = index_id();
    context.partition_id = partition_id();
    context.enable_unique_key_merge_on_write = enable_unique_key_merge_on_write();
    context.encrypt_algorithm = tablet_meta()->encryption_algorithm();
    return RowsetFactory::create_rowset_writer(_engine, context, vertical);
}

// create a rowset writer with rowset_id and seg_id
// after writer, merge this transient rowset with original rowset
Result<std::unique_ptr<RowsetWriter>> CloudTablet::create_transient_rowset_writer(
        const Rowset& rowset, std::shared_ptr<PartialUpdateInfo> partial_update_info,
        int64_t txn_expiration) {
    if (rowset.rowset_meta_state() != RowsetStatePB::BEGIN_PARTIAL_UPDATE &&
        rowset.rowset_meta_state() != RowsetStatePB::COMMITTED) [[unlikely]] {
        auto msg = fmt::format(
                "wrong rowset state when create_transient_rowset_writer, rowset state should be "
                "BEGIN_PARTIAL_UPDATE or COMMITTED, but found {}, rowset_id={}, tablet_id={}",
                RowsetStatePB_Name(rowset.rowset_meta_state()), rowset.rowset_id().to_string(),
                tablet_id());
        // see `CloudRowsetWriter::build` for detail.
        // if this is in a retry task, the rowset state may have been changed to RowsetStatePB::COMMITTED
        // in `RowsetMeta::merge_rowset_meta()` in previous trials.
        LOG(WARNING) << msg;
        DCHECK(false) << msg;
    }
    RowsetWriterContext context;
    context.rowset_state = PREPARED;
    context.segments_overlap = OVERLAPPING;
    // During a partial update, the extracted columns of a variant should not be included in the tablet schema.
    // This is because the partial update for a variant needs to ignore the extracted columns.
    // Otherwise, the schema types in different rowsets might be inconsistent. When performing a partial update,
    // the complete variant is constructed by reading all the sub-columns of the variant.
    context.tablet_schema = rowset.tablet_schema()->copy_without_variant_extracted_columns();
    context.newest_write_timestamp = UnixSeconds();
    context.tablet_id = table_id();
    context.enable_segcompaction = false;
    context.write_type = DataWriteType::TYPE_DIRECT;
    context.partial_update_info = std::move(partial_update_info);
    context.is_transient_rowset_writer = true;
    context.rowset_id = rowset.rowset_id();
    context.tablet_id = tablet_id();
    context.index_id = index_id();
    context.partition_id = partition_id();
    context.enable_unique_key_merge_on_write = enable_unique_key_merge_on_write();
    context.txn_expiration = txn_expiration;
    context.encrypt_algorithm = tablet_meta()->encryption_algorithm();
    // TODO(liaoxin) enable packed file for transient rowset
    context.allow_packed_file = false;

    auto storage_resource = rowset.rowset_meta()->remote_storage_resource();
    if (!storage_resource) {
        return ResultError(std::move(storage_resource.error()));
    }

    context.storage_resource = *storage_resource.value();

    return RowsetFactory::create_rowset_writer(_engine, context, false)
            .transform([&](auto&& writer) {
                writer->set_segment_start_id(cast_set<int32_t>(rowset.num_segments()));
                return writer;
            });
}

int64_t CloudTablet::get_cloud_base_compaction_score() const {
    if (_tablet_meta->compaction_policy() == CUMULATIVE_TIME_SERIES_POLICY) {
        bool has_delete = false;
        int64_t point = cumulative_layer_point();
        std::shared_lock<std::shared_mutex> rlock(_meta_lock);
        for (const auto& [_, rs_meta] : _tablet_meta->all_rs_metas()) {
            if (rs_meta->start_version() >= point) {
                continue;
            }
            if (rs_meta->has_delete_predicate()) {
                has_delete = true;
                break;
            }
        }
        if (!has_delete) {
            return 0;
        }
    }

    return _approximate_num_rowsets.load(std::memory_order_relaxed) -
           _approximate_cumu_num_rowsets.load(std::memory_order_relaxed);
}

int64_t CloudTablet::get_cloud_cumu_compaction_score() const {
    // TODO(plat1ko): Propose an algorithm that considers tablet's key type, number of delete rowsets,
    //  number of tablet versions simultaneously.
    return _approximate_cumu_num_deltas.load(std::memory_order_relaxed);
}

// return a json string to show the compaction status of this tablet
void CloudTablet::get_compaction_status(std::string* json_result) {
    rapidjson::Document root;
    root.SetObject();

    rapidjson::Document path_arr;
    path_arr.SetArray();

    std::vector<RowsetSharedPtr> rowsets;
    std::vector<RowsetSharedPtr> stale_rowsets;
    {
        std::shared_lock rdlock(_meta_lock);
        rowsets.reserve(_rs_version_map.size());
        for (auto& it : _rs_version_map) {
            rowsets.push_back(it.second);
        }
        stale_rowsets.reserve(_stale_rs_version_map.size());
        for (auto& it : _stale_rs_version_map) {
            stale_rowsets.push_back(it.second);
        }
    }
    std::sort(rowsets.begin(), rowsets.end(), Rowset::comparator);
    std::sort(stale_rowsets.begin(), stale_rowsets.end(), Rowset::comparator);

    // get snapshot version path json_doc
    _timestamped_version_tracker.get_stale_version_path_json_doc(path_arr);
    root.AddMember("cumulative point", _cumulative_point.load(), root.GetAllocator());
    rapidjson::Value cumu_value;
    std::string format_str = ToStringFromUnixMillis(_last_cumu_compaction_failure_millis.load());
    cumu_value.SetString(format_str.c_str(), cast_set<uint>(format_str.length()),
                         root.GetAllocator());
    root.AddMember("last cumulative failure time", cumu_value, root.GetAllocator());
    rapidjson::Value base_value;
    format_str = ToStringFromUnixMillis(_last_base_compaction_failure_millis.load());
    base_value.SetString(format_str.c_str(), cast_set<uint>(format_str.length()),
                         root.GetAllocator());
    root.AddMember("last base failure time", base_value, root.GetAllocator());
    rapidjson::Value full_value;
    format_str = ToStringFromUnixMillis(_last_full_compaction_failure_millis.load());
    full_value.SetString(format_str.c_str(), cast_set<uint>(format_str.length()),
                         root.GetAllocator());
    root.AddMember("last full failure time", full_value, root.GetAllocator());
    rapidjson::Value cumu_success_value;
    format_str = ToStringFromUnixMillis(_last_cumu_compaction_success_millis.load());
    cumu_success_value.SetString(format_str.c_str(), cast_set<uint>(format_str.length()),
                                 root.GetAllocator());
    root.AddMember("last cumulative success time", cumu_success_value, root.GetAllocator());
    rapidjson::Value base_success_value;
    format_str = ToStringFromUnixMillis(_last_base_compaction_success_millis.load());
    base_success_value.SetString(format_str.c_str(), cast_set<uint>(format_str.length()),
                                 root.GetAllocator());
    root.AddMember("last base success time", base_success_value, root.GetAllocator());
    rapidjson::Value full_success_value;
    format_str = ToStringFromUnixMillis(_last_full_compaction_success_millis.load());
    full_success_value.SetString(format_str.c_str(), cast_set<uint>(format_str.length()),
                                 root.GetAllocator());
    root.AddMember("last full success time", full_success_value, root.GetAllocator());
    rapidjson::Value cumu_schedule_value;
    format_str = ToStringFromUnixMillis(_last_cumu_compaction_schedule_millis.load());
    cumu_schedule_value.SetString(format_str.c_str(), cast_set<uint>(format_str.length()),
                                  root.GetAllocator());
    root.AddMember("last cumulative schedule time", cumu_schedule_value, root.GetAllocator());
    rapidjson::Value base_schedule_value;
    format_str = ToStringFromUnixMillis(_last_base_compaction_schedule_millis.load());
    base_schedule_value.SetString(format_str.c_str(), cast_set<uint>(format_str.length()),
                                  root.GetAllocator());
    root.AddMember("last base schedule time", base_schedule_value, root.GetAllocator());
    rapidjson::Value full_schedule_value;
    format_str = ToStringFromUnixMillis(_last_full_compaction_schedule_millis.load());
    full_schedule_value.SetString(format_str.c_str(), cast_set<uint>(format_str.length()),
                                  root.GetAllocator());
    root.AddMember("last full schedule time", full_schedule_value, root.GetAllocator());
    rapidjson::Value cumu_compaction_status_value;
    cumu_compaction_status_value.SetString(_last_cumu_compaction_status.c_str(),
                                           cast_set<uint>(_last_cumu_compaction_status.length()),
                                           root.GetAllocator());
    root.AddMember("last cumulative status", cumu_compaction_status_value, root.GetAllocator());
    rapidjson::Value base_compaction_status_value;
    base_compaction_status_value.SetString(_last_base_compaction_status.c_str(),
                                           cast_set<uint>(_last_base_compaction_status.length()),
                                           root.GetAllocator());
    root.AddMember("last base status", base_compaction_status_value, root.GetAllocator());
    rapidjson::Value full_compaction_status_value;
    full_compaction_status_value.SetString(_last_full_compaction_status.c_str(),
                                           cast_set<uint>(_last_full_compaction_status.length()),
                                           root.GetAllocator());
    root.AddMember("last full status", full_compaction_status_value, root.GetAllocator());
    rapidjson::Value exec_compaction_time;
    std::string num_str {std::to_string(exec_compaction_time_us.load())};
    exec_compaction_time.SetString(num_str.c_str(), cast_set<uint>(num_str.length()),
                                   root.GetAllocator());
    root.AddMember("exec compaction time us", exec_compaction_time, root.GetAllocator());
    rapidjson::Value local_read_time;
    num_str = std::to_string(local_read_time_us.load());
    local_read_time.SetString(num_str.c_str(), cast_set<uint>(num_str.length()),
                              root.GetAllocator());
    root.AddMember("compaction local read time us", local_read_time, root.GetAllocator());
    rapidjson::Value remote_read_time;
    num_str = std::to_string(remote_read_time_us.load());
    remote_read_time.SetString(num_str.c_str(), cast_set<uint>(num_str.length()),
                               root.GetAllocator());
    root.AddMember("compaction remote read time us", remote_read_time, root.GetAllocator());

    // print all rowsets' version as an array
    rapidjson::Document versions_arr;
    rapidjson::Document missing_versions_arr;
    versions_arr.SetArray();
    missing_versions_arr.SetArray();
    int64_t last_version = -1;
    for (auto& rowset : rowsets) {
        const Version& ver = rowset->version();
        if (ver.first != last_version + 1) {
            rapidjson::Value miss_value;
            miss_value.SetString(fmt::format("[{}-{}]", last_version + 1, ver.first - 1).c_str(),
                                 missing_versions_arr.GetAllocator());
            missing_versions_arr.PushBack(miss_value, missing_versions_arr.GetAllocator());
        }
        rapidjson::Value value;
        std::string version_str = rowset->get_rowset_info_str();
        value.SetString(version_str.c_str(), cast_set<uint32_t>(version_str.length()),
                        versions_arr.GetAllocator());
        versions_arr.PushBack(value, versions_arr.GetAllocator());
        last_version = ver.second;
    }
    root.AddMember("rowsets", versions_arr, root.GetAllocator());
    root.AddMember("missing_rowsets", missing_versions_arr, root.GetAllocator());

    // print all stale rowsets' version as an array
    rapidjson::Document stale_versions_arr;
    stale_versions_arr.SetArray();
    for (auto& rowset : stale_rowsets) {
        rapidjson::Value value;
        std::string version_str = rowset->get_rowset_info_str();
        value.SetString(version_str.c_str(), cast_set<uint32_t>(version_str.length()),
                        stale_versions_arr.GetAllocator());
        stale_versions_arr.PushBack(value, stale_versions_arr.GetAllocator());
    }
    root.AddMember("stale_rowsets", stale_versions_arr, root.GetAllocator());

    // add stale version rowsets
    root.AddMember("stale version path", path_arr, root.GetAllocator());

    // to json string
    rapidjson::StringBuffer strbuf;
    rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(strbuf);
    root.Accept(writer);
    *json_result = std::string(strbuf.GetString());
}

void CloudTablet::set_cumulative_layer_point(int64_t new_point) {
    if (new_point == Tablet::K_INVALID_CUMULATIVE_POINT || new_point >= _cumulative_point) {
        _cumulative_point = new_point;
        return;
    }
    // cumulative point should only be reset to -1, or be increased
    // FIXME: could happen in currently unresolved race conditions
    LOG(WARNING) << "Unexpected cumulative point: " << new_point
                 << ", origin: " << _cumulative_point.load();
}

Status CloudTablet::check_rowset_schema_for_build_index(std::vector<TColumn>& columns,
                                                        int schema_version) {
    std::map<std::string, TabletColumn> fe_col_map;
    for (int i = 0; i < columns.size(); i++) {
        fe_col_map[columns[i].column_name] = TabletColumn(columns[i]);
    }

    std::shared_lock rlock(_meta_lock);
    for (const auto& [version, rs] : _rs_version_map) {
        if (version.first == 0) {
            continue;
        }

        if (rs->tablet_schema()->schema_version() >= schema_version) {
            continue;
        }

        for (auto rs_col : rs->tablet_schema()->columns()) {
            auto find_ret = fe_col_map.find(rs_col->name());
            if (find_ret == fe_col_map.end()) {
                return Status::InternalError(
                        "check rowset meta failed:rowset's col is dropped in FE.");
            }

            if (rs_col->unique_id() != find_ret->second.unique_id()) {
                return Status::InternalError("check rowset meta failed:col id not match.");
            }

            if (rs_col->type() != find_ret->second.type()) {
                return Status::InternalError("check rowset meta failed:col type not match.");
            }
        }
    }

    return Status::OK();
}

Result<RowsetSharedPtr> CloudTablet::pick_a_rowset_for_index_change(int schema_version,
                                                                    bool& is_base_rowset) {
    TEST_SYNC_POINT_RETURN_WITH_VALUE("CloudTablet::pick_a_rowset_for_index_change",
                                      Result<RowsetSharedPtr>(nullptr));
    RowsetSharedPtr ret_rowset = nullptr;
    std::shared_lock rlock(_meta_lock);
    for (const auto& [version, rs] : _rs_version_map) {
        if (version.first == 0) {
            continue;
        }
        if (rs->num_rows() == 0) {
            VLOG_DEBUG << "[index_change]find empty rs, index change may "
                          "failed, id="
                       << rs->rowset_id().to_string();
        }

        if (rs->tablet_schema()->schema_version() >= schema_version) {
            VLOG_DEBUG << "[index_change] skip rowset " << rs->tablet_schema()->schema_version()
                       << "," << schema_version;
            continue;
        }

        if (ret_rowset == nullptr) {
            ret_rowset = rs;
            continue;
        }

        if (rs->start_version() > ret_rowset->start_version()) {
            ret_rowset = rs;
        }
    }

    if (ret_rowset != nullptr) {
        is_base_rowset = ret_rowset->version().first < _cumulative_point;
    }

    return ret_rowset;
}

std::vector<RowsetSharedPtr> CloudTablet::pick_candidate_rowsets_to_base_compaction() {
    std::vector<RowsetSharedPtr> candidate_rowsets;
    {
        std::shared_lock rlock(_meta_lock);
        for (const auto& [version, rs] : _rs_version_map) {
            if (version.first != 0 && version.first < _cumulative_point &&
                (_alter_version == -1 || version.second <= _alter_version)) {
                candidate_rowsets.push_back(rs);
            }
        }
    }
    std::sort(candidate_rowsets.begin(), candidate_rowsets.end(), Rowset::comparator);
    return candidate_rowsets;
}

std::vector<RowsetSharedPtr> CloudTablet::pick_candidate_rowsets_to_full_compaction() {
    std::vector<RowsetSharedPtr> candidate_rowsets;
    {
        std::shared_lock rlock(_meta_lock);
        for (auto& [v, rs] : _rs_version_map) {
            // MUST NOT compact rowset [0-1] for some historical reasons (see cloud_schema_change)
            if (v.first != 0) {
                candidate_rowsets.push_back(rs);
            }
        }
    }
    std::sort(candidate_rowsets.begin(), candidate_rowsets.end(), Rowset::comparator);
    return candidate_rowsets;
}

CalcDeleteBitmapExecutor* CloudTablet::calc_delete_bitmap_executor() {
    return _engine.calc_delete_bitmap_executor();
}

Status CloudTablet::save_delete_bitmap(const TabletTxnInfo* txn_info, int64_t txn_id,
                                       DeleteBitmapPtr delete_bitmap, RowsetWriter* rowset_writer,
                                       const RowsetIdUnorderedSet& cur_rowset_ids, int64_t lock_id,
                                       int64_t next_visible_version) {
    RowsetSharedPtr rowset = txn_info->rowset;
    int64_t cur_version = rowset->start_version();
    // update delete bitmap info, in order to avoid recalculation when trying again
    RETURN_IF_ERROR(_engine.txn_delete_bitmap_cache().update_tablet_txn_info(
            txn_id, tablet_id(), delete_bitmap, cur_rowset_ids, PublishStatus::PREPARE));

    if (txn_info->partial_update_info && txn_info->partial_update_info->is_partial_update() &&
        rowset_writer->num_rows() > 0) {
        DBUG_EXECUTE_IF("CloudTablet::save_delete_bitmap.update_tmp_rowset.error", {
            return Status::InternalError<false>("injected update_tmp_rowset error.");
        });
        const auto& rowset_meta = rowset->rowset_meta();
        RETURN_IF_ERROR(_engine.meta_mgr().update_tmp_rowset(*rowset_meta));
    }

    RETURN_IF_ERROR(save_delete_bitmap_to_ms(cur_version, txn_id, delete_bitmap, lock_id,
                                             next_visible_version, rowset));

    // store the delete bitmap with sentinel marks in txn_delete_bitmap_cache because if the txn is retried for some reason,
    // it will use the delete bitmap from txn_delete_bitmap_cache when re-calculating the delete bitmap, during which it will do
    // delete bitmap correctness check. If we store the new_delete_bitmap, the delete bitmap correctness check will fail
    RETURN_IF_ERROR(_engine.txn_delete_bitmap_cache().update_tablet_txn_info(
            txn_id, tablet_id(), delete_bitmap, cur_rowset_ids, PublishStatus::SUCCEED,
            txn_info->publish_info));

    DBUG_EXECUTE_IF("CloudTablet::save_delete_bitmap.enable_sleep", {
        auto sleep_sec = dp->param<int>("sleep", 5);
        std::this_thread::sleep_for(std::chrono::seconds(sleep_sec));
    });

    DBUG_EXECUTE_IF("CloudTablet::save_delete_bitmap.injected_error", {
        auto retry = dp->param<bool>("retry", false);
        auto sleep_sec = dp->param<int>("sleep", 0);
        std::this_thread::sleep_for(std::chrono::seconds(sleep_sec));
        if (retry) { // return DELETE_BITMAP_LOCK_ERROR to let it retry
            return Status::Error<ErrorCode::DELETE_BITMAP_LOCK_ERROR>(
                    "injected DELETE_BITMAP_LOCK_ERROR");
        } else {
            return Status::InternalError<false>("injected non-retryable error");
        }
    });

    return Status::OK();
}

Status CloudTablet::save_delete_bitmap_to_ms(int64_t cur_version, int64_t txn_id,
                                             DeleteBitmapPtr delete_bitmap, int64_t lock_id,
                                             int64_t next_visible_version, RowsetSharedPtr rowset) {
    DeleteBitmapPtr new_delete_bitmap = std::make_shared<DeleteBitmap>(tablet_id());
    for (auto iter = delete_bitmap->delete_bitmap.begin();
         iter != delete_bitmap->delete_bitmap.end(); ++iter) {
        // skip sentinel mark, which is used for delete bitmap correctness check
        if (std::get<1>(iter->first) != DeleteBitmap::INVALID_SEGMENT_ID) {
            new_delete_bitmap->merge(
                    {std::get<0>(iter->first), std::get<1>(iter->first), cur_version},
                    iter->second);
        }
    }
    // lock_id != -1 means this is in an explict txn
    bool is_explicit_txn = (lock_id != -1);
    auto ms_lock_id = !is_explicit_txn ? txn_id : lock_id;
    std::optional<StorageResource> storage_resource;
    auto storage_resource_result = rowset->rowset_meta()->remote_storage_resource();
    if (storage_resource_result) {
        storage_resource = *storage_resource_result.value();
    }
    RETURN_IF_ERROR(_engine.meta_mgr().update_delete_bitmap(
            *this, ms_lock_id, LOAD_INITIATOR_ID, new_delete_bitmap.get(), new_delete_bitmap.get(),
            rowset->rowset_id().to_string(), storage_resource,
            config::delete_bitmap_store_write_version, txn_id, is_explicit_txn,
            next_visible_version));
    return Status::OK();
}

Versions CloudTablet::calc_missed_versions(int64_t spec_version, Versions existing_versions) const {
    DCHECK(spec_version > 0) << "invalid spec_version: " << spec_version;

    // sort the existing versions in ascending order
    std::sort(existing_versions.begin(), existing_versions.end(),
              [](const Version& a, const Version& b) {
                  // simple because 2 versions are certainly not overlapping
                  return a.first < b.first;
              });

    // From the first version(=0), find the missing version until spec_version
    int64_t last_version = -1;
    Versions missed_versions;
    for (const Version& version : existing_versions) {
        if (version.first > last_version + 1) {
            // there is a hole between versions
            missed_versions.emplace_back(last_version + 1, std::min(version.first, spec_version));
        }
        last_version = version.second;
        if (last_version >= spec_version) {
            break;
        }
    }
    if (last_version < spec_version) {
        // there is a hole between the last version and the specificed version.
        missed_versions.emplace_back(last_version + 1, spec_version);
    }
    return missed_versions;
}

Status CloudTablet::calc_delete_bitmap_for_compaction(
        const std::vector<RowsetSharedPtr>& input_rowsets, const RowsetSharedPtr& output_rowset,
        const RowIdConversion& rowid_conversion, ReaderType compaction_type, int64_t merged_rows,
        int64_t filtered_rows, int64_t initiator, DeleteBitmapPtr& output_rowset_delete_bitmap,
        bool allow_delete_in_cumu_compaction, int64_t& get_delete_bitmap_lock_start_time) {
    output_rowset_delete_bitmap = std::make_shared<DeleteBitmap>(tablet_id());
    std::unique_ptr<RowLocationSet> missed_rows;
    if ((config::enable_missing_rows_correctness_check ||
         config::enable_mow_compaction_correctness_check_core ||
         config::enable_mow_compaction_correctness_check_fail) &&
        !allow_delete_in_cumu_compaction &&
        (compaction_type == ReaderType::READER_CUMULATIVE_COMPACTION ||
         !config::enable_prune_delete_sign_when_base_compaction)) {
        // also check duplicate key for base compaction when config::enable_prune_delete_sign_when_base_compaction==false
        missed_rows = std::make_unique<RowLocationSet>();
        LOG(INFO) << "RowLocation Set inited succ for tablet:" << tablet_id();
    }

    std::unique_ptr<std::map<RowsetSharedPtr, RowLocationPairList>> location_map;
    if (config::enable_rowid_conversion_correctness_check &&
        tablet_schema()->cluster_key_uids().empty()) {
        location_map = std::make_unique<std::map<RowsetSharedPtr, RowLocationPairList>>();
        LOG(INFO) << "Location Map inited succ for tablet:" << tablet_id();
    }

    // 1. calc delete bitmap for historical data
    RETURN_IF_ERROR(_engine.meta_mgr().sync_tablet_rowsets(this));
    Version version = max_version();
    std::size_t missed_rows_size = 0;
    calc_compaction_output_rowset_delete_bitmap(
            input_rowsets, rowid_conversion, 0, version.second + 1, missed_rows.get(),
            location_map.get(), tablet_meta()->delete_bitmap(), output_rowset_delete_bitmap.get());
    if (missed_rows) {
        missed_rows_size = missed_rows->size();
        if (!allow_delete_in_cumu_compaction) {
            if ((compaction_type == ReaderType::READER_CUMULATIVE_COMPACTION ||
                 !config::enable_prune_delete_sign_when_base_compaction) &&
                tablet_state() == TABLET_RUNNING) {
                if (merged_rows + filtered_rows >= 0 &&
                    merged_rows + filtered_rows != missed_rows_size) {
                    std::string err_msg = fmt::format(
                            "cumulative compaction: the merged rows({}), the filtered rows({}) is "
                            "not equal to missed rows({}) in rowid conversion, tablet_id: {}, "
                            "table_id:{}",
                            merged_rows, filtered_rows, missed_rows_size, tablet_id(), table_id());
                    LOG(WARNING) << err_msg;
                    if (config::enable_mow_compaction_correctness_check_core) {
                        CHECK(false) << err_msg;
                    } else if (config::enable_mow_compaction_correctness_check_fail) {
                        return Status::InternalError<false>(err_msg);
                    } else {
                        DCHECK(false) << err_msg;
                    }
                }
            }
        }
    }
    if (location_map) {
        RETURN_IF_ERROR(check_rowid_conversion(output_rowset, *location_map));
        location_map->clear();
    }

    // 2. calc delete bitmap for incremental data
    int64_t t1 = MonotonicMicros();
    RETURN_IF_ERROR(_engine.meta_mgr().get_delete_bitmap_update_lock(
            *this, COMPACTION_DELETE_BITMAP_LOCK_ID, initiator));
    int64_t t2 = MonotonicMicros();
    if (compaction_type == ReaderType::READER_CUMULATIVE_COMPACTION) {
        g_cu_compaction_get_delete_bitmap_lock_time_ms << (t2 - t1) / 1000;
    } else if (compaction_type == ReaderType::READER_BASE_COMPACTION) {
        g_base_compaction_get_delete_bitmap_lock_time_ms << (t2 - t1) / 1000;
    }
    get_delete_bitmap_lock_start_time = t2;
    RETURN_IF_ERROR(_engine.meta_mgr().sync_tablet_rowsets(this));
    int64_t t3 = MonotonicMicros();

    calc_compaction_output_rowset_delete_bitmap(
            input_rowsets, rowid_conversion, version.second, UINT64_MAX, missed_rows.get(),
            location_map.get(), tablet_meta()->delete_bitmap(), output_rowset_delete_bitmap.get());
    int64_t t4 = MonotonicMicros();
    if (location_map) {
        RETURN_IF_ERROR(check_rowid_conversion(output_rowset, *location_map));
    }
    int64_t t5 = MonotonicMicros();

    // 3. store delete bitmap
    DeleteBitmapPtr delete_bitmap_v2 = nullptr;
    auto delete_bitmap_size = output_rowset_delete_bitmap->delete_bitmap.size();
    auto store_version = config::delete_bitmap_store_write_version;
    if (store_version == 2 || store_version == 3) {
        delete_bitmap_v2 = std::make_shared<DeleteBitmap>(*output_rowset_delete_bitmap);
        std::vector<std::pair<RowsetId, int64_t>> retained_rowsets_to_seg_num;
        {
            std::shared_lock rlock(get_header_lock());
            for (const auto& [rowset_version, rowset_ptr] : rowset_map()) {
                if (rowset_version.second < output_rowset->start_version()) {
                    retained_rowsets_to_seg_num.emplace_back(
                            std::make_pair(rowset_ptr->rowset_id(), rowset_ptr->num_segments()));
                }
            }
        }
        if (config::enable_agg_delta_delete_bitmap_for_store_v2) {
            tablet_meta()->delete_bitmap().subset_and_agg(
                    retained_rowsets_to_seg_num, output_rowset->start_version(),
                    output_rowset->end_version(), delete_bitmap_v2.get());
        } else {
            tablet_meta()->delete_bitmap().subset(
                    retained_rowsets_to_seg_num, output_rowset->start_version(),
                    output_rowset->end_version(), delete_bitmap_v2.get());
        }
    }
    std::optional<StorageResource> storage_resource;
    auto storage_resource_result = output_rowset->rowset_meta()->remote_storage_resource();
    if (storage_resource_result) {
        storage_resource = *storage_resource_result.value();
    }
    auto st = _engine.meta_mgr().update_delete_bitmap(
            *this, -1, initiator, output_rowset_delete_bitmap.get(), delete_bitmap_v2.get(),
            output_rowset->rowset_id().to_string(), storage_resource, store_version);
    int64_t t6 = MonotonicMicros();
    LOG(INFO) << "calc_delete_bitmap_for_compaction, tablet_id=" << tablet_id()
              << ", get lock cost " << (t2 - t1) << " us, sync rowsets cost " << (t3 - t2)
              << " us, calc delete bitmap cost " << (t4 - t3) << " us, check rowid conversion cost "
              << (t5 - t4) << " us, store delete bitmap cost " << (t6 - t5)
              << " us, st=" << st.to_string() << ". store_version=" << store_version
              << ", calculated delete bitmap size=" << delete_bitmap_size
              << ", update delete bitmap size="
              << output_rowset_delete_bitmap->delete_bitmap.size();
    return st;
}

void CloudTablet::agg_delete_bitmap_for_compaction(
        int64_t start_version, int64_t end_version, const std::vector<RowsetSharedPtr>& pre_rowsets,
        DeleteBitmapPtr& new_delete_bitmap,
        std::map<std::string, int64_t>& pre_rowset_to_versions) {
    for (auto& rowset : pre_rowsets) {
        for (uint32_t seg_id = 0; seg_id < rowset->num_segments(); ++seg_id) {
            auto d = tablet_meta()->delete_bitmap().get_agg_without_cache(
                    {rowset->rowset_id(), seg_id, end_version}, start_version);
            if (d->isEmpty()) {
                continue;
            }
            VLOG_DEBUG << "agg delete bitmap for tablet_id=" << tablet_id()
                       << ", rowset_id=" << rowset->rowset_id() << ", seg_id=" << seg_id
                       << ", rowset_version=" << rowset->version().to_string()
                       << ". compaction start_version=" << start_version
                       << ", end_version=" << end_version
                       << ". delete_bitmap cardinality=" << d->cardinality();
            DeleteBitmap::BitmapKey end_key {rowset->rowset_id(), seg_id, end_version};
            new_delete_bitmap->set(end_key, *d);
            pre_rowset_to_versions[rowset->rowset_id().to_string()] = rowset->version().second;
        }
    }
}

Status CloudTablet::sync_meta() {
    if (!config::enable_file_cache) {
        return Status::OK();
    }

    TabletMetaSharedPtr tablet_meta;
    auto st = _engine.meta_mgr().get_tablet_meta(tablet_id(), &tablet_meta);
    if (!st.ok()) {
        if (st.is<ErrorCode::NOT_FOUND>()) {
            clear_cache();
        }
        return st;
    }

    auto new_compaction_policy = tablet_meta->compaction_policy();
    if (_tablet_meta->compaction_policy() != new_compaction_policy) {
        _tablet_meta->set_compaction_policy(new_compaction_policy);
    }
    auto new_time_series_compaction_goal_size_mbytes =
            tablet_meta->time_series_compaction_goal_size_mbytes();
    if (_tablet_meta->time_series_compaction_goal_size_mbytes() !=
        new_time_series_compaction_goal_size_mbytes) {
        _tablet_meta->set_time_series_compaction_goal_size_mbytes(
                new_time_series_compaction_goal_size_mbytes);
    }
    auto new_time_series_compaction_file_count_threshold =
            tablet_meta->time_series_compaction_file_count_threshold();
    if (_tablet_meta->time_series_compaction_file_count_threshold() !=
        new_time_series_compaction_file_count_threshold) {
        _tablet_meta->set_time_series_compaction_file_count_threshold(
                new_time_series_compaction_file_count_threshold);
    }
    auto new_time_series_compaction_time_threshold_seconds =
            tablet_meta->time_series_compaction_time_threshold_seconds();
    if (_tablet_meta->time_series_compaction_time_threshold_seconds() !=
        new_time_series_compaction_time_threshold_seconds) {
        _tablet_meta->set_time_series_compaction_time_threshold_seconds(
                new_time_series_compaction_time_threshold_seconds);
    }
    auto new_time_series_compaction_empty_rowsets_threshold =
            tablet_meta->time_series_compaction_empty_rowsets_threshold();
    if (_tablet_meta->time_series_compaction_empty_rowsets_threshold() !=
        new_time_series_compaction_empty_rowsets_threshold) {
        _tablet_meta->set_time_series_compaction_empty_rowsets_threshold(
                new_time_series_compaction_empty_rowsets_threshold);
    }
    auto new_time_series_compaction_level_threshold =
            tablet_meta->time_series_compaction_level_threshold();
    if (_tablet_meta->time_series_compaction_level_threshold() !=
        new_time_series_compaction_level_threshold) {
        _tablet_meta->set_time_series_compaction_level_threshold(
                new_time_series_compaction_level_threshold);
    }
    // Sync disable_auto_compaction (stored in tablet_schema)
    auto new_disable_auto_compaction = tablet_meta->tablet_schema()->disable_auto_compaction();
    if (_tablet_meta->tablet_schema()->disable_auto_compaction() != new_disable_auto_compaction) {
        _tablet_meta->mutable_tablet_schema()->set_disable_auto_compaction(
                new_disable_auto_compaction);
    }
    // Sync vertical_compaction_num_columns_per_group
    auto new_vertical_compaction_num_columns_per_group =
            tablet_meta->vertical_compaction_num_columns_per_group();
    if (_tablet_meta->vertical_compaction_num_columns_per_group() !=
        new_vertical_compaction_num_columns_per_group) {
        _tablet_meta->set_vertical_compaction_num_columns_per_group(
                new_vertical_compaction_num_columns_per_group);
    }

    return Status::OK();
}

void CloudTablet::build_tablet_report_info(TTabletInfo* tablet_info) {
    std::shared_lock rdlock(_meta_lock);
    tablet_info->__set_total_version_count(_tablet_meta->version_count());
    tablet_info->__set_tablet_id(_tablet_meta->tablet_id());
    // Currently, this information will not be used by the cloud report,
    // but it may be used in the future.
}

Status CloudTablet::check_delete_bitmap_cache(int64_t txn_id,
                                              DeleteBitmap* expected_delete_bitmap) {
    DeleteBitmapPtr cached_delete_bitmap;
    CloudStorageEngine& engine = ExecEnv::GetInstance()->storage_engine().to_cloud();
    Status st = engine.txn_delete_bitmap_cache().get_delete_bitmap(
            txn_id, tablet_id(), &cached_delete_bitmap, nullptr, nullptr);
    if (st.ok()) {
        bool res = (expected_delete_bitmap->cardinality() == cached_delete_bitmap->cardinality());
        auto msg = fmt::format(
                "delete bitmap cache check failed, cur_cardinality={}, cached_cardinality={}"
                "txn_id={}, tablet_id={}",
                expected_delete_bitmap->cardinality(), cached_delete_bitmap->cardinality(), txn_id,
                tablet_id());
        if (!res) {
            DCHECK(res) << msg;
            return Status::InternalError<false>(msg);
        }
    }
    return Status::OK();
}

WarmUpState CloudTablet::get_rowset_warmup_state(RowsetId rowset_id) {
    std::shared_lock rlock(_meta_lock);
    if (!_rowset_warm_up_states.contains(rowset_id)) {
        return {.trigger_source = WarmUpTriggerSource::NONE, .progress = WarmUpProgress::NONE};
    }
    auto& warmup_info = _rowset_warm_up_states[rowset_id];
    warmup_info.update_state();
    return warmup_info.state;
}

bool CloudTablet::add_rowset_warmup_state(const RowsetMeta& rowset, WarmUpTriggerSource source,
                                          std::chrono::steady_clock::time_point start_tp) {
    std::lock_guard wlock(_meta_lock);
    return add_rowset_warmup_state_unlocked(rowset, source, start_tp);
}

bool CloudTablet::update_rowset_warmup_state_inverted_idx_num(WarmUpTriggerSource source,
                                                              RowsetId rowset_id, int64_t delta) {
    std::lock_guard wlock(_meta_lock);
    return update_rowset_warmup_state_inverted_idx_num_unlocked(source, rowset_id, delta);
}

bool CloudTablet::update_rowset_warmup_state_inverted_idx_num_unlocked(WarmUpTriggerSource source,
                                                                       RowsetId rowset_id,
                                                                       int64_t delta) {
    auto it = _rowset_warm_up_states.find(rowset_id);
    if (it == _rowset_warm_up_states.end()) {
        return false;
    }
    if (it->second.state.trigger_source != source) {
        // Only the same trigger source can update the state
        return false;
    }
    it->second.num_inverted_idx += delta;
    return true;
}

bool CloudTablet::add_rowset_warmup_state_unlocked(const RowsetMeta& rowset,
                                                   WarmUpTriggerSource source,
                                                   std::chrono::steady_clock::time_point start_tp) {
    auto rowset_id = rowset.rowset_id();

    // Check if rowset already has warmup state
    if (_rowset_warm_up_states.contains(rowset_id)) {
        auto existing_state = _rowset_warm_up_states[rowset_id].state;

        // For job-triggered warmup (one-time and periodic warmup), allow it to proceed
        // except when there's already another job-triggered warmup in progress
        if (source == WarmUpTriggerSource::JOB) {
            if (existing_state.trigger_source == WarmUpTriggerSource::JOB &&
                existing_state.progress == WarmUpProgress::DOING) {
                // Same job type already in progress, skip to avoid duplicate warmup
                return false;
            }
        } else {
            // For non-job warmup (EVENT_DRIVEN, SYNC_ROWSET), skip if any warmup exists
            return false;
        }
    }

    if (source == WarmUpTriggerSource::JOB) {
        g_file_cache_warm_up_rowset_triggered_by_job_num << 1;
    } else if (source == WarmUpTriggerSource::SYNC_ROWSET) {
        g_file_cache_warm_up_rowset_triggered_by_sync_rowset_num << 1;
    } else if (source == WarmUpTriggerSource::EVENT_DRIVEN) {
        g_file_cache_warm_up_rowset_triggered_by_event_driven_num << 1;
    }
    _rowset_warm_up_states[rowset_id] = {
            .state = {.trigger_source = source,
                      .progress = (rowset.num_segments() == 0 ? WarmUpProgress::DONE
                                                              : WarmUpProgress::DOING)},
            .num_segments = rowset.num_segments(),
            .start_tp = start_tp};
    return true;
}

void CloudTablet::RowsetWarmUpInfo::update_state() {
    if (has_finished()) {
        g_file_cache_warm_up_rowset_complete_num << 1;
        auto cost = std::chrono::duration_cast<std::chrono::milliseconds>(
                            std::chrono::steady_clock::now() - start_tp)
                            .count();
        g_file_cache_warm_up_rowset_all_segments_latency << cost;
        state.progress = WarmUpProgress::DONE;
    }
}

WarmUpState CloudTablet::complete_rowset_segment_warmup(WarmUpTriggerSource trigger_source,
                                                        RowsetId rowset_id, Status status,
                                                        int64_t segment_num,
                                                        int64_t inverted_idx_num) {
    std::lock_guard wlock(_meta_lock);
    auto it = _rowset_warm_up_states.find(rowset_id);
    if (it == _rowset_warm_up_states.end()) {
        return {.trigger_source = WarmUpTriggerSource::NONE, .progress = WarmUpProgress::NONE};
    }
    auto& warmup_info = it->second;
    if (warmup_info.state.trigger_source != trigger_source) {
        // Only the same trigger source can update the state
        return warmup_info.state;
    }
    VLOG_DEBUG << "complete rowset segment warmup for rowset " << rowset_id << ", " << status;
    if (segment_num > 0) {
        g_file_cache_warm_up_segment_complete_num << segment_num;
        if (!status.ok()) {
            g_file_cache_warm_up_segment_failed_num << segment_num;
        }
    }
    if (inverted_idx_num > 0) {
        g_file_cache_warm_up_inverted_idx_complete_num << inverted_idx_num;
        if (!status.ok()) {
            g_file_cache_warm_up_inverted_idx_failed_num << inverted_idx_num;
        }
    }
    warmup_info.done(segment_num, inverted_idx_num);
    return warmup_info.state;
}

bool CloudTablet::is_rowset_warmed_up(const RowsetId& rowset_id) const {
    auto it = _rowset_warm_up_states.find(rowset_id);
    if (it == _rowset_warm_up_states.end()) {
        // The rowset is not in warmup state, which means the rowset has never been warmed up.
        // This may happen when the upstream BE tried to warm up rowsets on this BE but this BE
        // was restarting so the warmup failed, and _rowset_warm_up_states has no entry for it.
        //
        // Normally the startup_timepoint check in rowset_is_warmed_up_unlocked() would filter out
        // such rowsets (visible_timestamp < startup_timepoint → assumed warmed up). However,
        // compaction-produced rowsets have their visible_timestamp set at rowset builder
        // initialization time rather than the final transaction commit time on meta-service,
        // so their visible_timestamp can be earlier than startup_timepoint, causing the
        // startup_timepoint check to NOT filter them out and reaching here with no warmup entry.
        //
        // If such a rowset is before the cumulative compaction point and base compaction never
        // happens, returning false here would cause the version path algorithm to exclude it,
        // leading to a persistently low path_max_version. With continuous upstream ingestion,
        // the freshness tolerance fallback check would keep triggering, making every query on
        // this tablet fall back to reading all data from remote storage.
        //
        // Returning true (optimistically treating it as warmed up) allows the version path to
        // include it. On cache miss the data is transparently read from remote storage per-segment
        // and cached locally in 1MB blocks, so the problem self-heals through subsequent queries.
        g_rowset_warmup_state_missing_count << 1;
        LOG_EVERY_N(WARNING, 100) << fmt::format(
                "rowset warmup state missing, considering it as warmed up. tablet_id={}, "
                "rowset_id={}",
                tablet_id(), rowset_id.to_string());
        return true;
    }
    return it->second.state.progress == WarmUpProgress::DONE;
}

void CloudTablet::add_warmed_up_rowset(const RowsetId& rowset_id) {
    _rowset_warm_up_states[rowset_id] = {
            .state = {.trigger_source = WarmUpTriggerSource::SYNC_ROWSET,
                      .progress = WarmUpProgress::DONE},
            .num_segments = 1,
            .start_tp = std::chrono::steady_clock::now()};
}

void CloudTablet::add_not_warmed_up_rowset(const RowsetId& rowset_id) {
    _rowset_warm_up_states[rowset_id] = {
            .state = {.trigger_source = WarmUpTriggerSource::SYNC_ROWSET,
                      .progress = WarmUpProgress::DOING},
            .num_segments = 1,
            .start_tp = std::chrono::steady_clock::now()};
}

bool CloudTablet::_check_rowset_should_be_visible_but_not_warmed_up(
        const RowsetMetaSharedPtr& rs_meta, int64_t path_max_version,
        std::chrono::system_clock::time_point freshness_limit_tp) const {
    if (rs_meta->version() == Version {0, 1}) {
        // skip rowset[0-1]
        return false;
    }
    bool ret = rs_meta->start_version() > path_max_version &&
               rs_meta->visible_timestamp() < freshness_limit_tp;
    if (ret && config::read_cluster_cache_opt_verbose_log) {
        using namespace std::chrono;
        std::time_t t1 = system_clock::to_time_t(rs_meta->visible_timestamp());
        std::tm tm1 = *std::localtime(&t1);
        std::ostringstream oss1;
        oss1 << std::put_time(&tm1, "%Y-%m-%d %H:%M:%S");

        std::time_t t2 = system_clock::to_time_t(freshness_limit_tp);
        std::tm tm2 = *std::localtime(&t2);
        std::ostringstream oss2;
        oss2 << std::put_time(&tm2, "%Y-%m-%d %H:%M:%S");
        LOG_INFO(
                "[verbose] CloudTablet::capture_rs_readers_with_freshness_tolerance, "
                "find a rowset which should be visible but not warmed up, tablet_id={}, "
                "path_max_version={}, rowset_id={}, version={}, visible_time={}, "
                "freshness_limit={}, version_graph={}, rowset_warmup_digest={}",
                tablet_id(), path_max_version, rs_meta->rowset_id().to_string(),
                rs_meta->version().to_string(), oss1.str(), oss2.str(),
                _timestamped_version_tracker.debug_string(), rowset_warmup_digest());
    }
    return ret;
}

void CloudTablet::_submit_segment_download_task(const RowsetSharedPtr& rs,
                                                const StorageResource* storage_resource, int seg_id,

                                                int64_t expiration_time) {
    // clang-format off
    const auto& rowset_meta = rs->rowset_meta();
    auto self = std::dynamic_pointer_cast<CloudTablet>(shared_from_this());
    // Use rowset_meta->fs() instead of storage_resource->fs to support packed file.
    // RowsetMeta::fs() wraps the underlying FileSystem with PackedFileSystem when
    // packed_slice_locations is not empty, which correctly maps segment file paths
    // to their actual locations within packed files.
    auto file_system = rowset_meta->fs();
    if (!file_system) {
        LOG(WARNING) << "failed to get file system for tablet_id=" << _tablet_meta->tablet_id()
                     << ", rowset_id=" << rowset_meta->rowset_id();
        return;
    }
    _engine.file_cache_block_downloader().submit_download_task(io::DownloadFileMeta {
            .path = storage_resource->remote_segment_path(*rowset_meta, seg_id),
            .file_size = rs->rowset_meta()->segment_file_size(seg_id),
            .file_system = file_system,
            .ctx = {
                    .expiration_time = expiration_time,
                    .is_dryrun = config::enable_reader_dryrun_when_download_file_cache,
                    .is_warmup = true
            },
            .download_done {[=](Status st) {
                DBUG_EXECUTE_IF("CloudTablet::add_rowsets.download_data.callback.block_compaction_rowset", {
                            if (rs->version().second > rs->version().first) {
                                auto sleep_time = dp->param<int>("sleep", 3);
                                LOG_INFO(
                                        "[verbose] block download for rowset={}, "
                                        "version={}, sleep={}",
                                        rs->rowset_id().to_string(),
                                        rs->version().to_string(), sleep_time);
                                std::this_thread::sleep_for(
                                        std::chrono::seconds(sleep_time));
                            }
                });
                self->complete_rowset_segment_warmup(WarmUpTriggerSource::SYNC_ROWSET, rowset_meta->rowset_id(), st, 1, 0);
                if (!st) {
                    LOG_WARNING("add rowset warm up error ").error(st);
                }
            }},
    });
    // clang-format on
}

void CloudTablet::_submit_inverted_index_download_task(const RowsetSharedPtr& rs,
                                                       const StorageResource* storage_resource,
                                                       const io::Path& idx_path, int64_t idx_size,
                                                       int64_t expiration_time) {
    // clang-format off
    const auto& rowset_meta = rs->rowset_meta();
    auto self = std::dynamic_pointer_cast<CloudTablet>(shared_from_this());
    // Use rowset_meta->fs() instead of storage_resource->fs to support packed file for idx files.
    auto file_system = rowset_meta->fs();
    if (!file_system) {
        LOG(WARNING) << "failed to get file system for tablet_id=" << _tablet_meta->tablet_id()
                     << ", rowset_id=" << rowset_meta->rowset_id();
        return;
    }
    io::DownloadFileMeta meta {
            .path = idx_path,
            .file_size = idx_size,
            .file_system = file_system,
            .ctx = {
                    .expiration_time = expiration_time,
                    .is_dryrun = config::enable_reader_dryrun_when_download_file_cache,
                    .is_warmup = true
            },
            .download_done {[=](Status st) {
                DBUG_EXECUTE_IF("CloudTablet::add_rowsets.download_idx.callback.block", {
                    auto sleep_time = dp->param<int>("sleep", 3);
                    LOG_INFO(
                            "[verbose] block download for "
                            "rowset={}, inverted_idx_file={}, "
                            "sleep={}",
                            rs->rowset_id().to_string(), idx_path.string(), sleep_time);
                    std::this_thread::sleep_for(std::chrono::seconds(sleep_time));
                });
                self->complete_rowset_segment_warmup(WarmUpTriggerSource::SYNC_ROWSET, rowset_meta->rowset_id(), st, 0, 1);
                if (!st) {
                    LOG_WARNING("add rowset warm up error ").error(st);
                }
            }},
    };
    self->update_rowset_warmup_state_inverted_idx_num_unlocked(WarmUpTriggerSource::SYNC_ROWSET, rowset_meta->rowset_id(), 1);
    _engine.file_cache_block_downloader().submit_download_task(std::move(meta));
    g_file_cache_cloud_tablet_submitted_index_num << 1;
    g_file_cache_cloud_tablet_submitted_index_size << idx_size;
    // clang-format on
}

void CloudTablet::_add_rowsets_directly(std::vector<RowsetSharedPtr>& rowsets,
                                        bool warmup_delta_data) {
#ifdef BE_TEST
    warmup_delta_data = false;
#endif
    for (auto& rs : rowsets) {
        if (warmup_delta_data) {
            // Pre-set encryption algorithm to avoid re-entrant get_tablet() call
            // inside RowsetMeta::fs() which causes SingleFlight deadlock when the
            // tablet is not yet cached (during initial load_tablet).
            rs->rowset_meta()->set_encryption_algorithm(_tablet_meta->encryption_algorithm());
            bool warm_up_state_updated = false;
            // Warmup rowset data in background
            for (int seg_id = 0; seg_id < rs->num_segments(); ++seg_id) {
                const auto& rowset_meta = rs->rowset_meta();
                constexpr int64_t interval = 600; // 10 mins
                // When BE restart and receive the `load_sync` rpc, it will sync all historical rowsets first time.
                // So we need to filter out the old rowsets avoid to download the whole table.
                if (warmup_delta_data &&
                    ::time(nullptr) - rowset_meta->newest_write_timestamp() >= interval) {
                    continue;
                }

                auto storage_resource = rowset_meta->remote_storage_resource();
                if (!storage_resource) {
                    LOG(WARNING) << storage_resource.error();
                    continue;
                }

                int64_t expiration_time = _tablet_meta->ttl_seconds();
                g_file_cache_cloud_tablet_submitted_segment_num << 1;
                if (rs->rowset_meta()->segment_file_size(seg_id) > 0) {
                    g_file_cache_cloud_tablet_submitted_segment_size
                            << rs->rowset_meta()->segment_file_size(seg_id);
                }
                if (!warm_up_state_updated) {
                    VLOG_DEBUG << "warm up rowset " << rs->version() << "(" << rs->rowset_id()
                               << ") triggerd by sync rowset";
                    if (!add_rowset_warmup_state_unlocked(*(rs->rowset_meta()),
                                                          WarmUpTriggerSource::SYNC_ROWSET)) {
                        LOG(INFO) << "found duplicate warmup task for rowset " << rs->rowset_id()
                                  << ", skip it";
                        break;
                    }
                    warm_up_state_updated = true;
                }

                if (!config::file_cache_enable_only_warm_up_idx) {
                    _submit_segment_download_task(rs, storage_resource.value(), seg_id,
                                                  expiration_time);
                }

                auto schema_ptr = rowset_meta->tablet_schema();
                auto idx_version = schema_ptr->get_inverted_index_storage_format();
                if (idx_version == InvertedIndexStorageFormatPB::V1) {
                    std::unordered_map<int64_t, int64_t> index_size_map;
                    auto&& inverted_index_info = rowset_meta->inverted_index_file_info(seg_id);
                    for (const auto& info : inverted_index_info.index_info()) {
                        if (info.index_file_size() != -1) {
                            index_size_map[info.index_id()] = info.index_file_size();
                        } else {
                            VLOG_DEBUG << "Invalid index_file_size for segment_id " << seg_id
                                       << ", index_id " << info.index_id();
                        }
                    }
                    for (const auto& index : schema_ptr->inverted_indexes()) {
                        auto idx_path = storage_resource.value()->remote_idx_v1_path(
                                *rowset_meta, seg_id, index->index_id(), index->get_index_suffix());
                        _submit_inverted_index_download_task(rs, storage_resource.value(), idx_path,
                                                             index_size_map[index->index_id()],
                                                             expiration_time);
                    }
                } else {
                    if (schema_ptr->has_inverted_index() || schema_ptr->has_ann_index()) {
                        auto&& inverted_index_info = rowset_meta->inverted_index_file_info(seg_id);
                        int64_t idx_size = 0;
                        if (inverted_index_info.has_index_size()) {
                            idx_size = inverted_index_info.index_size();
                        } else {
                            VLOG_DEBUG << "index_size is not set for segment " << seg_id;
                        }
                        auto idx_path =
                                storage_resource.value()->remote_idx_v2_path(*rowset_meta, seg_id);
                        _submit_inverted_index_download_task(rs, storage_resource.value(), idx_path,
                                                             idx_size, expiration_time);
                    }
                }
            }
        }
        _rs_version_map.emplace(rs->version(), rs);
        _timestamped_version_tracker.add_version(rs->version());
        _max_version = std::max(rs->end_version(), _max_version);
        update_base_size(*rs);
    }
    _tablet_meta->add_rowsets_unchecked(rowsets);
}

void CloudTablet::clear_unused_visible_pending_rowsets() {
    int64_t cur_max_version = max_version().second;
    int32_t max_version_count = max_version_config();
    int64_t current_time = std::chrono::duration_cast<std::chrono::seconds>(
                                   std::chrono::system_clock::now().time_since_epoch())
                                   .count();

    std::unique_lock<std::mutex> wlock(_visible_pending_rs_lock);
    for (auto it = _visible_pending_rs_map.begin(); it != _visible_pending_rs_map.end();) {
        if (int64_t version = it->first, expiration_time = it->second.expiration_time;
            version <= cur_max_version || expiration_time < current_time) {
            it = _visible_pending_rs_map.erase(it);
        } else {
            ++it;
        }
    }

    while (!_visible_pending_rs_map.empty() && _visible_pending_rs_map.size() > max_version_count) {
        _visible_pending_rs_map.erase(--_visible_pending_rs_map.end());
    }
}

void CloudTablet::try_make_committed_rs_visible(int64_t txn_id, int64_t visible_version,
                                                int64_t version_update_time_ms) {
    if (enable_unique_key_merge_on_write()) {
        // for mow tablet, we get committed rowset from `CloudTxnDeleteBitmapCache` rather than `CommittedRowsetManager`
        try_make_committed_rs_visible_for_mow(txn_id, visible_version, version_update_time_ms);
        return;
    }

    auto& committed_rs_mgr = _engine.committed_rs_mgr();
    auto res = committed_rs_mgr.get_committed_rowset(txn_id, tablet_id());
    if (!res.has_value()) {
        return;
    }
    auto [rowset_meta, expiration_time] = res.value();
    bool is_empty_rowset = (rowset_meta == nullptr);
    if (!is_empty_rowset) {
        rowset_meta->set_cloud_fields_after_visible(visible_version, version_update_time_ms);
    }
    {
        std::lock_guard<std::mutex> lock(_visible_pending_rs_lock);
        _visible_pending_rs_map.emplace(
                visible_version,
                VisiblePendingRowset {rowset_meta, expiration_time, is_empty_rowset});
    }
    apply_visible_pending_rowsets();
    committed_rs_mgr.remove_committed_rowset(txn_id, tablet_id());
}

void CloudTablet::try_make_committed_rs_visible_for_mow(int64_t txn_id, int64_t visible_version,
                                                        int64_t version_update_time_ms) {
    Defer defer {[&] {
        _engine.txn_delete_bitmap_cache().remove_unused_tablet_txn_info(txn_id, tablet_id());
    }};
    auto res = _engine.txn_delete_bitmap_cache().get_rowset_and_delete_bitmap(txn_id, tablet_id());
    if (!res.has_value()) {
        return;
    }
    auto [rowset, delete_bitmap] = res.value();
    bool is_empty_rowset = (rowset == nullptr);
    {
        std::unique_lock lock {_sync_meta_lock};
        std::unique_lock meta_wlock {_meta_lock};
        if (_max_version + 1 != visible_version) {
            return;
        }
        if (is_empty_rowset) {
            Versions existing_versions;
            for (const auto& [_, rs] : tablet_meta()->all_rs_metas()) {
                existing_versions.emplace_back(rs->version());
            }
            if (existing_versions.empty()) {
                return;
            }
            auto max_version = std::ranges::max(existing_versions, {}, &Version::first);
            auto prev_rowset = get_rowset_by_version(max_version);
            auto st = _engine.meta_mgr().create_empty_rowset_for_hole(
                    this, visible_version, prev_rowset->rowset_meta(), &rowset);
            if (!st.ok()) {
                return;
            }
        } else {
            for (const auto& [delete_bitmap_key, bitmap_value] : delete_bitmap->delete_bitmap) {
                // skip sentinel mark, which is used for delete bitmap correctness check
                if (std::get<1>(delete_bitmap_key) != DeleteBitmap::INVALID_SEGMENT_ID) {
                    tablet_meta()->delete_bitmap().merge(
                            {std::get<0>(delete_bitmap_key), std::get<1>(delete_bitmap_key),
                             visible_version},
                            bitmap_value);
                }
            }
        }
        rowset->rowset_meta()->set_cloud_fields_after_visible(visible_version,
                                                              version_update_time_ms);
        add_rowsets({rowset}, false, meta_wlock, true);
    }
    LOG(INFO) << "mow added visible pending rowset, txn_id=" << txn_id
              << ", tablet_id=" << tablet_id() << ", version=" << visible_version
              << ", rowset_id=" << rowset->rowset_id().to_string();
}

void CloudTablet::apply_visible_pending_rowsets() {
    Defer defer {[&] { clear_unused_visible_pending_rowsets(); }};

    std::unique_lock lock(_sync_meta_lock);
    std::unique_lock<std::shared_mutex> meta_wlock(_meta_lock);
    int64_t next_version = _max_version + 1;
    std::vector<RowsetSharedPtr> to_add;
    std::lock_guard<std::mutex> pending_lock(_visible_pending_rs_lock);
    for (auto it = _visible_pending_rs_map.upper_bound(_max_version);
         it != _visible_pending_rs_map.end(); ++it) {
        int64_t version = it->first;
        if (version != next_version) break;

        auto& pending_rs = it->second;
        if (pending_rs.is_empty_rowset) {
            RowsetSharedPtr prev_rowset {nullptr};
            if (!to_add.empty()) {
                prev_rowset = to_add.back();
            } else {
                Versions existing_versions;
                for (const auto& [_, rs] : tablet_meta()->all_rs_metas()) {
                    existing_versions.emplace_back(rs->version());
                }
                if (existing_versions.empty()) {
                    break;
                }
                auto max_version = std::ranges::max(existing_versions, {}, &Version::first);
                prev_rowset = get_rowset_by_version(max_version);
            }
            RowsetSharedPtr rowset;
            auto st = _engine.meta_mgr().create_empty_rowset_for_hole(
                    this, version, prev_rowset->rowset_meta(), &rowset);
            if (!st.ok()) {
                return;
            }
            to_add.push_back(std::move(rowset));
        } else {
            RowsetSharedPtr rowset;
            auto st = RowsetFactory::create_rowset(nullptr, "", pending_rs.rowset_meta, &rowset);
            if (!st.ok()) {
                LOG(WARNING) << "failed to create rowset from pending rowset meta, tablet_id="
                             << tablet_id() << ", version=" << version
                             << ", rowset_id=" << pending_rs.rowset_meta->rowset_id().to_string()
                             << ", error=" << st;
                break;
            }
            to_add.push_back(std::move(rowset));
        }
        next_version++;
    }
    if (!to_add.empty()) {
        add_rowsets(to_add, false, meta_wlock, true);
        LOG_INFO(
                "applied_visible_pending_rowsets, tablet_id={}, new_max_version={}, "
                "count={}, new_rowsets={}",
                tablet_id(), _max_version, to_add.size(),
                fmt::join(to_add | std::views::transform([](const RowsetSharedPtr& rs) {
                              return fmt::format("{}{}", rs->rowset_id().to_string(),
                                                 rs->version().to_string());
                          }),
                          ","));
    }
}

#include "common/compile_check_end.h"

} // namespace doris
