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

#include <algorithm>
#include <limits>
#include <type_traits>

#include "common/global.h"
#ifdef ENABLE_THREADS
#include "common/thread_pool.h"
#endif
#include "compress/compressor_factory.h"
#include "encoding/decoder_factory.h"

using namespace common;
namespace storage {

int AlignedChunkReader::init(ReadFile* read_file, String m_name,
                             TSDataType data_type, Filter* time_filter) {
    read_file_ = read_file;
    measurement_name_.shallow_copy_from(m_name);
    time_decoder_ = DecoderFactory::alloc_time_decoder();
    value_decoder_ = nullptr;
    time_compressor_ = nullptr;
    value_compressor_ = nullptr;
    time_filter_ = time_filter;
    time_uncompressed_buf_ = nullptr;
    value_uncompressed_buf_ = nullptr;
    if (IS_NULL(time_decoder_)) {
        return E_OOM;
    }
    return E_OK;
}

void AlignedChunkReader::reset() {
    time_chunk_meta_ = nullptr;
    value_chunk_meta_ = nullptr;
    time_chunk_header_.reset();
    value_chunk_header_.reset();
    cur_time_page_header_.reset();
    cur_value_page_header_.reset();

    char* file_data_buf = time_in_stream_.get_wrapped_buf();
    if (file_data_buf != nullptr) {
        mem_free(file_data_buf);
    }
    time_in_stream_.clear_wrapped_buf();
    time_in_stream_.reset();
    file_data_buf = value_in_stream_.get_wrapped_buf();
    if (file_data_buf != nullptr) {
        mem_free(file_data_buf);
    }
    value_in_stream_.clear_wrapped_buf();
    value_in_stream_.reset();
    file_data_time_buf_size_ = 0;
    file_data_value_buf_size_ = 0;
    time_chunk_visit_offset_ = 0;
    value_chunk_visit_offset_ = 0;
    page_plan_built_ = false;
    current_page_loaded_ = false;
    current_page_plan_index_ = 0;
    time_predecoded_ = false;
    page_all_times_.clear();
    page_time_count_ = 0;
    page_time_cursor_ = 0;

    // Free leftover uncompressed buffers from the previous chunk.
    if (time_uncompressed_buf_ != nullptr && time_compressor_ != nullptr) {
        time_compressor_->after_uncompress(time_uncompressed_buf_);
        time_uncompressed_buf_ = nullptr;
    }

    // Multi-value reset
    for (auto* col : value_columns_) {
        // Free uncompressed buffer before resetting.
        if (col->uncompressed_buf != nullptr && col->compressor != nullptr) {
            col->compressor->after_uncompress(col->uncompressed_buf);
            col->uncompressed_buf = nullptr;
        }
        char* buf = col->in_stream.get_wrapped_buf();
        if (buf != nullptr) mem_free(buf);
        col->in_stream.clear_wrapped_buf();
        col->in_stream.reset();
        col->in.reset();
        col->chunk_header.reset();
        col->cur_page_header.reset();
        col->file_data_buf_size = 0;
        col->chunk_visit_offset = 0;
        col->notnull_bitmap.clear();
        col->cur_value_index = -1;
        col->chunk_meta = nullptr;
        for (auto& pps : col->per_page_state) {
            pps.predecode_pa.destroy();
        }
        col->per_page_state.clear();
        col->pending_decoded_values.clear();
        col->pending_decoded_count = 0;
        col->pending_decoded_cursor = 0;
        col->pending_decoded = false;
        // Note: decoder/compressor are NOT freed here — they are reused by
        // alloc_compressor_and_decoder() in load_by_aligned_meta_multi().
    }
    release_current_page_state();
    chunk_pages_.clear();
    per_page_times_.clear();
}

void AlignedChunkReader::destroy() {
    // .clear() leaves the vector's internal heap buffer allocated, which
    // mem_free can't reach because we placement-new the reader. swap with
    // an empty vector to actually release the backing storage so ASan's
    // LeakSanitizer doesn't flag the (rather large) ChunkPageInfo buffers.
    std::vector<ChunkPageInfo>{}.swap(chunk_pages_);
    std::vector<int64_t>{}.swap(page_all_times_);
    if (time_uncompressed_buf_ != nullptr && time_compressor_ != nullptr) {
        time_compressor_->after_uncompress(time_uncompressed_buf_);
        time_uncompressed_buf_ = nullptr;
    }
    if (value_uncompressed_buf_ != nullptr && value_compressor_ != nullptr) {
        value_compressor_->after_uncompress(value_uncompressed_buf_);
        value_uncompressed_buf_ = nullptr;
    }
    value_page_col_notnull_bitmap_.clear();
    value_page_col_notnull_bitmap_.shrink_to_fit();
    if (time_decoder_ != nullptr) {
        time_decoder_->~Decoder();
        DecoderFactory::free(time_decoder_);
        time_decoder_ = nullptr;
    }
    if (value_decoder_ != nullptr) {
        value_decoder_->~Decoder();
        DecoderFactory::free(value_decoder_);
        value_decoder_ = nullptr;
    }
    if (time_compressor_ != nullptr) {
        time_compressor_->~Compressor();
        CompressorFactory::free(time_compressor_);
        time_compressor_ = nullptr;
    }
    if (value_compressor_ != nullptr) {
        value_compressor_->~Compressor();
        CompressorFactory::free(value_compressor_);
        value_compressor_ = nullptr;
    }
    char* buf = time_in_stream_.get_wrapped_buf();
    if (buf != nullptr) {
        mem_free(buf);
        time_in_stream_.clear_wrapped_buf();
    }
    cur_time_page_header_.reset();
    buf = value_in_stream_.get_wrapped_buf();
    if (buf != nullptr) {
        mem_free(buf);
        value_in_stream_.clear_wrapped_buf();
    }
    cur_value_page_header_.reset();
    chunk_header_.~ChunkHeader();

    // Multi-value destroy
    for (size_t ci = 0; ci < value_columns_.size(); ci++) {
        auto* col = value_columns_[ci];
        if (col->decoder != nullptr) {
            col->decoder->~Decoder();
            DecoderFactory::free(col->decoder);
            col->decoder = nullptr;
        }
        if (col->compressor != nullptr) {
            col->compressor->~Compressor();
            CompressorFactory::free(col->compressor);
            col->compressor = nullptr;
        }
        for (auto& pps : col->per_page_state) {
            pps.predecode_pa.destroy();
        }
        col->per_page_state.clear();
        col->pending_decoded_values.clear();
        buf = col->in_stream.get_wrapped_buf();
        if (buf != nullptr) {
            mem_free(buf);
            col->in_stream.clear_wrapped_buf();
        }
        col->cur_page_header.reset();
        delete col;
    }
    // This reader is placement-new'd and torn down via destroy() + mem_free
    // without ever running ~AlignedChunkReader (see
    // TsFileSeriesScanIterator::destroy), so .clear() would leave these
    // vectors' backing buffers allocated and unreachable.  swap with an empty
    // vector to actually release the storage, matching the chunk_pages_ /
    // page_all_times_ handling above.
    std::vector<ValueColumnState*>().swap(value_columns_);
    release_current_page_state();
    std::vector<std::vector<int64_t>>().swap(per_page_times_);
#ifdef ENABLE_THREADS
    decode_pool_ = nullptr;  // borrowed, not owned
    for (auto* d : time_decoder_pool_) {
        if (d != nullptr) {
            d->~Decoder();
            DecoderFactory::free(d);
        }
    }
    std::vector<Decoder*>().swap(time_decoder_pool_);
    for (auto* c : time_compressor_pool_) {
        if (c != nullptr) {
            c->~Compressor();
            CompressorFactory::free(c);
        }
    }
    std::vector<Compressor*>().swap(time_compressor_pool_);
#endif
}

int AlignedChunkReader::load_by_aligned_meta(ChunkMeta* time_chunk_meta,
                                             ChunkMeta* value_chunk_meta) {
    int ret = E_OK;
    time_chunk_meta_ = time_chunk_meta;
    value_chunk_meta_ = value_chunk_meta;
#if DEBUG_SE
    std::cout << "AlignedChunkReader::load_by_meta, meta=" << *time_chunk_meta
              << ", " << *value_chunk_meta << std::endl;
#endif
    /* ================ deserialize time_chunk_header ================*/
    // TODO configurable
    file_data_time_buf_size_ = 1024;
    file_data_value_buf_size_ = 1024;
    int32_t ret_read_len = 0;
    char* time_file_data_buf =
        (char*)mem_alloc(file_data_time_buf_size_, MOD_CHUNK_READER);
    if (IS_NULL(time_file_data_buf)) {
        return E_OOM;
    }
    ret = read_file_->read(time_chunk_meta_->offset_of_chunk_header_,
                           time_file_data_buf, file_data_time_buf_size_,
                           ret_read_len);
    if (IS_SUCC(ret) && ret_read_len < ChunkHeader::MIN_SERIALIZED_SIZE) {
        ret = E_TSFILE_CORRUPTED;
        LOGE("file corrupted, ret=" << ret << ", offset="
                                    << time_chunk_meta_->offset_of_chunk_header_
                                    << "read_len=" << ret_read_len);
        mem_free(time_file_data_buf);
    }
    if (IS_SUCC(ret)) {
        time_in_stream_.wrap_from(time_file_data_buf, ret_read_len);
        if (RET_FAIL(time_chunk_header_.deserialize_from(time_in_stream_))) {
        } else {
            time_chunk_visit_offset_ = time_in_stream_.read_pos();
        }
    }
    /* ================ deserialize value_chunk_header ================*/
    ret_read_len = 0;
    char* value_file_data_buf =
        (char*)mem_alloc(file_data_value_buf_size_, MOD_CHUNK_READER);
    if (IS_NULL(value_file_data_buf)) {
        return E_OOM;
    }
    ret = read_file_->read(value_chunk_meta_->offset_of_chunk_header_,
                           value_file_data_buf, file_data_value_buf_size_,
                           ret_read_len);
    if (IS_SUCC(ret) && ret_read_len < ChunkHeader::MIN_SERIALIZED_SIZE) {
        ret = E_TSFILE_CORRUPTED;
        LOGE("file corrupted, ret="
             << ret << ", offset=" << value_chunk_meta_->offset_of_chunk_header_
             << "read_len=" << ret_read_len);
        mem_free(value_file_data_buf);
    }
    if (IS_SUCC(ret)) {
        value_in_stream_.wrap_from(value_file_data_buf, ret_read_len);
        if (RET_FAIL(value_chunk_header_.deserialize_from(value_in_stream_))) {
        } else if (RET_FAIL(alloc_compressor_and_decoder(
                       time_decoder_, time_compressor_,
                       time_chunk_header_.encoding_type_,
                       time_chunk_header_.data_type_,
                       time_chunk_header_.compression_type_))) {
        } else if (RET_FAIL(alloc_compressor_and_decoder(
                       value_decoder_, value_compressor_,
                       value_chunk_header_.encoding_type_,
                       value_chunk_header_.data_type_,
                       value_chunk_header_.compression_type_))) {
        } else {
            value_chunk_visit_offset_ = value_in_stream_.read_pos();
#if DEBUG_SE
            std::cout << "AlignedChunkReader::load_by_meta, time_chunk_header="
                      << time_chunk_header_
                      << ", value_chunk_header=" << value_chunk_header_
                      << std::endl;
#endif
        }
    }
    return ret;
}

int AlignedChunkReader::alloc_compressor_and_decoder(
    storage::Decoder*& decoder, storage::Compressor*& compressor,
    TSEncoding encoding, TSDataType data_type, CompressionType compression) {
    if (decoder != nullptr) {
        decoder->reset();
    } else {
        decoder = DecoderFactory::alloc_value_decoder(encoding, data_type);
        if (IS_NULL(decoder)) {
            return E_OOM;
        }
    }

    if (compressor != nullptr) {
        compressor->reset(false);
    } else {
        compressor = CompressorFactory::alloc_compressor(compression);
        if (compressor == nullptr) {
            return E_OOM;
        }
    }
    return E_OK;
}

int AlignedChunkReader::get_next_page(TsBlock* ret_tsblock,
                                      Filter* oneshoot_filter, PageArena& pa) {
    if (multi_value_mode_) {
        return get_next_page_multi(ret_tsblock, oneshoot_filter, pa);
    }
    int ret = E_OK;
    Filter* filter =
        (oneshoot_filter != nullptr ? oneshoot_filter : time_filter_);
    bool pt = prev_time_page_not_finish();
    bool pv = prev_value_page_not_finish();
    if (pt && pv) {
        ret = decode_time_value_buf_into_tsblock(ret_tsblock, filter, &pa);
        return ret;
    }
    if (!pt && !pv) {
        while (IS_SUCC(ret)) {
            if (RET_FAIL(get_cur_page_header(
                    time_chunk_meta_, time_in_stream_, cur_time_page_header_,
                    time_chunk_visit_offset_, time_chunk_header_))) {
            } else if (RET_FAIL(get_cur_page_header(
                           value_chunk_meta_, value_in_stream_,
                           cur_value_page_header_, value_chunk_visit_offset_,
                           value_chunk_header_))) {
            } else if (cur_page_statisify_filter(filter)) {
                break;
            } else if (RET_FAIL(skip_cur_page())) {
            }
            if (!has_more_data()) {
                ret = E_NO_MORE_DATA;
                break;
            }
        }
        if (IS_SUCC(ret)) {
            ret = decode_cur_time_page_data() || decode_cur_value_page_data();
        }
    }
    if (IS_SUCC(ret)) {
        ret = decode_time_value_buf_into_tsblock(ret_tsblock, filter, &pa);
    }
    return ret;
}

int AlignedChunkReader::get_cur_page_header(ChunkMeta*& chunk_meta,
                                            common::ByteStream& in_stream,
                                            PageHeader& cur_page_header,
                                            uint32_t& chunk_visit_offset,
                                            ChunkHeader& chunk_header,
                                            int32_t* override_buf_size) {
    int ret = E_OK;
    bool retry = true;
    int cur_page_header_serialized_size = 0;
    // TODO： configurable
    int retry_read_want_size = 1024;
    if (chunk_visit_offset - chunk_header.serialized_size_ >=
        chunk_header.data_size_) {
        cur_page_header.reset();
        return E_OK;
    }

    do {
        in_stream.mark_read_pos();
        cur_page_header.reset();
        ret = cur_page_header.deserialize_from(
            in_stream, !chunk_has_only_one_page(chunk_header),
            chunk_header.data_type_);
        cur_page_header_serialized_size = in_stream.get_mark_len();
        if (deserialize_buf_not_enough(ret) && retry) {
            retry = false;
            retry_read_want_size += 1024;
            int32_t& file_data_buf_size =
                override_buf_size != nullptr ? *override_buf_size
                : chunk_header.data_type_ == common::VECTOR
                    ? file_data_time_buf_size_
                    : file_data_value_buf_size_;
            // do not shrink buffer for page header, otherwise, the buffer is
            // most likely to grow back when reading page data
            if (E_OK == read_from_file_and_rewrap(
                            in_stream, chunk_meta, chunk_visit_offset,
                            file_data_buf_size, retry_read_want_size, false)) {
                continue;
            }
        }
        break;
    } while (true);
    if (IS_SUCC(ret)) {
        // visit a header
        chunk_visit_offset += cur_page_header_serialized_size;
    }
#if DEBUG_SE
    std::cout << "get_cur_page_header, ret=" << ret << ", retry=" << retry
              << ", cur_page_header=" << cur_page_header
              << ", chunk_meta->offset_of_chunk_header_="
              << chunk_meta->offset_of_chunk_header_
              << ", cur_page_header_serialized_size="
              << cur_page_header_serialized_size << std::endl;
#endif
    return ret;
}

// reader at least @want_size bytes from file and wrap the buffer into
// @in_stream_
int AlignedChunkReader::read_from_file_and_rewrap(
    common::ByteStream& in_stream_, ChunkMeta*& chunk_meta,
    uint32_t& chunk_visit_offset, int32_t& file_data_buf_size, int want_size,
    bool may_shrink) {
    int ret = E_OK;
    const int DEFAULT_READ_SIZE = 4096;  // may use page_size + page_header_size
    char* file_data_buf = in_stream_.get_wrapped_buf();
    int64_t offset = chunk_meta->offset_of_chunk_header_ + chunk_visit_offset;
    int read_size =
        (want_size < DEFAULT_READ_SIZE ? DEFAULT_READ_SIZE : want_size);
    if (file_data_buf_size < read_size ||
        (may_shrink && read_size < file_data_buf_size / 10)) {
        file_data_buf = (char*)mem_realloc(file_data_buf, read_size);
        if (IS_NULL(file_data_buf)) {
            in_stream_.clear_wrapped_buf();
            return E_OOM;
        }
        file_data_buf_size = read_size;
        // Update stream pointer immediately so it stays valid even if
        // the subsequent read fails and the caller frees via destroy().
        in_stream_.wrap_from(file_data_buf, read_size);
    }
    int ret_read_len = 0;
    if (RET_FAIL(
            read_file_->read(offset, file_data_buf, read_size, ret_read_len))) {
    } else {
        in_stream_.wrap_from(file_data_buf, ret_read_len);
#ifdef DEBUG_SE
        std::cout << "file offset = " << offset << " len = " << ret_read_len
                  << std::endl;
        DEBUG_hex_dump_buf("wrapped buf = ", file_data_buf, 256);
#endif
    }
    return ret;
}

bool AlignedChunkReader::cur_page_statisify_filter(Filter* filter) {
    bool value_satisfy = filter == nullptr ||
                         cur_value_page_header_.statistic_ == nullptr ||
                         filter->satisfy(cur_value_page_header_.statistic_);
    bool time_satisfy = filter == nullptr ||
                        cur_time_page_header_.statistic_ == nullptr ||
                        filter->satisfy(cur_time_page_header_.statistic_);
    return time_satisfy && value_satisfy;
}

int AlignedChunkReader::skip_cur_page() {
    int ret = E_OK;
    // visit a page tv data
    time_chunk_visit_offset_ += cur_time_page_header_.compressed_size_;
    time_in_stream_.wrapped_buf_advance_read_pos(
        cur_time_page_header_.compressed_size_);
    value_chunk_visit_offset_ += cur_value_page_header_.compressed_size_;
    value_in_stream_.wrapped_buf_advance_read_pos(
        cur_value_page_header_.compressed_size_);
    return ret;
}

int AlignedChunkReader::decode_cur_time_page_data() {
    int ret = E_OK;

    // Step 1: make sure we load the whole page data in @in_stream_
    if (time_in_stream_.remaining_size() <
        cur_time_page_header_.compressed_size_) {
        // std::cout << "decode_cur_page_data. in_stream_.remaining_size="<<
        // in_stream_.remaining_size() << ", cur_page_header_.compressed_size_="
        // << cur_page_header_.compressed_size_ << std::endl;
        if (RET_FAIL(read_from_file_and_rewrap(
                time_in_stream_, time_chunk_meta_, time_chunk_visit_offset_,
                file_data_time_buf_size_,
                cur_time_page_header_.compressed_size_))) {
        }
    }

    char* time_compressed_buf = nullptr;
    char* time_uncompressed_buf = nullptr;
    uint32_t time_compressed_buf_size = 0;
    uint32_t time_uncompressed_buf_size = 0;

    // Step 2: do uncompress
    if (IS_SUCC(ret)) {
        time_compressed_buf =
            time_in_stream_.get_wrapped_buf() + time_in_stream_.read_pos();
#ifdef DEBUG_SE
        std::cout << "AlignedChunkReader::decode_cur_page_data,time_in_stream_."
                     "get_wrapped_buf="
                  << (void*)(time_in_stream_.get_wrapped_buf())
                  << ", time_in_stream_.read_pos=" << time_in_stream_.read_pos()
                  << std::endl;
#endif
        time_compressed_buf_size = cur_time_page_header_.compressed_size_;
        time_in_stream_.wrapped_buf_advance_read_pos(time_compressed_buf_size);
        time_chunk_visit_offset_ += time_compressed_buf_size;
        if (RET_FAIL(time_compressor_->reset(false))) {
        } else if (RET_FAIL(time_compressor_->uncompress(
                       time_compressed_buf, time_compressed_buf_size,
                       time_uncompressed_buf, time_uncompressed_buf_size))) {
        } else {
            time_uncompressed_buf_ = time_uncompressed_buf;
        }
#ifdef DEBUG_SE
        DEBUG_hex_dump_buf(
            "AlignedChunkReader reader, time_uncompressed buf = ",
            time_uncompressed_buf, time_uncompressed_buf_size);
#endif
        if (ret != E_OK || time_uncompressed_buf_size !=
                               cur_time_page_header_.uncompressed_size_) {
            ret = E_TSFILE_CORRUPTED;
            ASSERT(false);
        }
    }

    time_decoder_->reset();
#ifdef DEBUG_SE
    DEBUG_hex_dump_buf("AlignedChunkReader reader, time_buf = ", time_buf,
                       time_buf_size);
#endif
    time_in_.wrap_from(time_uncompressed_buf_, time_uncompressed_buf_size);
    return ret;
}

int AlignedChunkReader::decode_cur_value_page_data() {
    int ret = E_OK;

    // Step 1: make sure we load the whole page data in @in_stream_
    if (value_in_stream_.remaining_size() <
        cur_value_page_header_.compressed_size_) {
        // std::cout << "decode_cur_page_data. in_stream_.remaining_size="<<
        // in_stream_.remaining_size() << ", cur_page_header_.compressed_size_="
        // << cur_page_header_.compressed_size_ << std::endl;
        if (RET_FAIL(read_from_file_and_rewrap(
                value_in_stream_, value_chunk_meta_, value_chunk_visit_offset_,
                file_data_value_buf_size_,
                cur_value_page_header_.compressed_size_))) {
        }
    }

    char* value_compressed_buf = nullptr;
    char* value_uncompressed_buf = nullptr;
    uint32_t value_compressed_buf_size = 0;
    uint32_t value_uncompressed_buf_size = 0;
    char* value_buf = nullptr;
    uint32_t value_buf_size = 0;

    if (cur_value_page_header_.compressed_size_ == 0) {
        value_in_.wrap_from(value_buf, 0);
        return E_OK;
    }

    // Step 2: do uncompress
    if (IS_SUCC(ret)) {
        value_compressed_buf =
            value_in_stream_.get_wrapped_buf() + value_in_stream_.read_pos();
        value_compressed_buf_size = cur_value_page_header_.compressed_size_;
        value_in_stream_.wrapped_buf_advance_read_pos(
            value_compressed_buf_size);
        value_chunk_visit_offset_ += value_compressed_buf_size;
        if (RET_FAIL(value_compressor_->reset(false))) {
        } else if (RET_FAIL(value_compressor_->uncompress(
                       value_compressed_buf, value_compressed_buf_size,
                       value_uncompressed_buf, value_uncompressed_buf_size))) {
        } else {
            value_uncompressed_buf_ = value_uncompressed_buf;
        }
#ifdef DEBUG_SE
        DEBUG_hex_dump_buf(
            "AlignedChunkReader reader, value_uncompressed buf = ",
            value_uncompressed_buf, value_uncompressed_buf_size);
#endif
        if (ret != E_OK || value_uncompressed_buf_size !=
                               cur_value_page_header_.uncompressed_size_) {
            ret = E_TSFILE_CORRUPTED;
            ASSERT(false);
        }
    }
    // Step 3: get value_buf
    if (IS_SUCC(ret)) {
        uint32_t value_uncompressed_buf_offset = 0;
        value_page_data_num_ =
            SerializationUtil::read_ui32(value_uncompressed_buf);
        value_uncompressed_buf_offset += sizeof(uint32_t);
        value_page_col_notnull_bitmap_.resize((value_page_data_num_ + 7) / 8);
        for (unsigned char& i : value_page_col_notnull_bitmap_) {
            i = *(value_uncompressed_buf + value_uncompressed_buf_offset);
            value_uncompressed_buf_offset++;
        }
        cur_value_index = -1;
        value_buf = value_uncompressed_buf + value_uncompressed_buf_offset;
        value_buf_size =
            value_uncompressed_buf_size - value_uncompressed_buf_offset;
    }
    value_decoder_->reset();
#ifdef DEBUG_SE
    DEBUG_hex_dump_buf("AlignedChunkReader reader, value_buf = ", value_buf,
                       value_buf_size);
#endif
    value_in_.wrap_from(value_buf, value_buf_size);
    return ret;
}

int AlignedChunkReader::decode_time_value_buf_into_tsblock(
    TsBlock*& ret_tsblock, Filter* filter, common::PageArena* pa) {
    int ret = common::E_OK;
    ret = decode_tv_buf_into_tsblock_by_datatype(time_in_, value_in_,
                                                 ret_tsblock, filter, pa);
    // if we return during @decode_tv_buf_into_tsblock, we should keep
    // @uncompressed_buf_ valid until all TV pairs are decoded.
    if (ret != E_OVERFLOW) {
        if (time_uncompressed_buf_ != nullptr) {
            time_compressor_->after_uncompress(time_uncompressed_buf_);
            time_uncompressed_buf_ = nullptr;
        }
        if (value_uncompressed_buf_ != nullptr) {
            value_compressor_->after_uncompress(value_uncompressed_buf_);
            value_uncompressed_buf_ = nullptr;
        }
        if (!prev_value_page_not_finish()) {
            value_in_.reset();
        }
        if (!prev_time_page_not_finish()) {
            time_in_.reset();
        }
        value_page_col_notnull_bitmap_.clear();
        value_page_col_notnull_bitmap_.shrink_to_fit();
    } else {
        ret = E_OK;
    }
    return ret;
}

#define DECODE_TYPED_TV_INTO_TSBLOCK(CppType, ReadType, time_in, value_in,     \
                                     row_appender)                             \
    do {                                                                       \
        uint32_t mask = 1 << 7;                                                \
        int64_t time = 0;                                                      \
        CppType value;                                                         \
        while (time_decoder_->has_remaining(time_in)) {                        \
            cur_value_index++;                                                 \
            if (value_page_col_notnull_bitmap_.empty() ||                      \
                ((value_page_col_notnull_bitmap_[cur_value_index / 8] &        \
                  0xFF) &                                                      \
                 (mask >> (cur_value_index % 8))) == 0) {                      \
                if (UNLIKELY(!row_appender.add_row())) {                       \
                    ret = E_OVERFLOW;                                          \
                    cur_value_index--;                                         \
                    break;                                                     \
                }                                                              \
                ret = time_decoder_->read_int64(time, time_in);                \
                if (ret != E_OK) {                                             \
                    break;                                                     \
                }                                                              \
                row_appender.append(0, (char*)&time, sizeof(time));            \
                row_appender.append_null(1);                                   \
                continue;                                                      \
            }                                                                  \
            assert(value_decoder_->has_remaining(value_in));                   \
            if (!value_decoder_->has_remaining(value_in)) {                    \
                return common::E_DATA_INCONSISTENCY;                           \
            }                                                                  \
            if (UNLIKELY(!row_appender.add_row())) {                           \
                ret = E_OVERFLOW;                                              \
                cur_value_index--;                                             \
                break;                                                         \
            } else if (RET_FAIL(time_decoder_->read_int64(time, time_in))) {   \
            } else if (RET_FAIL(value_decoder_->read_##ReadType(value,         \
                                                                value_in))) {  \
            } else if (filter != nullptr && !filter->satisfy(time, value)) {   \
                row_appender.backoff_add_row();                                \
                continue;                                                      \
            } else {                                                           \
                /*std::cout << "decoder: time=" << time << ", value=" << value \
                 * << std::endl;*/                                             \
                row_appender.append(0, (char*)&time, sizeof(time));            \
                row_appender.append(1, (char*)&value, sizeof(value));          \
            }                                                                  \
        }                                                                      \
    } while (false)

int AlignedChunkReader::i32_DECODE_TYPED_TV_INTO_TSBLOCK(
    ByteStream& time_in, ByteStream& value_in, RowAppender& row_appender,
    Filter* filter) {
    int ret = E_OK;
    uint32_t mask = 1 << 7;
    int64_t time = 0;
    int32_t value;
    while (time_decoder_->has_remaining(time_in)) {
        cur_value_index++;
        if (value_page_col_notnull_bitmap_.empty() ||
            ((value_page_col_notnull_bitmap_[cur_value_index / 8] & 0xFF) &
             (mask >> (cur_value_index % 8))) == 0) {
            ret = time_decoder_->read_int64(time, time_in);
            if (ret != E_OK) {
                break;
            }
            if (UNLIKELY(!row_appender.add_row())) {
                ret = E_OVERFLOW;
                break;
            }
            row_appender.append(0, (char*)&time, sizeof(time));
            row_appender.append_null(1);
            continue;
        }
        assert(value_decoder_->has_remaining(value_in));
        if (!value_decoder_->has_remaining(value_in)) {
            return common::E_DATA_INCONSISTENCY;
        }
        if (UNLIKELY(!row_appender.add_row())) {
            ret = E_OVERFLOW;
            cur_value_index--;
            break;
        } else if (RET_FAIL(time_decoder_->read_int64(time, time_in))) {
        } else if (RET_FAIL(value_decoder_->read_int32(value, value_in))) {
        } else if (filter != nullptr && !filter->satisfy(time, value)) {
            row_appender.backoff_add_row();
            continue;
        } else {
            /*std::cout << "decoder: time=" << time << ", value=" << value
             * << std::endl;*/
            row_appender.append(0, (char*)&time, sizeof(time));
            row_appender.append(1, (char*)&value, sizeof(value));
        }
    }
    return ret;
}

namespace {
// Type-dispatched value batch read / skip for decode_tv_batch<T>.  Overload
// resolution on the value pointer type selects the matching Decoder method, so
// the four fixed-width value types share one decode loop.
FORCE_INLINE int read_value_batch_typed(Decoder* d, int32_t* out, int cap,
                                        int& actual, ByteStream& in) {
    return d->read_batch_int32(out, cap, actual, in);
}
FORCE_INLINE int read_value_batch_typed(Decoder* d, int64_t* out, int cap,
                                        int& actual, ByteStream& in) {
    return d->read_batch_int64(out, cap, actual, in);
}
FORCE_INLINE int read_value_batch_typed(Decoder* d, float* out, int cap,
                                        int& actual, ByteStream& in) {
    return d->read_batch_float(out, cap, actual, in);
}
FORCE_INLINE int read_value_batch_typed(Decoder* d, double* out, int cap,
                                        int& actual, ByteStream& in) {
    return d->read_batch_double(out, cap, actual, in);
}
FORCE_INLINE int skip_value_typed(Decoder* d, int32_t*, int n, int& skipped,
                                  ByteStream& in) {
    return d->skip_int32(n, skipped, in);
}
FORCE_INLINE int skip_value_typed(Decoder* d, int64_t*, int n, int& skipped,
                                  ByteStream& in) {
    return d->skip_int64(n, skipped, in);
}
FORCE_INLINE int skip_value_typed(Decoder* d, float*, int n, int& skipped,
                                  ByteStream& in) {
    return d->skip_float(n, skipped, in);
}
FORCE_INLINE int skip_value_typed(Decoder* d, double*, int n, int& skipped,
                                  ByteStream& in) {
    return d->skip_double(n, skipped, in);
}
}  // namespace

// Unified aligned time+value page decode for fixed-width value types
// (INT32/INT64/FLOAT/DOUBLE).  These differ only in the value array type, the
// typed read/skip calls (dispatched via the helpers above), and whether the
// per-value Filter::satisfy (which takes an int64 value) is applied — only
// integral value columns use it; float/double are filtered on time only.
template <typename T>
int AlignedChunkReader::decode_tv_batch(ByteStream& time_in,
                                        ByteStream& value_in,
                                        RowAppender& row_appender,
                                        Filter* filter) {
    int ret = E_OK;
    const int BATCH = 129;
    int64_t times[BATCH];
    T values[BATCH];
    const uint32_t null_mask_base = 1 << 7;

    while (time_decoder_->has_remaining(time_in)) {
        if (row_appender.remaining() < (uint32_t)BATCH) {
            ret = E_OVERFLOW;
            break;
        }

        // Block-level time filter check: skip entire block if out of range.
        bool block_all_pass = false;
        if (filter != nullptr) {
            int64_t block_min, block_max;
            int block_count;
            if (time_decoder_->peek_next_block_range_int64(
                    time_in, block_min, block_max, block_count)) {
                if (!filter->satisfy_start_end_time(block_min, block_max)) {
                    int skipped = 0;
                    time_decoder_->skip_peeked_block_int64(time_in, skipped);
                    int nonnull = 0;
                    for (int i = 0; i < block_count; ++i) {
                        int vi = cur_value_index + 1 + i;
                        if (!value_page_col_notnull_bitmap_.empty() &&
                            ((value_page_col_notnull_bitmap_[vi / 8] & 0xFF) &
                             (null_mask_base >> (vi % 8))) != 0) {
                            ++nonnull;
                        }
                    }
                    cur_value_index += block_count;
                    if (nonnull > 0) {
                        // skip_* may legitimately fail (truncated page) or
                        // short-read (corrupt bitmap vs. data); both must abort
                        // the loop rather than silently desync the value
                        // decoder.
                        int sk = 0;
                        if (RET_FAIL(skip_value_typed(value_decoder_, values,
                                                      nonnull, sk, value_in))) {
                            break;
                        }
                        if (sk != nonnull) {
                            ret = E_TSFILE_CORRUPTED;
                            break;
                        }
                    }
                    continue;
                }
                if (filter->contain_start_end_time(block_min, block_max)) {
                    block_all_pass = true;
                }
            }
        }

        int time_count = 0;
        if (RET_FAIL(time_decoder_->read_batch_int64(times, BATCH, time_count,
                                                     time_in))) {
            break;
        }
        if (time_count == 0) break;

        bool is_null[BATCH];
        int nonnull_count = 0;
        for (int i = 0; i < time_count; ++i) {
            int vi = cur_value_index + 1 + i;
            if (value_page_col_notnull_bitmap_.empty() ||
                ((value_page_col_notnull_bitmap_[vi / 8] & 0xFF) &
                 (null_mask_base >> (vi % 8))) == 0) {
                is_null[i] = true;
            } else {
                is_null[i] = false;
                ++nonnull_count;
            }
        }

        bool time_mask[BATCH];
        int pass_count = time_count;
        if (filter != nullptr && !block_all_pass) {
            pass_count =
                filter->satisfy_batch_time(times, time_count, time_mask);
        }

        if (pass_count == 0) {
            if (nonnull_count > 0) {
                int skipped = 0;
                if (RET_FAIL(skip_value_typed(value_decoder_, values,
                                              nonnull_count, skipped,
                                              value_in))) {
                    break;
                }
                if (skipped != nonnull_count) {
                    ret = E_TSFILE_CORRUPTED;
                    break;
                }
            }
            cur_value_index += time_count;
            continue;
        }

        int value_count = 0;
        if (nonnull_count > 0) {
            if (RET_FAIL(read_value_batch_typed(value_decoder_, values,
                                                nonnull_count, value_count,
                                                value_in))) {
                break;
            }
        }

        int val_idx = 0;
        for (int i = 0; i < time_count; ++i) {
            cur_value_index++;
            if (filter != nullptr && !block_all_pass && !time_mask[i]) {
                if (!is_null[i]) ++val_idx;
                continue;
            }
            if (is_null[i]) {
                if (UNLIKELY(!row_appender.add_row())) {
                    ret = E_OVERFLOW;
                    break;
                }
                row_appender.append(0, (char*)&times[i], sizeof(int64_t));
                row_appender.append_null(1);
            } else {
                T val = values[val_idx++];
                // Per-value filter applies only to integral value columns;
                // Filter::satisfy takes an int64 value.  is_integral<T> is a
                // compile-time constant, so this branch is elided (and the
                // int64 cast never evaluated) for float/double.
                if (std::is_integral<T>::value && filter != nullptr &&
                    !block_all_pass &&
                    !filter->satisfy(times[i], static_cast<int64_t>(val))) {
                    continue;
                }
                if (UNLIKELY(!row_appender.add_row())) {
                    ret = E_OVERFLOW;
                    break;
                }
                row_appender.append(0, (char*)&times[i], sizeof(int64_t));
                row_appender.append(1, (char*)&val, sizeof(T));
            }
        }
        if (ret != E_OK) break;
    }
    return ret;
}

int AlignedChunkReader::decode_tv_buf_into_tsblock_by_datatype(
    ByteStream& time_in, ByteStream& value_in, TsBlock* ret_tsblock,
    Filter* filter, common::PageArena* pa) {
    int ret = E_OK;
    RowAppender row_appender(ret_tsblock);
    switch (value_chunk_header_.data_type_) {
        case common::BOOLEAN:
            DECODE_TYPED_TV_INTO_TSBLOCK(bool, boolean, time_in_, value_in_,
                                         row_appender);
            break;
        case common::DATE:
        case common::INT32:
            // Batch decode path: read_batch_int{32,64} consumes whole TS_2DIFF
            // blocks at once (and uses SIMD when ENABLE_SIMD); replaces a
            // per-value decode() loop that hot-dominated the read flame graph.
            ret = decode_tv_batch<int32_t>(time_in_, value_in_, row_appender,
                                           filter);
            break;
        case common::TIMESTAMP:
        case common::INT64:
            ret = decode_tv_batch<int64_t>(time_in_, value_in_, row_appender,
                                           filter);
            break;
        case common::FLOAT:
            ret = decode_tv_batch<float>(time_in_, value_in_, row_appender,
                                         filter);
            break;
        case common::DOUBLE:
            ret = decode_tv_batch<double>(time_in_, value_in_, row_appender,
                                          filter);
            break;
        case common::STRING:
        case common::BLOB:
        case common::TEXT:
            ret = STRING_DECODE_TYPED_TV_INTO_TSBLOCK(
                time_in, value_in, row_appender, *pa, filter);
            break;
        default:
            ret = E_NOT_SUPPORT;
            ASSERT(false);
    }
    if (ret_tsblock->get_row_count() == 0 && ret == E_OK) {
        ret = E_NO_MORE_DATA;
    }
    return ret;
}

int AlignedChunkReader::STRING_DECODE_TYPED_TV_INTO_TSBLOCK(
    ByteStream& time_in, ByteStream& value_in, RowAppender& row_appender,
    PageArena& pa, Filter* filter) {
    int ret = E_OK;
    int64_t time = 0;
    common::String value;
    uint32_t mask = 1 << 7;
    while (time_decoder_->has_remaining(time_in)) {
        cur_value_index++;
        bool should_read_data = true;
        if (value_page_col_notnull_bitmap_.empty() ||
            ((value_page_col_notnull_bitmap_[cur_value_index / 8] & 0xFF) &
             (mask >> (cur_value_index % 8))) == 0) {
            should_read_data = false;
        }

        if (should_read_data) {
            assert(value_decoder_->has_remaining(value_in));
            if (!value_decoder_->has_remaining(value_in)) {
                return E_DATA_INCONSISTENCY;
            }
        }

        if (UNLIKELY(!row_appender.add_row())) {
            ret = E_OVERFLOW;
            cur_value_index--;
            break;
        } else if (RET_FAIL(time_decoder_->read_int64(time, time_in))) {
        } else if (should_read_data &&
                   RET_FAIL(value_decoder_->read_String(value, pa, value_in))) {
        } else if (filter != nullptr && !filter->satisfy(time, value)) {
            row_appender.backoff_add_row();
            continue;
        } else {
            row_appender.append(0, (char*)&time, sizeof(time));
            if (!should_read_data) {
                row_appender.append_null(1);
            } else {
                row_appender.append(1, value.buf_, value.len_);
            }
        }
    }
    return ret;
}

bool AlignedChunkReader::should_skip_page_by_time(int64_t min_time_hint) {
    if (min_time_hint == std::numeric_limits<int64_t>::min()) {
        return false;
    }
    // Use time page statistic for time-based skipping.
    if (cur_time_page_header_.statistic_ != nullptr) {
        return cur_time_page_header_.statistic_->end_time_ < min_time_hint;
    }
    if (cur_value_page_header_.statistic_ != nullptr) {
        return cur_value_page_header_.statistic_->end_time_ < min_time_hint;
    }
    return false;
}

bool AlignedChunkReader::should_skip_page_by_offset(int& row_offset) {
    if (row_offset <= 0) {
        return false;
    }
    // Use time page statistic for count.
    Statistic* stat = cur_time_page_header_.statistic_;
    if (stat == nullptr) {
        stat = cur_value_page_header_.statistic_;
    }
    if (stat == nullptr || stat->count_ == 0) {
        return false;
    }
    int32_t count = stat->count_;
    if (row_offset >= count) {
        row_offset -= count;
        return true;
    }
    return false;
}

int AlignedChunkReader::get_next_page(TsBlock* ret_tsblock,
                                      Filter* oneshoot_filter, PageArena& pa,
                                      int64_t min_time_hint, int& row_offset,
                                      int& row_limit) {
    if (multi_value_mode_) {
        // Multi-value aligned path doesn't yet honour row_offset / row_limit
        // / min_time_hint — they get dropped on the floor, which silently
        // returns full chunk data when the caller asked for a sub-range.
        // Refuse the combination so the caller sees an actual error instead
        // of garbage results.  set_row_range(0, -1) keeps the all-rows
        // contract intact for normal queries.
        if (row_offset > 0 || row_limit >= 0 ||
            min_time_hint != std::numeric_limits<int64_t>::min()) {
            return common::E_NOT_SUPPORT;
        }
        return get_next_page_multi(ret_tsblock, oneshoot_filter, pa);
    }
    int ret = E_OK;
    Filter* filter =
        (oneshoot_filter != nullptr ? oneshoot_filter : time_filter_);

    if (row_limit == 0) {
        return E_NO_MORE_DATA;
    }

    bool pt = prev_time_page_not_finish();
    bool pv = prev_value_page_not_finish();

    if (pt && pv) {
        ret = decode_time_value_buf_into_tsblock(ret_tsblock, filter, &pa);
        return ret;
    }
    if (!pt && !pv) {
        while (IS_SUCC(ret)) {
            if (RET_FAIL(get_cur_page_header(
                    time_chunk_meta_, time_in_stream_, cur_time_page_header_,
                    time_chunk_visit_offset_, time_chunk_header_))) {
            } else if (RET_FAIL(get_cur_page_header(
                           value_chunk_meta_, value_in_stream_,
                           cur_value_page_header_, value_chunk_visit_offset_,
                           value_chunk_header_))) {
            } else if (!cur_page_statisify_filter(filter)) {
                if (RET_FAIL(skip_cur_page())) {
                }
            } else if (should_skip_page_by_time(min_time_hint)) {
                if (RET_FAIL(skip_cur_page())) {
                }
            } else if (should_skip_page_by_offset(row_offset)) {
                if (RET_FAIL(skip_cur_page())) {
                }
            } else {
                break;
            }
            if (!has_more_data()) {
                ret = E_NO_MORE_DATA;
                break;
            }
        }
        if (IS_SUCC(ret)) {
            ret = decode_cur_time_page_data() || decode_cur_value_page_data();
        }
    }
    if (IS_SUCC(ret)) {
        ret = decode_time_value_buf_into_tsblock(ret_tsblock, filter, &pa);
    }
    return ret;
}

// ══════════════════════════════════════════════════════════════════════════
//  Multi-value AlignedChunkReader implementation
// ══════════════════════════════════════════════════════════════════════════

int AlignedChunkReader::load_by_aligned_meta_multi(
    ChunkMeta* time_chunk_meta, const std::vector<ChunkMeta*>& value_metas) {
    int ret = E_OK;
    multi_value_mode_ = true;
    time_chunk_meta_ = time_chunk_meta;
    page_plan_built_ = false;
    current_page_loaded_ = false;
    current_page_plan_index_ = 0;
    time_predecoded_ = false;
    page_all_times_.clear();
    page_time_count_ = 0;
    page_time_cursor_ = 0;

    // ── Load time chunk header ──
    file_data_time_buf_size_ = 1024;
    int32_t ret_read_len = 0;
    char* time_file_data_buf =
        (char*)mem_alloc(file_data_time_buf_size_, MOD_CHUNK_READER);
    if (IS_NULL(time_file_data_buf)) return E_OOM;

    ret = read_file_->read(time_chunk_meta_->offset_of_chunk_header_,
                           time_file_data_buf, file_data_time_buf_size_,
                           ret_read_len);
    if (IS_SUCC(ret) && ret_read_len < ChunkHeader::MIN_SERIALIZED_SIZE) {
        ret = E_TSFILE_CORRUPTED;
        mem_free(time_file_data_buf);
        return ret;
    }
    if (IS_SUCC(ret)) {
        time_in_stream_.wrap_from(time_file_data_buf, ret_read_len);
        if (RET_FAIL(time_chunk_header_.deserialize_from(time_in_stream_))) {
            return ret;
        }
        time_chunk_visit_offset_ = time_in_stream_.read_pos();
    }

    // Alloc time decoder/compressor
    if (IS_SUCC(ret)) {
        if (RET_FAIL(alloc_compressor_and_decoder(
                time_decoder_, time_compressor_,
                time_chunk_header_.encoding_type_,
                time_chunk_header_.data_type_,
                time_chunk_header_.compression_type_))) {
            return ret;
        }
    }

    // ── Load each value column ──
    // Reuse existing ValueColumnState objects if count matches (reset() already
    // cleared their internal state).  Otherwise, recreate.
    if (value_columns_.size() != value_metas.size()) {
        for (auto* p : value_columns_) delete p;
        value_columns_.clear();
        value_columns_.reserve(value_metas.size());
        for (size_t c = 0; c < value_metas.size(); c++) {
            value_columns_.push_back(new ValueColumnState);
        }
    }
    for (size_t c = 0; c < value_metas.size() && IS_SUCC(ret); c++) {
        auto* col = value_columns_[c];
        col->chunk_meta = value_metas[c];
        col->file_data_buf_size = 1024;
        ret_read_len = 0;
        char* vbuf =
            (char*)mem_alloc(col->file_data_buf_size, MOD_CHUNK_READER);
        if (IS_NULL(vbuf)) return E_OOM;

        ret = read_file_->read(col->chunk_meta->offset_of_chunk_header_, vbuf,
                               col->file_data_buf_size, ret_read_len);
        if (IS_SUCC(ret) && ret_read_len < ChunkHeader::MIN_SERIALIZED_SIZE) {
            ret = E_TSFILE_CORRUPTED;
            mem_free(vbuf);
            break;
        }
        if (IS_SUCC(ret)) {
            col->in_stream.wrap_from(vbuf, ret_read_len);
            if (RET_FAIL(col->chunk_header.deserialize_from(col->in_stream))) {
                break;
            }
            col->chunk_visit_offset = col->in_stream.read_pos();
            if (RET_FAIL(alloc_compressor_and_decoder(
                    col->decoder, col->compressor,
                    col->chunk_header.encoding_type_,
                    col->chunk_header.data_type_,
                    col->chunk_header.compression_type_))) {
                break;
            }
        }
    }

    return ret;
}

bool AlignedChunkReader::has_more_data_multi() const {
    if (page_plan_built_) {
        if (current_page_loaded_) {
            return page_time_cursor_ < page_time_count_;
        }
        return current_page_plan_index_ < chunk_pages_.size();
    }
    if (prev_time_page_not_finish() || prev_any_value_page_not_finish_multi()) {
        return true;
    }
    if (time_chunk_visit_offset_ - time_chunk_header_.serialized_size_ <
        time_chunk_header_.data_size_) {
        return true;
    }
    for (const auto* col : value_columns_) {
        if (col->chunk_visit_offset - col->chunk_header.serialized_size_ <
            col->chunk_header.data_size_) {
            return true;
        }
    }
    return false;
}

bool AlignedChunkReader::prev_any_value_page_not_finish_multi() const {
    for (const auto* col : value_columns_) {
        if ((col->decoder && col->decoder->has_remaining(col->in)) ||
            col->in.has_remaining()) {
            return true;
        }
    }
    return false;
}

bool AlignedChunkReader::has_variable_length_value_column() const {
    for (const auto* col : value_columns_) {
        if (col->chunk_header.data_type_ == common::STRING ||
            col->chunk_header.data_type_ == common::TEXT ||
            col->chunk_header.data_type_ == common::BLOB) {
            return true;
        }
    }
    return false;
}

int AlignedChunkReader::count_non_null_prefix(
    const std::vector<uint8_t>& bitmap, int32_t row_limit) const {
    if (row_limit <= 0 || bitmap.empty()) {
        return 0;
    }
    const uint32_t mask_base = 1 << 7;
    int count = 0;
    for (int32_t i = 0; i < row_limit; i++) {
        if (((bitmap[i / 8] & 0xFF) & (mask_base >> (i % 8))) != 0) {
            count++;
        }
    }
    return count;
}

int AlignedChunkReader::decode_time_page_direct(
    const ChunkPageInfo& page_info, std::vector<int64_t>& out_times) {
    return decode_time_page_with(page_info, out_times, time_decoder_,
                                 time_compressor_);
}

// Worker-safe variant: uses caller-provided decoder + compressor instead of
// the shared time_decoder_/time_compressor_ members.  Used by the parallel
// time-page decode dispatch in decode_all_planned_pages.
int AlignedChunkReader::decode_time_page_with(const ChunkPageInfo& page_info,
                                              std::vector<int64_t>& out_times,
                                              Decoder* decoder,
                                              Compressor* compressor) {
    out_times.clear();
    if (page_info.time_compressed_size == 0) {
        return E_OK;
    }

    char stack_buf[4096];
    char* compressed_buf = stack_buf;
    bool heap = page_info.time_compressed_size > sizeof(stack_buf);
    if (heap) {
        compressed_buf = static_cast<char*>(common::mem_alloc(
            page_info.time_compressed_size, common::MOD_DEFAULT));
        if (compressed_buf == nullptr) {
            return E_OOM;
        }
    }

    int32_t read_len = 0;
    int ret = read_file_->read(page_info.time_file_offset, compressed_buf,
                               page_info.time_compressed_size, read_len);
    if (IS_FAIL(ret)) {
        if (heap) common::mem_free(compressed_buf);
        return ret;
    }
    // ReadFile::read() returns E_OK + short read_len on EOF; uncompressing
    // page_info.time_compressed_size from a buffer with uninitialised tail
    // bytes would feed garbage to the decompressor.
    if (read_len != static_cast<int32_t>(page_info.time_compressed_size)) {
        if (heap) common::mem_free(compressed_buf);
        return E_TSFILE_CORRUPTED;
    }

    char* uncompressed_buf = nullptr;
    uint32_t uncompressed_size = 0;
    if (RET_FAIL(compressor->reset(false))) {
        if (heap) common::mem_free(compressed_buf);
        return ret;
    }
    ret = compressor->uncompress(compressed_buf, page_info.time_compressed_size,
                                 uncompressed_buf, uncompressed_size);
    if (heap && compressed_buf != uncompressed_buf) {
        common::mem_free(compressed_buf);
    }
    if (IS_FAIL(ret) || uncompressed_size != page_info.time_uncompressed_size) {
        if (uncompressed_buf != nullptr) {
            compressor->after_uncompress(uncompressed_buf);
        }
        return E_TSFILE_CORRUPTED;
    }

    common::ByteStream in;
    in.wrap_from(uncompressed_buf, uncompressed_size);
    decoder->reset();
    const int batch_size = 1024;
    int64_t batch[batch_size];
    while (decoder->has_remaining(in)) {
        int actual = 0;
        if (RET_FAIL(
                decoder->read_batch_int64(batch, batch_size, actual, in))) {
            break;
        }
        if (actual == 0) {
            break;
        }
        out_times.insert(out_times.end(), batch, batch + actual);
    }
    compressor->after_uncompress(uncompressed_buf);
    return ret;
}

int AlignedChunkReader::build_page_plan(Filter* filter) {
    int ret = E_OK;
    chunk_pages_.clear();
    current_page_plan_index_ = 0;
    current_page_loaded_ = false;
    page_plan_built_ = false;

    const uint32_t num_cols = value_columns_.size();
    while (IS_SUCC(ret)) {
        if (time_chunk_visit_offset_ - time_chunk_header_.serialized_size_ >=
            time_chunk_header_.data_size_) {
            break;
        }

        if (RET_FAIL(get_cur_page_header(
                time_chunk_meta_, time_in_stream_, cur_time_page_header_,
                time_chunk_visit_offset_, time_chunk_header_))) {
            break;
        }
        if (cur_time_page_header_.compressed_size_ == 0 &&
            cur_time_page_header_.uncompressed_size_ == 0) {
            break;
        }

        ChunkPageInfo page_info;
        page_info.time_file_offset = time_chunk_meta_->offset_of_chunk_header_ +
                                     time_chunk_visit_offset_;
        page_info.time_compressed_size = cur_time_page_header_.compressed_size_;
        page_info.time_uncompressed_size =
            cur_time_page_header_.uncompressed_size_;
        page_info.value_file_offsets.resize(num_cols);
        page_info.value_compressed_sizes.resize(num_cols);
        page_info.value_uncompressed_sizes.resize(num_cols);

        for (uint32_t c = 0; c < num_cols && IS_SUCC(ret); c++) {
            auto* col = value_columns_[c];
            if (RET_FAIL(get_cur_page_header(
                    col->chunk_meta, col->in_stream, col->cur_page_header,
                    col->chunk_visit_offset, col->chunk_header,
                    &col->file_data_buf_size))) {
                break;
            }
            page_info.value_file_offsets[c] =
                col->chunk_meta->offset_of_chunk_header_ +
                col->chunk_visit_offset;
            page_info.value_compressed_sizes[c] =
                col->cur_page_header.compressed_size_;
            page_info.value_uncompressed_sizes[c] =
                col->cur_page_header.uncompressed_size_;
        }
        if (IS_FAIL(ret)) {
            break;
        }

        Statistic* stat = cur_time_page_header_.statistic_;
        if (filter == nullptr) {
            page_info.pass_type = PagePassType::FULL_PASS;
            page_info.row_begin = 0;
            page_info.row_end = stat != nullptr ? stat->count_ : 0;
        } else if (stat != nullptr && !filter->satisfy(stat)) {
            page_info.pass_type = PagePassType::SKIP;
        } else if (stat != nullptr && filter->contain_start_end_time(
                                          stat->start_time_, stat->end_time_)) {
            page_info.pass_type = PagePassType::FULL_PASS;
            page_info.row_begin = 0;
            page_info.row_end = stat->count_;
        } else {
            page_info.pass_type = PagePassType::BOUNDARY;
            std::vector<int64_t> times;
            if (RET_FAIL(decode_time_page_direct(page_info, times))) {
                break;
            }
            int32_t first = -1;
            int32_t last = -1;
            for (int32_t i = 0; i < static_cast<int32_t>(times.size()); i++) {
                if (filter->satisfy_start_end_time(times[i], times[i])) {
                    if (first < 0) first = i;
                    last = i;
                }
            }
            if (first >= 0) {
                page_info.row_begin = first;
                page_info.row_end = last + 1;
            } else {
                page_info.pass_type = PagePassType::SKIP;
            }
        }

        if (page_info.pass_type != PagePassType::SKIP) {
            if (page_info.row_end == 0) {
                std::vector<int64_t> times;
                if (RET_FAIL(decode_time_page_direct(page_info, times))) {
                    break;
                }
                page_info.row_end = static_cast<int32_t>(times.size());
            }
            if (page_info.row_begin < page_info.row_end) {
                chunk_pages_.push_back(std::move(page_info));
            }
        }

        time_chunk_visit_offset_ += cur_time_page_header_.compressed_size_;
        time_in_stream_.wrapped_buf_advance_read_pos(
            cur_time_page_header_.compressed_size_);
        for (uint32_t c = 0; c < num_cols; c++) {
            auto* col = value_columns_[c];
            col->chunk_visit_offset += col->cur_page_header.compressed_size_;
            col->in_stream.wrapped_buf_advance_read_pos(
                col->cur_page_header.compressed_size_);
        }
    }

    page_plan_built_ = IS_SUCC(ret);

    if (page_plan_built_) {
        per_page_times_.assign(chunk_pages_.size(), std::vector<int64_t>{});
        for (auto* col : value_columns_) {
            col->per_page_state.clear();
            col->per_page_state.resize(chunk_pages_.size());
        }
    }
    return ret;
}

void AlignedChunkReader::release_current_page_state() {
    time_predecoded_ = false;
    page_all_times_.clear();
    page_time_count_ = 0;
    page_time_cursor_ = 0;
    for (auto* col : value_columns_) {
        if (col->uncompressed_buf != nullptr && col->compressor != nullptr) {
            col->compressor->after_uncompress(col->uncompressed_buf);
            col->uncompressed_buf = nullptr;
        }
        col->notnull_bitmap.clear();
        col->cur_value_index = -1;
        col->in.reset();
        for (auto& pps : col->per_page_state) {
            pps.predecode_pa.destroy();
        }
        col->per_page_state.clear();
        col->pending_decoded_values.clear();
        col->pending_decoded_count = 0;
        col->pending_decoded_cursor = 0;
        col->pending_decoded = false;
    }
    per_page_times_.clear();
    current_page_loaded_ = false;
}

int AlignedChunkReader::decode_value_page_for_slot(uint32_t col_idx,
                                                   size_t page_idx) {
    const ChunkPageInfo& page_info = chunk_pages_[page_idx];
    auto* col = value_columns_[col_idx];
    auto& pps = col->per_page_state[page_idx];

    pps.notnull_bitmap.clear();
    pps.predecoded_values.clear();
    pps.predecoded_strings.clear();
    pps.predecoded_read_pos = 0;
    pps.predecoded_count = 0;
    pps.predecode_pa.destroy();

    if (page_info.value_compressed_sizes[col_idx] == 0) {
        return E_OK;
    }

    char stack_buf[4096];
    char* compressed_buf = stack_buf;
    bool heap = page_info.value_compressed_sizes[col_idx] > sizeof(stack_buf);
    if (heap) {
        compressed_buf = static_cast<char*>(common::mem_alloc(
            page_info.value_compressed_sizes[col_idx], common::MOD_DEFAULT));
        if (compressed_buf == nullptr) return E_OOM;
    }

    int32_t read_len = 0;
    int ret =
        read_file_->read(page_info.value_file_offsets[col_idx], compressed_buf,
                         page_info.value_compressed_sizes[col_idx], read_len);
    if (IS_FAIL(ret)) {
        if (heap) common::mem_free(compressed_buf);
        return ret;
    }
    if (read_len !=
        static_cast<int32_t>(page_info.value_compressed_sizes[col_idx])) {
        if (heap) common::mem_free(compressed_buf);
        return E_TSFILE_CORRUPTED;
    }

    char* uncompressed_buf = nullptr;
    uint32_t uncompressed_size = 0;
    if (RET_FAIL(col->compressor->reset(false))) {
        if (heap) common::mem_free(compressed_buf);
        return ret;
    }
    ret = col->compressor->uncompress(compressed_buf,
                                      page_info.value_compressed_sizes[col_idx],
                                      uncompressed_buf, uncompressed_size);
    if (heap && compressed_buf != uncompressed_buf) {
        common::mem_free(compressed_buf);
    }
    if (IS_FAIL(ret) ||
        uncompressed_size != page_info.value_uncompressed_sizes[col_idx]) {
        if (uncompressed_buf != nullptr) {
            col->compressor->after_uncompress(uncompressed_buf);
        }
        return E_TSFILE_CORRUPTED;
    }
    // The value page begins with a uint32 data_num followed by a bitmap of
    // ceil(data_num/8) bytes; a corrupt or truncated page that doesn't even
    // hold the data_num header would let read_ui32() walk past the buffer.
    if (uncompressed_size < sizeof(uint32_t)) {
        col->compressor->after_uncompress(uncompressed_buf);
        return E_TSFILE_CORRUPTED;
    }

    uint32_t offset = 0;
    uint32_t data_num = SerializationUtil::read_ui32(uncompressed_buf);
    offset += sizeof(uint32_t);
    uint32_t bitmap_bytes = (data_num + 7) / 8;
    if (uncompressed_size - offset < bitmap_bytes) {
        col->compressor->after_uncompress(uncompressed_buf);
        return E_TSFILE_CORRUPTED;
    }
    pps.notnull_bitmap.resize(bitmap_bytes);
    memcpy(pps.notnull_bitmap.data(), uncompressed_buf + offset, bitmap_bytes);
    offset += bitmap_bytes;

    char* value_buf = uncompressed_buf + offset;
    uint32_t value_buf_size = uncompressed_size - offset;
    common::ByteStream in;
    in.wrap_from(value_buf, value_buf_size);
    col->decoder->reset();

    auto dt = col->chunk_header.data_type_;
    int nonnull_total = count_non_null_prefix(pps.notnull_bitmap,
                                              static_cast<int32_t>(data_num));
    int prefix_nonnull =
        count_non_null_prefix(pps.notnull_bitmap, page_info.row_begin);
    pps.predecoded_read_pos = prefix_nonnull;

    auto cleanup = [&]() {
        col->compressor->after_uncompress(uncompressed_buf);
    };

    if (dt == common::STRING || dt == common::TEXT || dt == common::BLOB) {
        pps.predecode_pa.init(512, common::MOD_TSFILE_READER);
        pps.predecoded_strings.resize(nonnull_total);
        for (int i = 0; i < nonnull_total; i++) {
            if (RET_FAIL(col->decoder->read_String(pps.predecoded_strings[i],
                                                   pps.predecode_pa, in))) {
                cleanup();
                return ret;
            }
        }
        pps.predecoded_count = nonnull_total;
        cleanup();
        return E_OK;
    }

    if (nonnull_total == 0) {
        cleanup();
        return E_OK;
    }

    uint32_t elem_size = common::get_data_type_size(dt);
    pps.predecoded_values.resize(static_cast<size_t>(nonnull_total) *
                                 elem_size);
    int actual = 0;
    switch (dt) {
        case common::BOOLEAN: {
            bool* out = reinterpret_cast<bool*>(pps.predecoded_values.data());
            for (int i = 0; i < nonnull_total; i++) {
                if (RET_FAIL(col->decoder->read_boolean(out[i], in))) {
                    cleanup();
                    return ret;
                }
            }
            actual = nonnull_total;
            break;
        }
        case common::INT32:
        case common::DATE:
            if (RET_FAIL(col->decoder->read_batch_int32(
                    reinterpret_cast<int32_t*>(pps.predecoded_values.data()),
                    nonnull_total, actual, in))) {
                cleanup();
                return ret;
            }
            break;
        case common::INT64:
        case common::TIMESTAMP:
            if (RET_FAIL(col->decoder->read_batch_int64(
                    reinterpret_cast<int64_t*>(pps.predecoded_values.data()),
                    nonnull_total, actual, in))) {
                cleanup();
                return ret;
            }
            break;
        case common::FLOAT:
            if (RET_FAIL(col->decoder->read_batch_float(
                    reinterpret_cast<float*>(pps.predecoded_values.data()),
                    nonnull_total, actual, in))) {
                cleanup();
                return ret;
            }
            break;
        case common::DOUBLE:
            if (RET_FAIL(col->decoder->read_batch_double(
                    reinterpret_cast<double*>(pps.predecoded_values.data()),
                    nonnull_total, actual, in))) {
                cleanup();
                return ret;
            }
            break;
        default:
            cleanup();
            return E_NOT_SUPPORT;
    }
    pps.predecoded_count = actual;
    cleanup();
    return E_OK;
}

// Multi-thread path: one task per value column, each decoding all non-SKIP
// pages of that column serially.  Time pages dispatched as worker-bucketed
// strided tasks using per-worker decoder/compressor (filled from
// time_decoder_pool_ / time_compressor_pool_) so they don't contend on the
// shared time_decoder_/time_compressor_.
//
// Single-thread: do NOT pre-decode every page upfront — leave per_page_state
// empty so the scatter loop decodes on demand and releases after each page
// (see decode_page_lazy() / release_page_slot()).  Bounds memory to one page.
int AlignedChunkReader::decode_all_planned_pages() {
    if (chunk_pages_.empty()) return E_OK;

#ifdef ENABLE_THREADS
    if (decode_pool_ != nullptr && value_columns_.size() > 1) {
        // Lazily grow the per-worker time decoder/compressor pool.  Both
        // factories can return nullptr on OOM/unsupported config; without
        // checking, the worker task below dereferences null when calling
        // decode_time_page_with().
        size_t worker_count = decode_pool_->num_threads();
        if (time_decoder_pool_.size() < worker_count) {
            time_decoder_pool_.resize(worker_count, nullptr);
            time_compressor_pool_.resize(worker_count, nullptr);
            for (size_t w = 0; w < worker_count; w++) {
                if (time_decoder_pool_[w] == nullptr) {
                    time_decoder_pool_[w] =
                        DecoderFactory::alloc_time_decoder();
                    if (time_decoder_pool_[w] == nullptr) return E_OOM;
                }
                if (time_compressor_pool_[w] == nullptr) {
                    time_compressor_pool_[w] =
                        CompressorFactory::alloc_compressor(
                            time_chunk_header_.compression_type_);
                    if (time_compressor_pool_[w] == nullptr) return E_OOM;
                }
            }
        }

        std::vector<std::future<void>> futures;
        std::vector<int> col_rets(value_columns_.size(), E_OK);
        for (uint32_t c = 0; c < value_columns_.size(); c++) {
            int* col_ret = &col_rets[c];
            futures.push_back(decode_pool_->submit([this, c, col_ret]() {
                for (size_t p = 0; p < chunk_pages_.size(); p++) {
                    int r = decode_value_page_for_slot(c, p);
                    if (IS_FAIL(r)) {
                        *col_ret = r;
                        return;
                    }
                }
            }));
        }
        // Time pages dispatched in worker-sized chunks (one task per worker)
        // to amortize submit/wait overhead.  Stride for load balance.
        size_t time_task_count = std::min(worker_count, chunk_pages_.size());
        std::vector<int> time_rets(time_task_count, E_OK);
        for (size_t k = 0; k < time_task_count; k++) {
            int* tr = &time_rets[k];
            futures.push_back(decode_pool_->submit(
                [this, k, tr, time_task_count, worker_count]() {
                    size_t wid = common::ThreadPool::current_worker_id();
                    if (wid >= worker_count) wid = 0;
                    Decoder* dec = time_decoder_pool_[wid];
                    Compressor* comp = time_compressor_pool_[wid];
                    for (size_t p = k; p < chunk_pages_.size();
                         p += time_task_count) {
                        int r = decode_time_page_with(
                            chunk_pages_[p], per_page_times_[p], dec, comp);
                        if (IS_FAIL(r)) {
                            *tr = r;
                            return;
                        }
                    }
                }));
        }
        // Wait on each task's own future rather than draining the whole pool:
        // it is shared process-wide, so wait_all() would also block on
        // unrelated concurrent operations' tasks still in flight.
        for (auto& f : futures) f.get();
        for (auto r : time_rets) {
            if (IS_FAIL(r)) return r;
        }
        for (uint32_t c = 0; c < value_columns_.size(); c++) {
            if (IS_FAIL(col_rets[c])) return col_rets[c];
        }
        return E_OK;
    }
#endif
    // Single-thread: defer decode to scatter time.
    return E_OK;
}

// Decode time + all value columns for a single page slot on demand.
// Used by the single-thread path to keep memory bounded to one page.
int AlignedChunkReader::decode_page_lazy(size_t page_idx) {
    int ret = E_OK;
    if (RET_FAIL(decode_time_page_direct(chunk_pages_[page_idx],
                                         per_page_times_[page_idx]))) {
        return ret;
    }
    for (uint32_t c = 0; c < value_columns_.size(); c++) {
        if (RET_FAIL(decode_value_page_for_slot(c, page_idx))) {
            return ret;
        }
    }
    return E_OK;
}

// Release the decoded buffers of one page slot so they can be reused by the
// next page (keeps memory footprint bounded for the single-thread path).
void AlignedChunkReader::release_page_slot(size_t page_idx) {
    std::vector<int64_t>{}.swap(per_page_times_[page_idx]);
    for (auto* col : value_columns_) {
        if (page_idx >= col->per_page_state.size()) continue;
        auto& pps = col->per_page_state[page_idx];
        std::vector<uint8_t>{}.swap(pps.notnull_bitmap);
        std::vector<char>{}.swap(pps.predecoded_values);
        std::vector<common::String>{}.swap(pps.predecoded_strings);
        pps.predecode_pa.destroy();
        pps.predecoded_count = 0;
        pps.predecoded_read_pos = 0;
    }
}

int AlignedChunkReader::get_next_page_multi(TsBlock* ret_tsblock,
                                            Filter* oneshoot_filter,
                                            PageArena& pa) {
    int ret = E_OK;
    Filter* filter =
        (oneshoot_filter != nullptr ? oneshoot_filter : time_filter_);

    // Dispatch:
    //   - Multi-column with a thread pool → chunk-level pre-decode: one task
    //     per value column decodes that column's whole chunk up front, then the
    //     scatter loop bulk-memcpys.  decode_all_planned_pages() works for any
    //     column count.  (An earlier cutoff sent >6 columns down the serial
    //     path because per_page_state — the upfront predecode buffer — grows
    //     with column count and was feared to thrash cache; it still grows, so
    //     very wide aligned chunks are the case to watch if reads regress.)
    //   - Single column, or no thread pool → serial path: decode the current
    //     page's columns inline (multi_DECODE_TV_BATCH), no thread-pool
    //     fan-out.
#ifdef ENABLE_THREADS
    const bool use_chunk_level =
        decode_pool_ != nullptr && value_columns_.size() > 1;
#else
    const bool use_chunk_level = false;
#endif
    if (!use_chunk_level) {
        return get_next_page_multi_serial(ret_tsblock, filter, pa);
    }

    if (!page_plan_built_) {
        if (RET_FAIL(build_page_plan(filter))) {
            return ret;
        }
        if (RET_FAIL(decode_all_planned_pages())) {
            return ret;
        }
    }
    if (chunk_pages_.empty()) {
        return E_NO_MORE_DATA;
    }

    const uint32_t null_mask_base = 1 << 7;
    const uint32_t num_cols = value_columns_.size();
    RowAppender row_appender(ret_tsblock);
    // Detect single-thread lazy mode by whether decode_all_planned_pages left
    // per_page_times_ empty (it leaves slots empty when there's no pool).
    const bool single_thread_lazy = per_page_times_[0].empty();

    while (current_page_plan_index_ < chunk_pages_.size()) {
        const ChunkPageInfo& page_info = chunk_pages_[current_page_plan_index_];

        if (!current_page_loaded_) {
            if (single_thread_lazy) {
                if (RET_FAIL(decode_page_lazy(current_page_plan_index_))) {
                    return ret;
                }
            }
            page_time_cursor_ = page_info.row_begin;
            page_time_count_ = page_info.row_end;
            current_page_loaded_ = true;
        }
        const std::vector<int64_t>& times =
            per_page_times_[current_page_plan_index_];

        int32_t remaining_in_page = page_time_count_ - page_time_cursor_;
        uint32_t budget = row_appender.remaining();

        // Fast path: FULL_PASS page, no nulls in any value column, types
        // match destination, budget > 0.  Bulk-memcpys up to
        // min(budget, remaining_in_page) rows from page_time_cursor_; tail
        // pages of an SSI tsblock still take the memcpy path instead of
        // falling into the row-by-row scatter loop.
        bool can_bulk = page_info.pass_type == PagePassType::FULL_PASS &&
                        remaining_in_page > 0 && budget > 0;
        if (can_bulk) {
            for (uint32_t c = 0; c < num_cols; c++) {
                auto* col = value_columns_[c];
                auto& pps = col->per_page_state[current_page_plan_index_];
                auto dt = col->chunk_header.data_type_;
                if (dt == common::STRING || dt == common::TEXT ||
                    dt == common::BLOB ||
                    ret_tsblock->get_vector(c + 1)->get_vector_type() != dt ||
                    pps.predecoded_count != page_time_count_) {
                    can_bulk = false;
                    break;
                }
            }
        }

        if (can_bulk) {
            uint32_t bulk_count =
                std::min(budget, static_cast<uint32_t>(remaining_in_page));
            size_t time_byte_off =
                static_cast<size_t>(page_time_cursor_) * sizeof(int64_t);
            // Bulk-append both bytes AND row count for every Vector.
            // Skipping add_row_nums() would leave each Vector's row_num_
            // at 0 while the TsBlock-level row_count_ jumped to bulk_count;
            // fill_trailling_nulls() would then mark every just-written
            // row as null, and column iterators would report the wrong
            // length.
            common::Vector* time_vec = ret_tsblock->get_vector(0);
            time_vec->get_value_data().append_fixed_value(
                reinterpret_cast<const char*>(times.data()) + time_byte_off,
                bulk_count * sizeof(int64_t));
            time_vec->add_row_nums(bulk_count);
            for (uint32_t c = 0; c < num_cols; c++) {
                auto* col = value_columns_[c];
                auto& pps = col->per_page_state[current_page_plan_index_];
                uint32_t elem_size =
                    common::get_data_type_size(col->chunk_header.data_type_);
                common::Vector* vec = ret_tsblock->get_vector(c + 1);
                vec->get_value_data().append_fixed_value(
                    pps.predecoded_values.data() +
                        static_cast<size_t>(page_time_cursor_) * elem_size,
                    bulk_count * elem_size);
                vec->add_row_nums(bulk_count);
            }
            row_appender.add_rows(bulk_count);
            page_time_cursor_ += bulk_count;
            if (page_time_cursor_ >= page_time_count_) {
                if (single_thread_lazy) {
                    release_page_slot(current_page_plan_index_);
                }
                current_page_plan_index_++;
                current_page_loaded_ = false;
                continue;
            }
            // Budget exhausted mid-page; caller will drain and resume.
            return E_OK;
        }

        // Slow path: row-by-row.  Handles null bitmap, type promotion,
        // BOUNDARY pages, and partial-page E_OVERFLOW.
        // BOUNDARY pages: build_page_plan compressed the page to the
        // [first-hit, last-hit] range, but timestamps inside that range may
        // still fail the filter (e.g. TimeIn({2, 8}) leaves 3..7 unmatched).
        // Re-apply the filter per timestamp here, advancing predecoded
        // read positions for skipped non-null rows so the cursor stays
        // aligned with the page's value layout.
        const bool boundary_filter =
            page_info.pass_type == PagePassType::BOUNDARY && filter != nullptr;
        while (page_time_cursor_ < page_time_count_) {
            if (row_appender.remaining() == 0) {
                return E_OK;
            }
            int64_t ts = times[page_time_cursor_];
            if (boundary_filter && !filter->satisfy_start_end_time(ts, ts)) {
                for (uint32_t c = 0; c < num_cols; c++) {
                    auto* col = value_columns_[c];
                    auto& pps = col->per_page_state[current_page_plan_index_];
                    // An empty notnull_bitmap means this column carried no data
                    // for the page (a missing / sparse aligned measurement), so
                    // every row is null; otherwise consult the per-row bit.
                    bool is_null = true;
                    if (!pps.notnull_bitmap.empty()) {
                        is_null =
                            ((pps.notnull_bitmap[page_time_cursor_ / 8] &
                              0xFF) &
                             (null_mask_base >> (page_time_cursor_ % 8))) == 0;
                    }
                    if (!is_null) pps.predecoded_read_pos++;
                }
                page_time_cursor_++;
                continue;
            }
            if (UNLIKELY(!row_appender.add_row())) {
                return E_OK;
            }
            row_appender.append(0, reinterpret_cast<char*>(&ts), sizeof(ts));

            for (uint32_t c = 0; c < num_cols; c++) {
                auto* col = value_columns_[c];
                auto& pps = col->per_page_state[current_page_plan_index_];
                bool is_null = true;
                if (!pps.notnull_bitmap.empty()) {
                    is_null =
                        ((pps.notnull_bitmap[page_time_cursor_ / 8] & 0xFF) &
                         (null_mask_base >> (page_time_cursor_ % 8))) == 0;
                }
                if (is_null) {
                    row_appender.append_null(c + 1);
                    continue;
                }
                if (col->chunk_header.data_type_ == common::STRING ||
                    col->chunk_header.data_type_ == common::TEXT ||
                    col->chunk_header.data_type_ == common::BLOB) {
                    const common::String& value =
                        pps.predecoded_strings[pps.predecoded_read_pos++];
                    row_appender.append(c + 1, value.buf_, value.len_);
                } else {
                    uint32_t elem_size = common::get_data_type_size(
                        col->chunk_header.data_type_);
                    row_appender.append(
                        c + 1,
                        pps.predecoded_values.data() +
                            static_cast<size_t>(pps.predecoded_read_pos++) *
                                elem_size,
                        elem_size);
                }
            }
            page_time_cursor_++;
        }

        if (single_thread_lazy) {
            release_page_slot(current_page_plan_index_);
        }
        current_page_plan_index_++;
        current_page_loaded_ = false;
    }
    return E_NO_MORE_DATA;
}

int AlignedChunkReader::get_next_page_multi_serial(TsBlock* ret_tsblock,
                                                   Filter* filter,
                                                   PageArena& pa) {
    int ret = E_OK;
    bool pt = prev_time_page_not_finish();
    bool pv = prev_any_value_page_not_finish_multi();
    if (pt && pv) {
        ret =
            decode_time_value_buf_into_tsblock_multi(ret_tsblock, filter, &pa);
        return ret;
    }
    if (!pt && !pv) {
        while (IS_SUCC(ret)) {
            if (RET_FAIL(get_cur_page_header(
                    time_chunk_meta_, time_in_stream_, cur_time_page_header_,
                    time_chunk_visit_offset_, time_chunk_header_))) {
                break;
            }
            for (size_t c = 0; c < value_columns_.size() && IS_SUCC(ret); c++) {
                auto* col = value_columns_[c];
                if (RET_FAIL(get_cur_page_header(
                        col->chunk_meta, col->in_stream, col->cur_page_header,
                        col->chunk_visit_offset, col->chunk_header,
                        &col->file_data_buf_size))) {
                }
            }
            if (IS_FAIL(ret)) break;
            if (cur_page_statisify_filter_multi(filter)) break;
            if (RET_FAIL(skip_cur_page_multi())) break;
            if (!has_more_data()) {
                ret = E_NO_MORE_DATA;
                break;
            }
        }
        if (IS_SUCC(ret)) {
            ret = decode_cur_time_page_data();
            if (IS_SUCC(ret)) ret = decode_cur_value_pages_multi();
        }
    }
    if (IS_SUCC(ret)) {
        ret =
            decode_time_value_buf_into_tsblock_multi(ret_tsblock, filter, &pa);
    }
    return ret;
}

bool AlignedChunkReader::cur_page_statisify_filter_multi(Filter* filter) {
    bool time_satisfy = filter == nullptr ||
                        cur_time_page_header_.statistic_ == nullptr ||
                        filter->satisfy(cur_time_page_header_.statistic_);
    return time_satisfy;
}

int AlignedChunkReader::skip_cur_page_multi() {
    time_chunk_visit_offset_ += cur_time_page_header_.compressed_size_;
    time_in_stream_.wrapped_buf_advance_read_pos(
        cur_time_page_header_.compressed_size_);
    for (auto* col : value_columns_) {
        col->chunk_visit_offset += col->cur_page_header.compressed_size_;
        col->in_stream.wrapped_buf_advance_read_pos(
            col->cur_page_header.compressed_size_);
    }
    return E_OK;
}

int AlignedChunkReader::decode_cur_value_pages_multi() {
    int ret = E_OK;
    // Phase 1: Serial IO — ensure each column's page data is in memory.
    for (size_t c = 0; c < value_columns_.size() && IS_SUCC(ret); c++) {
        ret = ensure_value_page_loaded(*value_columns_[c]);
    }
    if (IS_FAIL(ret)) return ret;

    // Phase 2: decompress + parse bitmap + reset decoder for each column's
    // current page, inline.  This serial path now only runs for single-column
    // reads or when no thread pool exists — multi-column reads with a pool take
    // the chunk-level path (decode_all_planned_pages), so there is no per-page
    // thread-pool fan-out here anymore.  predecode=false lets the scatter loop
    // (multi_DECODE_TV_BATCH) decode inline, which has better cache locality
    // when there is no parallelism to amortize an extra predecode buffer write.
    for (size_t c = 0; c < value_columns_.size() && IS_SUCC(ret); c++) {
        ret = decompress_and_parse_value_page(*value_columns_[c], false);
    }
    return ret;
}

int AlignedChunkReader::decode_cur_value_page_data_for(ValueColumnState& col) {
    int ret = E_OK;

    // Step 1: ensure full page data is loaded
    if (col.in_stream.remaining_size() < col.cur_page_header.compressed_size_) {
        if (RET_FAIL(read_from_file_and_rewrap(
                col.in_stream, col.chunk_meta, col.chunk_visit_offset,
                col.file_data_buf_size,
                col.cur_page_header.compressed_size_))) {
            return ret;
        }
    }

    if (col.cur_page_header.compressed_size_ == 0) {
        col.in.wrap_from(nullptr, 0);
        return E_OK;
    }

    // Step 2: uncompress
    char* compressed_buf =
        col.in_stream.get_wrapped_buf() + col.in_stream.read_pos();
    uint32_t compressed_size = col.cur_page_header.compressed_size_;
    col.in_stream.wrapped_buf_advance_read_pos(compressed_size);
    col.chunk_visit_offset += compressed_size;

    char* uncompressed_buf = nullptr;
    uint32_t uncompressed_size = 0;
    if (RET_FAIL(col.compressor->reset(false))) {
        return ret;
    }
    if (RET_FAIL(col.compressor->uncompress(compressed_buf, compressed_size,
                                            uncompressed_buf,
                                            uncompressed_size))) {
        return ret;
    }
    col.uncompressed_buf = uncompressed_buf;

    if (uncompressed_size != col.cur_page_header.uncompressed_size_) {
        return E_TSFILE_CORRUPTED;
    }

    // Step 3: parse bitmap + value data
    if (uncompressed_size < sizeof(uint32_t)) return E_TSFILE_CORRUPTED;
    uint32_t offset = 0;
    uint32_t data_num = SerializationUtil::read_ui32(uncompressed_buf);
    offset += sizeof(uint32_t);
    uint32_t bitmap_bytes = (data_num + 7) / 8;
    if (uncompressed_size - offset < bitmap_bytes) return E_TSFILE_CORRUPTED;
    col.notnull_bitmap.resize(bitmap_bytes);
    memcpy(col.notnull_bitmap.data(), uncompressed_buf + offset, bitmap_bytes);
    offset += bitmap_bytes;
    col.cur_value_index = -1;

    char* value_buf = uncompressed_buf + offset;
    uint32_t value_buf_size = uncompressed_size - offset;
    col.decoder->reset();
    col.in.wrap_from(value_buf, value_buf_size);
    return ret;
}

int AlignedChunkReader::ensure_value_page_loaded(ValueColumnState& col) {
    int ret = E_OK;
    if (col.in_stream.remaining_size() < col.cur_page_header.compressed_size_) {
        if (RET_FAIL(read_from_file_and_rewrap(
                col.in_stream, col.chunk_meta, col.chunk_visit_offset,
                col.file_data_buf_size,
                col.cur_page_header.compressed_size_))) {
            return ret;
        }
    }
    return ret;
}

int AlignedChunkReader::decompress_and_parse_value_page(ValueColumnState& col,
                                                        bool predecode) {
    int ret = E_OK;

    if (col.cur_page_header.compressed_size_ == 0) {
        col.in.wrap_from(nullptr, 0);
        return E_OK;
    }

    // Decompress
    char* compressed_buf =
        col.in_stream.get_wrapped_buf() + col.in_stream.read_pos();
    uint32_t compressed_size = col.cur_page_header.compressed_size_;
    col.in_stream.wrapped_buf_advance_read_pos(compressed_size);
    col.chunk_visit_offset += compressed_size;

    char* uncompressed_buf = nullptr;
    uint32_t uncompressed_size = 0;
    if (RET_FAIL(col.compressor->reset(false))) {
        return ret;
    }
    if (RET_FAIL(col.compressor->uncompress(compressed_buf, compressed_size,
                                            uncompressed_buf,
                                            uncompressed_size))) {
        return ret;
    }
    col.uncompressed_buf = uncompressed_buf;

    if (uncompressed_size != col.cur_page_header.uncompressed_size_) {
        return E_TSFILE_CORRUPTED;
    }

    // Parse bitmap + value data
    if (uncompressed_size < sizeof(uint32_t)) return E_TSFILE_CORRUPTED;
    uint32_t offset = 0;
    uint32_t data_num = SerializationUtil::read_ui32(uncompressed_buf);
    offset += sizeof(uint32_t);
    uint32_t bitmap_bytes = (data_num + 7) / 8;
    if (uncompressed_size - offset < bitmap_bytes) return E_TSFILE_CORRUPTED;
    col.notnull_bitmap.resize(bitmap_bytes);
    memcpy(col.notnull_bitmap.data(), uncompressed_buf + offset, bitmap_bytes);
    offset += bitmap_bytes;
    col.cur_value_index = -1;

    char* value_buf = uncompressed_buf + offset;
    uint32_t value_buf_size = uncompressed_size - offset;
    col.decoder->reset();
    col.in.wrap_from(value_buf, value_buf_size);

    // Pre-decode all non-null values into pending_decoded_values so the
    // scatter loop (multi_DECODE_TV_BATCH) just memcpys instead of calling
    // the decoder.  Moves the expensive int64/double decode into the worker
    // task so it runs in parallel.  Only handles fixed-length types — strings
    // stay on the inline-decode path.
    col.pending_decoded = false;
    col.pending_decoded_count = 0;
    col.pending_decoded_cursor = 0;
    auto dt = col.chunk_header.data_type_;
    if (predecode && dt != common::STRING && dt != common::TEXT &&
        dt != common::BLOB) {
        int nonnull_total = 0;
        for (uint32_t i = 0; i < data_num; i++) {
            if ((col.notnull_bitmap[i / 8] & (0x80 >> (i % 8))) != 0) {
                nonnull_total++;
            }
        }
        if (nonnull_total > 0) {
            uint32_t elem_size = common::get_data_type_size(dt);
            col.pending_decoded_values.resize(
                static_cast<size_t>(nonnull_total) * elem_size);
            int actual = 0;
            int rret = common::E_OK;
            switch (dt) {
                case common::BOOLEAN: {
                    bool* out = reinterpret_cast<bool*>(
                        col.pending_decoded_values.data());
                    for (int i = 0; i < nonnull_total; i++) {
                        bool v;
                        if (col.decoder->read_boolean(v, col.in) !=
                            common::E_OK) {
                            rret = common::E_OUT_OF_RANGE;
                            break;
                        }
                        out[i] = v;
                    }
                    actual = nonnull_total;
                    break;
                }
                case common::INT32:
                case common::DATE:
                    rret = col.decoder->read_batch_int32(
                        reinterpret_cast<int32_t*>(
                            col.pending_decoded_values.data()),
                        nonnull_total, actual, col.in);
                    break;
                case common::INT64:
                case common::TIMESTAMP:
                    rret = col.decoder->read_batch_int64(
                        reinterpret_cast<int64_t*>(
                            col.pending_decoded_values.data()),
                        nonnull_total, actual, col.in);
                    break;
                case common::FLOAT:
                    rret = col.decoder->read_batch_float(
                        reinterpret_cast<float*>(
                            col.pending_decoded_values.data()),
                        nonnull_total, actual, col.in);
                    break;
                case common::DOUBLE:
                    rret = col.decoder->read_batch_double(
                        reinterpret_cast<double*>(
                            col.pending_decoded_values.data()),
                        nonnull_total, actual, col.in);
                    break;
                default:
                    rret = common::E_OUT_OF_RANGE;
            }
            if (rret == common::E_OK && actual == nonnull_total) {
                col.pending_decoded_count = nonnull_total;
                col.pending_decoded = true;
            }
        } else {
            col.pending_decoded = true;  // empty page is trivially predecoded
        }
    }
    return ret;
}

int AlignedChunkReader::decode_time_value_buf_into_tsblock_multi(
    TsBlock*& ret_tsblock, Filter* filter, PageArena* pa) {
    int ret = E_OK;
    RowAppender row_appender(ret_tsblock);
    ret = multi_DECODE_TV_BATCH(ret_tsblock, row_appender, filter, pa);

    // Release uncompressed buffers if pages are done
    if (ret != E_OVERFLOW) {
        if (time_uncompressed_buf_ != nullptr) {
            time_compressor_->after_uncompress(time_uncompressed_buf_);
            time_uncompressed_buf_ = nullptr;
        }
        for (auto* col : value_columns_) {
            if (col->uncompressed_buf != nullptr) {
                col->compressor->after_uncompress(col->uncompressed_buf);
                col->uncompressed_buf = nullptr;
            }
            // The time stream and bitmap define the page's row/value count.
            // Once the page is fully processed, bytes left in an all-null
            // value stream are only encoder terminators or padding and must
            // not make has_more_data_multi() treat the page as unfinished.
            col->in.reset();
            col->notnull_bitmap.clear();
            col->notnull_bitmap.shrink_to_fit();
        }
        if (!prev_time_page_not_finish()) {
            time_in_.reset();
        }
    } else {
        ret = E_OK;
    }
    return ret;
}

int AlignedChunkReader::multi_DECODE_TV_BATCH(TsBlock* ret_tsblock,
                                              RowAppender& row_appender,
                                              Filter* filter, PageArena* pa) {
    int ret = E_OK;
    const int BATCH = 129;
    int64_t times[BATCH];
    const uint32_t null_mask_base = 1 << 7;
    const uint32_t num_cols = value_columns_.size();

    while (time_decoder_->has_remaining(time_in_)) {
        // Cap each pass to what the appender can still hold; mirrors the fix
        // in ChunkReader's per-type batch loops.  A blanket "remaining < BATCH
        // → E_OVERFLOW" made progress impossible whenever the caller handed
        // us a TsBlock with capacity below BATCH (e.g. small per-block sizes
        // in multi-chunk queries).
        int eff_batch =
            std::min(BATCH, static_cast<int>(row_appender.remaining()));
        if (eff_batch <= 0) {
            ret = E_OVERFLOW;
            break;
        }

        // ── Phase 1: Decode a batch of timestamps ──
        int time_count = 0;
        if (RET_FAIL(time_decoder_->read_batch_int64(times, eff_batch,
                                                     time_count, time_in_))) {
            break;
        }
        if (time_count == 0) break;

        // ── Phase 2: Apply time filter ──
        bool time_mask[BATCH];
        bool block_all_pass = (filter == nullptr);
        int pass_count = time_count;
        if (!block_all_pass) {
            pass_count =
                filter->satisfy_batch_time(times, time_count, time_mask);
        }

        // ── Phase 3: Per-column null check + value decode ──
        // For each column, compute null flags and decode non-null values.
        // We store decoded values in column-specific buffers.
        // Max 8 bytes per value, 129 values per batch.
        struct ColBatch {
            bool is_null[BATCH];
            int nonnull_count;
            // Value buffer for fixed-width types — up to 129 * 8 bytes
            char val_buf[BATCH * 8];
            int val_count;
            // Variable-length values for STRING/TEXT/BLOB columns.  Only
            // populated when the column's data_type_ is variable; their
            // bufs are owned by the caller-provided PageArena.
            std::vector<common::String> str_vals;
        };
        // One ColBatch per value column.
        std::vector<ColBatch> col_batches(num_cols);

        for (uint32_t c = 0; c < num_cols; c++) {
            auto* col = value_columns_[c];
            auto& cb = col_batches[c];
            cb.nonnull_count = 0;
            cb.val_count = 0;
            for (int i = 0; i < time_count; i++) {
                int vi = col->cur_value_index + 1 + i;
                if (col->notnull_bitmap.empty() ||
                    ((col->notnull_bitmap[vi / 8] & 0xFF) &
                     (null_mask_base >> (vi % 8))) == 0) {
                    cb.is_null[i] = true;
                } else {
                    cb.is_null[i] = false;
                    cb.nonnull_count++;
                }
            }

            // Skip values if no rows pass time filter.  Skip/read errors and
            // short reads (decoder returned fewer values than the bitmap
            // promised) must abort; otherwise the input stream is left
            // mid-value and later batches would decode garbage from
            // misaligned bytes.
            if (pass_count == 0 && cb.nonnull_count > 0) {
                int dret = common::E_OK;
                int sk = 0;
                switch (col->chunk_header.data_type_) {
                    case common::BOOLEAN: {
                        bool dummy;
                        for (sk = 0; sk < cb.nonnull_count; sk++) {
                            dret = col->decoder->read_boolean(dummy, col->in);
                            if (dret != common::E_OK) break;
                        }
                        break;
                    }
                    case common::INT32:
                    case common::DATE:
                        dret = col->decoder->skip_int32(cb.nonnull_count, sk,
                                                        col->in);
                        break;
                    case common::INT64:
                    case common::TIMESTAMP:
                        dret = col->decoder->skip_int64(cb.nonnull_count, sk,
                                                        col->in);
                        break;
                    case common::FLOAT:
                        dret = col->decoder->skip_float(cb.nonnull_count, sk,
                                                        col->in);
                        break;
                    case common::DOUBLE:
                        dret = col->decoder->skip_double(cb.nonnull_count, sk,
                                                         col->in);
                        break;
                    case common::STRING:
                    case common::TEXT:
                    case common::BLOB: {
                        // The decoder has no fast skip for var-length strings;
                        // reading + discarding is the only way to advance the
                        // input stream past the row's payload.
                        common::String tmp;
                        for (sk = 0; sk < cb.nonnull_count; sk++) {
                            dret = col->decoder->read_String(tmp, *pa, col->in);
                            if (dret != common::E_OK) break;
                        }
                        break;
                    }
                    default:
                        ret = E_TSFILE_CORRUPTED;
                        break;
                }
                if (ret != common::E_OK) break;
                if (dret != common::E_OK) {
                    ret = dret;
                    break;
                }
                if (sk != cb.nonnull_count) {
                    ret = E_TSFILE_CORRUPTED;
                    break;
                }
                cb.nonnull_count = 0;  // bytes consumed cleanly
            }

            // Decode non-null values.  Fast path: values were predecoded
            // into col->pending_decoded_values by the parallel worker — just
            // memcpy the slice for this batch.  Fallback: call the decoder
            // inline (used for STRING/TEXT/BLOB and when predecode was
            // skipped).
            if (cb.nonnull_count > 0) {
                if (col->pending_decoded) {
                    uint32_t elem_size = common::get_data_type_size(
                        col->chunk_header.data_type_);
                    memcpy(
                        cb.val_buf,
                        col->pending_decoded_values.data() +
                            static_cast<size_t>(col->pending_decoded_cursor) *
                                elem_size,
                        static_cast<size_t>(cb.nonnull_count) * elem_size);
                    col->pending_decoded_cursor += cb.nonnull_count;
                    cb.val_count = cb.nonnull_count;
                } else {
                    int dret = common::E_OK;
                    switch (col->chunk_header.data_type_) {
                        case common::BOOLEAN: {
                            bool* out = reinterpret_cast<bool*>(cb.val_buf);
                            cb.val_count = 0;
                            for (int s = 0; s < cb.nonnull_count; s++) {
                                bool v;
                                dret = col->decoder->read_boolean(v, col->in);
                                if (dret != common::E_OK) break;
                                out[cb.val_count++] = v;
                            }
                            break;
                        }
                        case common::INT32:
                        case common::DATE:
                            dret = col->decoder->read_batch_int32(
                                reinterpret_cast<int32_t*>(cb.val_buf),
                                cb.nonnull_count, cb.val_count, col->in);
                            break;
                        case common::INT64:
                        case common::TIMESTAMP:
                            dret = col->decoder->read_batch_int64(
                                reinterpret_cast<int64_t*>(cb.val_buf),
                                cb.nonnull_count, cb.val_count, col->in);
                            break;
                        case common::FLOAT:
                            dret = col->decoder->read_batch_float(
                                reinterpret_cast<float*>(cb.val_buf),
                                cb.nonnull_count, cb.val_count, col->in);
                            break;
                        case common::DOUBLE:
                            dret = col->decoder->read_batch_double(
                                reinterpret_cast<double*>(cb.val_buf),
                                cb.nonnull_count, cb.val_count, col->in);
                            break;
                        case common::STRING:
                        case common::TEXT:
                        case common::BLOB: {
                            // Variable-length payload doesn't fit in
                            // cb.val_buf; pull each value into str_vals and
                            // let the scatter loop index by val_count.
                            cb.str_vals.resize(cb.nonnull_count);
                            cb.val_count = 0;
                            for (int s = 0; s < cb.nonnull_count; s++) {
                                dret = col->decoder->read_String(cb.str_vals[s],
                                                                 *pa, col->in);
                                if (dret != common::E_OK) break;
                                cb.val_count++;
                            }
                            break;
                        }
                        default:
                            break;
                    }
                    // Any decoder error, or a short decode that produced
                    // fewer values than the bitmap promised, indicates a
                    // corrupt page; propagate immediately so the scatter
                    // loop doesn't read uninitialised cb.val_buf bytes.
                    if (dret != common::E_OK) {
                        ret = dret;
                        break;
                    }
                    if (col->chunk_header.data_type_ != common::STRING &&
                        col->chunk_header.data_type_ != common::TEXT &&
                        col->chunk_header.data_type_ != common::BLOB &&
                        cb.val_count != cb.nonnull_count) {
                        ret = E_TSFILE_CORRUPTED;
                        break;
                    }
                }
            }
        }
        if (ret != E_OK) break;

        // ── Phase 4: Skip if no rows pass ──
        if (pass_count == 0) {
            for (uint32_t c = 0; c < num_cols; c++) {
                value_columns_[c]->cur_value_index += time_count;
            }
            continue;
        }

        // ── Phase 5: Scatter into TsBlock ──

        // Fast path: all rows pass filter AND all columns have no nulls
        // → batch memcpy directly into Vector buffers.  STRING/TEXT/BLOB
        // columns have variable-width payload and live in cb.str_vals, not
        // cb.val_buf, so they must take the slow scatter path.
        if (pass_count == time_count) {
            bool all_nonnull_and_fixed_size = true;
            for (uint32_t c = 0; c < num_cols; c++) {
                auto dt = value_columns_[c]->chunk_header.data_type_;
                if (col_batches[c].nonnull_count != time_count ||
                    dt == common::STRING || dt == common::TEXT ||
                    dt == common::BLOB) {
                    all_nonnull_and_fixed_size = false;
                    break;
                }
            }
            if (all_nonnull_and_fixed_size) {
                // Batch append time column (bytes + row count); see the
                // chunk-level bulk path above for why add_row_nums() is
                // required alongside append_fixed_value().
                common::Vector* time_vec = ret_tsblock->get_vector(0);
                time_vec->get_value_data().append_fixed_value(
                    (const char*)times,
                    static_cast<uint32_t>(time_count) * sizeof(int64_t));
                time_vec->add_row_nums(static_cast<uint32_t>(time_count));
                // Batch append each value column
                for (uint32_t c = 0; c < num_cols; c++) {
                    auto& cb = col_batches[c];
                    auto* col = value_columns_[c];
                    uint32_t elem_size = common::get_data_type_size(
                        col->chunk_header.data_type_);
                    common::Vector* vec = ret_tsblock->get_vector(c + 1);
                    vec->get_value_data().append_fixed_value(
                        cb.val_buf,
                        static_cast<uint32_t>(cb.val_count) * elem_size);
                    vec->add_row_nums(static_cast<uint32_t>(cb.val_count));
                    col->cur_value_index += time_count;
                }
                row_appender.add_rows(static_cast<uint32_t>(time_count));
                continue;
            }
        }

        // Slow path: per-row scatter (has filter or has nulls or strings)
        std::vector<int> val_idx(num_cols, 0);

        for (int i = 0; i < time_count; i++) {
            bool passes = block_all_pass || time_mask[i];

            if (!passes) {
                for (uint32_t c = 0; c < num_cols; c++) {
                    value_columns_[c]->cur_value_index++;
                    if (!col_batches[c].is_null[i]) val_idx[c]++;
                }
                continue;
            }

            if (UNLIKELY(!row_appender.add_row())) {
                ret = E_OVERFLOW;
                break;
            }

            row_appender.append(0, (char*)&times[i], sizeof(int64_t));

            for (uint32_t c = 0; c < num_cols; c++) {
                value_columns_[c]->cur_value_index++;
                auto& cb = col_batches[c];
                auto* col = value_columns_[c];

                if (cb.is_null[i]) {
                    row_appender.append_null(c + 1);
                } else {
                    auto dt = col->chunk_header.data_type_;
                    if (dt == common::STRING || dt == common::TEXT ||
                        dt == common::BLOB) {
                        const common::String& sv = cb.str_vals[val_idx[c]];
                        row_appender.append(c + 1, sv.buf_, sv.len_);
                    } else {
                        uint32_t elem_size = common::get_data_type_size(dt);
                        row_appender.append(c + 1,
                                            cb.val_buf + val_idx[c] * elem_size,
                                            elem_size);
                    }
                    val_idx[c]++;
                }
            }
        }
        if (ret != E_OK) break;
    }
    return ret;
}

}  // end namespace storage
