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

#ifndef ENCODING_TS2DIFF_DECODER_H
#define ENCODING_TS2DIFF_DECODER_H

#include <sys/types.h>

#include <cmath>
#include <cstddef>
#include <cstring>
#include <vector>

#include "common/allocator/alloc_base.h"
#include "common/allocator/byte_stream.h"
#include "decoder.h"
#include "ts2diff_wire_format.h"
#include "utils/util_define.h"

#ifdef ENABLE_SIMD
#include "simde/x86/avx2.h"
#endif

namespace storage {

// ============================================================================
// SIMD batch decode helpers (INT32)
// ============================================================================
#ifdef ENABLE_SIMD

// Decode 4 INT32 values from bit-packed data using SIMD gather + shift.
// @in:        pointer to the start of packed bit data for the block
// @bit_width: bits per delta value
// @delta_min: minimum delta offset for this block
// @index:     current position within the block (0-based, among write_index_
//             deltas)
// @base:      the previous reconstructed value (for prefix-sum)
// @out:       output array (4 values written)
// Returns:    the last reconstructed value (new base for next group)
static inline int32_t simd_decode_4_i32(const uint8_t* in, int32_t bit_width,
                                        int32_t delta_min, int32_t index,
                                        int32_t base, int32_t out[4]) {
    static const simde__m128i SHUF_REV4 = simde_mm_setr_epi8(
        3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12);

    const simde__m128i VMIN4 = simde_mm_set1_epi32(delta_min);

    int32_t pos0 = index * bit_width;
    int32_t pos[4] = {pos0, pos0 + bit_width, pos0 + 2 * bit_width,
                      pos0 + 3 * bit_width};
    int32_t bidx[4] = {pos[0] >> 3, pos[1] >> 3, pos[2] >> 3, pos[3] >> 3};
    int32_t off[4] = {pos[0] & 7, pos[1] & 7, pos[2] & 7, pos[3] & 7};

    simde__m128i IDX = simde_mm_setr_epi32(bidx[0], bidx[1], bidx[2], bidx[3]);
    simde__m128i OFF = simde_mm_setr_epi32(off[0], off[1], off[2], off[3]);

    simde__m128i V4;

    if (bit_width <= 16) {
        int rshift = 32 - bit_width;
        simde__m128i w32_le = simde_mm_i32gather_epi32((const int*)in, IDX, 1);
        simde__m128i w32_be = simde_mm_shuffle_epi8(w32_le, SHUF_REV4);
        simde__m128i U32 = simde_mm_sllv_epi32(w32_be, OFF);
        simde__m128i RS32 = simde_mm_set1_epi32(rshift);
        V4 = simde_mm_srlv_epi32(U32, RS32);
    } else {
        static const simde__m256i SHUF_REV8 = simde_mm256_setr_epi8(
            7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3,
            2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8);
        int rshift = 64 - bit_width;
        simde__m256i w64_le =
            simde_mm256_i32gather_epi64((const int64_t*)in, IDX, 1);
        simde__m256i w64_be = simde_mm256_shuffle_epi8(w64_le, SHUF_REV8);
        simde__m256i OFF64 = simde_mm256_cvtepu32_epi64(OFF);
        simde__m256i U64 = simde_mm256_sllv_epi64(w64_be, OFF64);
        simde__m256i V64 =
            simde_mm256_srl_epi64(U64, simde_mm_cvtsi32_si128(rshift));
        simde__m256i perm = simde_mm256_setr_epi32(0, 2, 4, 6, 0, 0, 0, 0);
        simde__m256i comp = simde_mm256_permutevar8x32_epi32(V64, perm);
        V4 = simde_mm256_castsi256_si128(comp);
    }

    // Add delta_min
    V4 = simde_mm_add_epi32(V4, VMIN4);

    // Prefix sum to reconstruct absolute values
    simde__m128i t;
    t = simde_mm_slli_si128(V4, 4);
    V4 = simde_mm_add_epi32(V4, t);
    t = simde_mm_slli_si128(V4, 8);
    V4 = simde_mm_add_epi32(V4, t);

    // Add base
    simde__m128i C4 = simde_mm_set1_epi32(base);
    V4 = simde_mm_add_epi32(V4, C4);

    simde_mm_storeu_si128((simde__m128i*)out, V4);
    return out[3];
}

// Decode 4 INT64 values from bit-packed data using SIMD.
static inline int64_t simd_decode_4_i64(const uint8_t* in, int32_t bit_width,
                                        int64_t delta_min, int32_t index,
                                        int64_t base, int64_t out[4]) {
    static const simde__m256i SHUF_REV8 = simde_mm256_setr_epi8(
        7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2,
        1, 0, 15, 14, 13, 12, 11, 10, 9, 8);

    const simde__m256i VMIN4 = simde_mm256_set1_epi64x(delta_min);

    int32_t pos0 = index * bit_width;
    int32_t pos[4] = {pos0, pos0 + bit_width, pos0 + 2 * bit_width,
                      pos0 + 3 * bit_width};
    int32_t bidx[4] = {pos[0] >> 3, pos[1] >> 3, pos[2] >> 3, pos[3] >> 3};
    int32_t off[4] = {pos[0] & 7, pos[1] & 7, pos[2] & 7, pos[3] & 7};

    simde__m128i IDX = simde_mm_setr_epi32(bidx[0], bidx[1], bidx[2], bidx[3]);

    int rshift = 64 - bit_width;
    simde__m256i w64_le =
        simde_mm256_i32gather_epi64((const int64_t*)in, IDX, 1);
    simde__m256i w64_be = simde_mm256_shuffle_epi8(w64_le, SHUF_REV8);
    simde__m256i OFF64 = simde_mm256_cvtepu32_epi64(
        simde_mm_setr_epi32(off[0], off[1], off[2], off[3]));
    simde__m256i U64 = simde_mm256_sllv_epi64(w64_be, OFF64);
    simde__m256i V64 =
        simde_mm256_srl_epi64(U64, simde_mm_cvtsi32_si128(rshift));

    // Add delta_min
    V64 = simde_mm256_add_epi64(V64, VMIN4);

    // Prefix sum (64-bit, 4 lanes)
    simde__m256i t;
    // shift by 8 bytes = 1 lane
    t = simde_mm256_slli_si256(V64, 8);
    V64 = simde_mm256_add_epi64(V64, t);
    // cross-lane: add lane[1] to lane[2] and lane[3]
    // Extract high 128 bits, add broadcast of element[1] to both elements
    int64_t tmp_buf[4];
    simde_mm256_storeu_si256((simde__m256i*)tmp_buf, V64);
    tmp_buf[2] += tmp_buf[1];
    tmp_buf[3] += tmp_buf[1];
    V64 = simde_mm256_loadu_si256((const simde__m256i*)tmp_buf);

    // Add base
    simde__m256i C4 = simde_mm256_set1_epi64x(base);
    V64 = simde_mm256_add_epi64(V64, C4);

    simde_mm256_storeu_si256((simde__m256i*)out, V64);
    return out[3];
}

#endif  // ENABLE_SIMD

// ============================================================================
// Scalar batch decode helpers
// ============================================================================

// Scalar: extract one value from bit-packed data.
// @data:      pointer to packed bits (NOT advanced; caller handles position)
// @bit_pos:   bit offset from start of data
// @bit_width: bits per value
static inline int64_t scalar_read_bits(const uint8_t* data, int32_t bit_pos,
                                       int32_t bit_width) {
    int64_t value = 0;
    int bits = bit_width;
    int byte_idx = bit_pos >> 3;
    int bit_offset = bit_pos & 7;
    int bits_avail = 8 - bit_offset;

    while (bits > 0) {
        if (bits >= bits_avail) {
            uint8_t d = data[byte_idx] & ((1 << bits_avail) - 1);
            value = (value << bits_avail) | d;
            bits -= bits_avail;
            byte_idx++;
            bits_avail = 8;
        } else {
            uint8_t d =
                (data[byte_idx] >> (bits_avail - bits)) & ((1 << bits) - 1);
            value = (value << bits) | d;
            bits = 0;
        }
    }
    return value;
}

namespace ts2diff_java_detail {

inline bool bitmap_marked(const std::vector<uint8_t>& bm, int idx) {
    if (bm.empty()) {
        return false;
    }
    size_t byte_idx = static_cast<size_t>(idx / 8);
    if (byte_idx >= bm.size()) {
        return false;
    }
    return (bm[byte_idx] & static_cast<uint8_t>(1u << (idx % 8))) != 0;
}

// Page-level FLOAT/DOUBLE metadata, parsed exactly once per page.
// Layout (see cpp/docs/ts2diff-float-double-wire-format.md):
//   form 1: [maxPointNumber varint]
//   form 2: [Integer.MAX_VALUE][count][scaled bitmap][maxPointNumber]
//   form 3: [Integer.MAX_VALUE-1][count][scaled bitmap][raw bitmap]
//           [maxPointNumber]
// A leading 0x00 byte is the normal encoding of maxPointNumber = 0 (the
// Java Ts2Diff builder default), not a legacy marker.  maxPointNumber is
// whatever the varint carries: Java applies no upper bound, and a value so
// large that Math.pow overflows simply yields maxPointValue = +inf, which
// decodes every value through the raw-bits form.
//
// Inputs that do not match this grammar are a format error (E_DECODE_ERR);
// a stream that ends mid-field propagates the underlying read error.
struct PageMeta {
    bool has_scaled_bm = false;
    bool has_raw_bm = false;
    std::vector<uint8_t> scaled_bm;
    std::vector<uint8_t> raw_bm;
    int max_point_number = 0;
    int page_value_count = 0;
};

inline int read_page_meta(common::ByteStream& in, PageMeta& meta) {
    int ret = common::E_OK;
    uint32_t tag = 0;
    if (RET_FAIL(common::SerializationUtil::read_var_uint(tag, in))) {
        return ret;
    }
    if (tag == FLAG_SCALED_VALUE_OVERFLOW ||
        tag == FLAG_ORIGINAL_VALUE_OVERFLOW) {
        uint32_t count = 0;
        if (RET_FAIL(common::SerializationUtil::read_var_uint(count, in))) {
            return ret;
        }
        if (count == 0 || count > 0x7FFFFFFFu) {
            return common::E_DECODE_ERR;
        }
        const int bm_len = static_cast<int>(count) / 8 + 1;
        // Guard the allocation: a tiny corrupt page must not trigger a
        // bitmap-sized allocation the stream cannot possibly back.  Form 3
        // carries two bitmaps of bm_len bytes each, so the required byte
        // count is bm_len * bitmaps, not bm_len.
        const uint64_t bitmaps = tag == FLAG_ORIGINAL_VALUE_OVERFLOW ? 2 : 1;
        if (static_cast<uint64_t>(bm_len) * bitmaps >
            static_cast<uint64_t>(in.remaining_size())) {
            return common::E_DECODE_ERR;
        }
        meta.has_scaled_bm = true;
        meta.scaled_bm.resize(static_cast<size_t>(bm_len), 0);
        uint32_t read_len = 0;
        if (RET_FAIL(in.read_buf(meta.scaled_bm.data(),
                                 static_cast<uint32_t>(bm_len), read_len))) {
            return ret;
        }
        if (read_len != static_cast<uint32_t>(bm_len)) {
            return common::E_DECODE_ERR;
        }
        if (tag == FLAG_ORIGINAL_VALUE_OVERFLOW) {
            meta.has_raw_bm = true;
            meta.raw_bm.resize(static_cast<size_t>(bm_len), 0);
            if (RET_FAIL(in.read_buf(meta.raw_bm.data(),
                                     static_cast<uint32_t>(bm_len),
                                     read_len))) {
                return ret;
            }
            if (read_len != static_cast<uint32_t>(bm_len)) {
                return common::E_DECODE_ERR;
            }
        }
        meta.page_value_count = static_cast<int>(count);
        uint32_t mpn = 0;
        if (RET_FAIL(common::SerializationUtil::read_var_uint(mpn, in))) {
            return ret;
        }
        meta.max_point_number = static_cast<int>(mpn);
    } else {
        meta.max_point_number = static_cast<int>(tag);
        meta.page_value_count = 0;  // unknown until the blocks are decoded
    }
    return common::E_OK;
}

}  // namespace ts2diff_java_detail

// ============================================================================
// TS2DIFFDecoder template
// ============================================================================
template <typename T>
class TS2DIFFDecoder : public Decoder {
   public:
    TS2DIFFDecoder() { reset(); }
    ~TS2DIFFDecoder() override {}

    void reset() override {
        write_index_ = -1;
        bits_left_ = 0;
        stored_value_ = 0;
        buffer_ = 0;
        delta_min_ = 0;
        first_value_ = 0;
        previous_value_ = 0;
        bit_width_ = 0;
        current_index_ = 0;
        header_peeked_ = false;
        read_error_ = common::E_OK;
        max_values_ = -1;
    }

    FORCE_INLINE bool has_remaining(const common::ByteStream& buffer) override {
        if (buffer.has_remaining()) return true;
        return header_peeked_ || bits_left_ != 0 ||
               (current_index_ <= write_index_ && write_index_ != -1 &&
                current_index_ != 0);
    }

    // Reads the 4+4 byte block header.  A failure latches read_error_ so
    // the value-returning decode() path can surface it, and is returned
    // directly for the batch entry points.
    //
    // writeIndex is bounded by the bytes the stream can actually supply,
    // not by the encoder's BLOCK_DEFAULT_SIZE: Java exposes block-size
    // constructors, so blocks larger than 129 values are valid input.
    int read_header(common::ByteStream& in) {
        int32_t write_index = 0;
        int32_t bit_width = 0;
        int ret = common::SerializationUtil::read_i32(write_index, in);
        if (ret == common::E_OK) {
            ret = common::SerializationUtil::read_i32(bit_width, in);
        }
        if (ret != common::E_OK) {
            read_error_ = ret;
            return ret;
        }
        const int64_t block_bytes_64 =
            (static_cast<int64_t>(write_index) * bit_width + 7) / 8;
        // The value-count bound is computed in int64: write_index + 1
        // overflows for write_index == INT32_MAX and would wrap negative,
        // silently passing the comparison.
        if (write_index < 0 || bit_width < 0 ||
            bit_width > (int)sizeof(T) * 8 ||
            (max_values_ >= 0 && static_cast<int64_t>(write_index) + 1 >
                                     static_cast<int64_t>(max_values_)) ||
            block_bytes_64 > static_cast<int64_t>(in.remaining_size())) {
            read_error_ = common::E_DECODE_ERR;
            return common::E_DECODE_ERR;
        }
        write_index_ = write_index;
        bit_width_ = bit_width;
        return common::E_OK;
    }

    void set_max_values(int max_values) { max_values_ = max_values; }

    // If empty, cache 8 bits from in_stream to 'buffer_'.
    void read_byte_if_empty(common::ByteStream& in) {
        if (bits_left_ == 0) {
            uint32_t read_len = 0;
            in.read_buf(&buffer_, 1, read_len);
            if (read_len != 0) {
                bits_left_ = 8;
            }
        }
    }

    int64_t read_long(int bits, common::ByteStream& in) {
        int64_t value = 0;
        while (bits > 0) {
            read_byte_if_empty(in);
            // The stream ended with bits still owed, so the page is
            // truncated or desynced.  read_header's availability check
            // grants slack for the delta_min/first_value fields, so a
            // truncated page can reach here.
            if (bits_left_ == 0 && !in.has_remaining()) {
                read_error_ = common::E_DECODE_ERR;
                current_index_ = 0;
                write_index_ = 0;
                break;
            }
            if (bits > bits_left_ || bits == 8) {
                // Take only the bits_left_ "least significant" bits.
                uint8_t d = (uint8_t)(buffer_ & ((1 << bits_left_) - 1));
                value = (value << bits_left_) + (d & 0xFF);
                bits -= bits_left_;
                bits_left_ = 0;
            } else {
                // Shift to correct position and take only least significant
                // bits.
                uint8_t d =
                    (uint8_t)((((uint8_t)buffer_) >> (bits_left_ - bits)) &
                              ((1 << bits) - 1));
                value = (value << bits) + (d & 0xFF);
                bits_left_ -= bits;
                bits = 0;
            }
            if (bits <= 0 && current_index_ == 0) {
                break;
            }
        }
        return value;
    }

    T decode(common::ByteStream& in);
    int read_boolean(bool& ret_value, common::ByteStream& in) override;
    int read_int32(int32_t& ret_value, common::ByteStream& in) override;
    int read_int64(int64_t& ret_value, common::ByteStream& in) override;
    int read_float(float& ret_value, common::ByteStream& in) override;
    int read_double(double& ret_value, common::ByteStream& in) override;
    int read_String(common::String& ret_value, common::PageArena& pa,
                    common::ByteStream& in) override;

    int read_batch_int32(int32_t* out, int capacity, int& actual,
                         common::ByteStream& in) override;
    int read_batch_int64(int64_t* out, int capacity, int& actual,
                         common::ByteStream& in) override;
    int skip_int32(int count, int& skipped, common::ByteStream& in) override;
    int skip_int64(int count, int& skipped, common::ByteStream& in) override;

    bool peek_next_block_range_int64(common::ByteStream& in, int64_t& block_min,
                                     int64_t& block_max,
                                     int& block_count) override;
    int skip_peeked_block_int64(common::ByteStream& in, int& skipped) override;

   public:
    T first_value_;
    T previous_value_;
    T stored_value_;
    T delta_min_;
    uint8_t buffer_;
    int bits_left_;
    int bit_width_;
    int write_index_;
    int current_index_;
    bool header_peeked_;
    // Sticky: a block header or fixed-field read failed.  decode() returns
    // a value rather than an error code, so its callers consult this.
    int read_error_{common::E_OK};
    int max_values_{-1};
};

// ============================================================================
// Per-value decode (unchanged)
// ============================================================================

template <>
inline int32_t TS2DIFFDecoder<int32_t>::decode(common::ByteStream& in) {
    int32_t ret_value = stored_value_;
    if (UNLIKELY(current_index_ == 0)) {
        if (read_header(in) != common::E_OK) {
            // Poison the block state so callers stop; value is undefined
            // for corrupt input.
            write_index_ = 0;
            current_index_ = 0;
            return ret_value;
        }
        int fixed_ret = common::SerializationUtil::read_i32(delta_min_, in);
        if (fixed_ret == common::E_OK) {
            fixed_ret = common::SerializationUtil::read_i32(first_value_, in);
        }
        if (fixed_ret != common::E_OK) {
            // Surface the stream's own error rather than relabelling a
            // short read as a format violation.
            read_error_ = fixed_ret;
            return ret_value;
        }
        ret_value = first_value_;
        bits_left_ = 0;
        buffer_ = 0;
        if (write_index_ == 0) {
            current_index_ = 0;
        } else {
            current_index_ = 1;
        }
        return ret_value;
    }
    // although it seems we are reading an int64, bit_width_ guarantees
    // that it does not overflow int32
    stored_value_ = read_long(bit_width_, in);
    ret_value = stored_value_ + first_value_ + delta_min_;
    if (current_index_++ >= write_index_) {
        current_index_ = 0;
        bits_left_ = 0;
    }
    first_value_ = ret_value;
    return ret_value;
}

template <>
inline int64_t TS2DIFFDecoder<int64_t>::decode(common::ByteStream& in) {
    int64_t ret_value = stored_value_;
    if (UNLIKELY(current_index_ == 0)) {
        if (read_header(in) != common::E_OK) {
            write_index_ = 0;
            current_index_ = 0;
            return ret_value;
        }
        int fixed_ret = common::SerializationUtil::read_i64(delta_min_, in);
        if (fixed_ret == common::E_OK) {
            fixed_ret = common::SerializationUtil::read_i64(first_value_, in);
        }
        if (fixed_ret != common::E_OK) {
            // Surface the stream's own error rather than relabelling a
            // short read as a format violation.
            read_error_ = fixed_ret;
            return ret_value;
        }
        ret_value = first_value_;
        if (write_index_ == 0) {
            current_index_ = 0;
        } else {
            current_index_ = 1;
        }
        return ret_value;
    }
    stored_value_ = (int64_t)read_long(bit_width_, in);
    ret_value = stored_value_ + first_value_ + delta_min_;
    first_value_ = ret_value;
    if (current_index_++ >= write_index_) {
        current_index_ = 0;
        bits_left_ = 0;
    }
    return ret_value;
}

// ============================================================================
// Batch decode: INT32
// Decodes one full block (up to 129 values) per call using SIMD when enabled.
// ============================================================================

template <>
inline int TS2DIFFDecoder<int32_t>::read_batch_int32(int32_t* out, int capacity,
                                                     int& actual,
                                                     common::ByteStream& in) {
    actual = 0;

    while (actual < capacity && has_remaining(in)) {
        // If we are mid-block (current_index_ != 0), finish it per-value.
        if (current_index_ != 0) {
            while (actual < capacity && current_index_ != 0 &&
                   has_remaining(in)) {
                out[actual++] = decode(in);
            }
            continue;
        }

        // Start of a new block — read header
        int hdr_ret = read_header(in);
        if (hdr_ret != common::E_OK) {
            return hdr_ret;
        }
        int fixed_ret = common::SerializationUtil::read_i32(delta_min_, in);
        if (fixed_ret == common::E_OK) {
            fixed_ret = common::SerializationUtil::read_i32(first_value_, in);
        }
        if (fixed_ret != common::E_OK) {
            read_error_ = fixed_ret;
            return fixed_ret;
        }
        bits_left_ = 0;
        buffer_ = 0;

        // Output first_value
        if (actual >= capacity) {
            // Must consume first_value next time; set state for per-value path
            current_index_ = 0;
            // We already consumed the header; push first_value as stored
            // and let the next call to decode() handle it.
            // Actually, we need to handle this: rewind is not possible.
            // So we output first_value and accept going 1 over capacity.
        }
        out[actual++] = first_value_;

        if (write_index_ == 0) {
            // Block has only first_value, no deltas
            current_index_ = 0;
            continue;
        }

        int32_t remaining = write_index_;
        if (actual + remaining > capacity) {
            // Block won't fit in output. Fall back to per-value decode.
            // Stream is at packed data start; bits_left_/buffer_ are reset.
            current_index_ = 1;
            continue;
        }
        if (!in.is_wrapped()) {
            // SIMD/scalar block decode below requires a contiguous wrapped
            // buffer.  For a paged ByteStream, drop down to per-value
            // decode the same way the doesn't-fit branch does.
            current_index_ = 1;
            continue;
        }

        // Full block decode. Validate against corrupt headers before
        // advancing the read position — a bogus bit_width_ or write_index_
        // could compute a block_bytes that overflows the int32_t multiply
        // or runs past the wrapped buffer.
        if (UNLIKELY(write_index_ < 0 || bit_width_ < 0 || bit_width_ > 32)) {
            return common::E_DECODE_ERR;
        }
        const int64_t block_bytes_64 =
            (static_cast<int64_t>(write_index_) * bit_width_ + 7) / 8;
        if (UNLIKELY(block_bytes_64 >
                     static_cast<int64_t>(in.remaining_size()))) {
            return common::E_DECODE_ERR;
        }
        if (UNLIKELY(block_bytes_64 > INT32_MAX)) {
            // This path indexes the packed buffer with int32 offsets.  A
            // block that large is still valid input, so fall back to the
            // per-value path rather than rejecting it.
            current_index_ = 1;
            continue;
        }
        const int32_t block_bytes = static_cast<int32_t>(block_bytes_64);
        const uint8_t* blk_ptr =
            (const uint8_t*)in.get_wrapped_buf() + in.read_pos();
        in.wrapped_buf_advance_read_pos(static_cast<uint32_t>(block_bytes));

        int32_t prev = first_value_;
        int32_t i = 0;

#ifdef ENABLE_SIMD
        // SIMD path: decode 8 values at a time (2 groups of 4)
        for (; i + 7 < remaining; i += 8) {
            int32_t need_bytes = ((i + 7) * bit_width_ + bit_width_ + 7) / 8 +
                                 (bit_width_ > 16 ? 8 : 4);
            if (need_bytes > block_bytes) break;

            int32_t grp_out[8];
            prev = simd_decode_4_i32(blk_ptr, bit_width_, delta_min_, i, prev,
                                     grp_out);
            prev = simd_decode_4_i32(blk_ptr, bit_width_, delta_min_, i + 4,
                                     prev, grp_out + 4);

            memcpy(out + actual, grp_out, 8 * sizeof(int32_t));
            actual += 8;
        }
#endif

        // Scalar tail
        int32_t bit_pos = i * bit_width_;
        for (; i < remaining; ++i) {
            int64_t delta = scalar_read_bits(blk_ptr, bit_pos, bit_width_);
            bit_pos += bit_width_;
            int32_t val = (int32_t)delta + prev + delta_min_;
            prev = val;
            out[actual++] = val;
        }

        // Block done, reset state
        first_value_ = prev;
        current_index_ = 0;
    }

    return common::E_OK;
}

// ============================================================================
// Batch decode: INT64
// ============================================================================

template <>
inline int TS2DIFFDecoder<int64_t>::read_batch_int64(int64_t* out, int capacity,
                                                     int& actual,
                                                     common::ByteStream& in) {
    actual = 0;

    while (actual < capacity && has_remaining(in)) {
        // If mid-block, finish per-value
        if (current_index_ != 0) {
            while (actual < capacity && current_index_ != 0 &&
                   has_remaining(in)) {
                out[actual++] = decode(in);
            }
            continue;
        }

        // Start of a new block
        if (!header_peeked_) {
            const int hdr_ret = read_header(in);
            if (hdr_ret != common::E_OK) {
                return hdr_ret;
            }
            int fixed_ret = common::SerializationUtil::read_i64(delta_min_, in);
            if (fixed_ret == common::E_OK) {
                fixed_ret =
                    common::SerializationUtil::read_i64(first_value_, in);
            }
            if (fixed_ret != common::E_OK) {
                read_error_ = fixed_ret;
                return fixed_ret;
            }
            bits_left_ = 0;
            buffer_ = 0;
        }
        header_peeked_ = false;

        out[actual++] = first_value_;

        if (write_index_ == 0) {
            current_index_ = 0;
            continue;
        }

        int32_t remaining = write_index_;
        if (actual + remaining > capacity) {
            // Block won't fit in output. Fall back to per-value decode.
            // Stream is at packed data start; bits_left_/buffer_ are reset.
            current_index_ = 1;
            continue;
        }
        if (!in.is_wrapped()) {
            // SIMD/scalar block decode below requires a contiguous wrapped
            // buffer.  Page-backed ByteStreams must use the per-value path.
            current_index_ = 1;
            continue;
        }

        // Validate against corrupt headers (see int32 path).
        if (UNLIKELY(write_index_ < 0 || bit_width_ < 0 || bit_width_ > 64)) {
            return common::E_DECODE_ERR;
        }
        const int64_t block_bytes_64 =
            (static_cast<int64_t>(write_index_) * bit_width_ + 7) / 8;
        if (UNLIKELY(block_bytes_64 >
                     static_cast<int64_t>(in.remaining_size()))) {
            return common::E_DECODE_ERR;
        }
        if (UNLIKELY(block_bytes_64 > INT32_MAX)) {
            // See the int32 path: int32 packed-buffer offsets, so a block
            // this large falls back to per-value decode instead of being
            // rejected.
            current_index_ = 1;
            continue;
        }
        const int32_t block_bytes = static_cast<int32_t>(block_bytes_64);
        // Direct pointer into the wrapped ByteStream buffer.
        const uint8_t* blk_ptr =
            (const uint8_t*)in.get_wrapped_buf() + in.read_pos();
        in.wrapped_buf_advance_read_pos(static_cast<uint32_t>(block_bytes));

        int64_t prev = first_value_;
        int32_t i = 0;

        // An evenly spaced timestamp block has no packed residual data. Build
        // the arithmetic progression directly instead of entering the generic
        // bit-extraction path (whose SIMD guard requires readable input bytes).
        if (bit_width_ == 0) {
#ifdef ENABLE_SIMD
            if (remaining >= 4) {
                int64_t value1 = prev + delta_min_;
                int64_t value2 = value1 + delta_min_;
                int64_t value3 = value2 + delta_min_;
                int64_t value4 = value3 + delta_min_;
                simde__m256i values =
                    simde_mm256_set_epi64x(value4, value3, value2, value1);

                simde__m256i step = simde_mm256_set1_epi64x(delta_min_);
                step = simde_mm256_add_epi64(step, step);
                step = simde_mm256_add_epi64(step, step);

                for (; i + 3 < remaining; i += 4) {
                    simde_mm256_storeu_si256(
                        reinterpret_cast<simde__m256i*>(out + actual), values);
                    actual += 4;
                    values = simde_mm256_add_epi64(values, step);
                }
                prev = out[actual - 1];
            }
#endif

            for (; i < remaining; ++i) {
                prev += delta_min_;
                out[actual++] = prev;
            }

            first_value_ = prev;
            current_index_ = 0;
            continue;
        }

#ifdef ENABLE_SIMD
        // SIMD path: decode 4 INT64 values at a time
        for (; i + 3 < remaining; i += 4) {
            int32_t need_bytes =
                ((i + 3) * bit_width_ + bit_width_ + 7) / 8 + 8;
            if (need_bytes > block_bytes) break;

            int64_t grp_out[4];
            prev = simd_decode_4_i64(blk_ptr, bit_width_, delta_min_, i, prev,
                                     grp_out);
            memcpy(out + actual, grp_out, 4 * sizeof(int64_t));
            actual += 4;
        }
#endif

        // Scalar tail
        int32_t bit_pos = i * bit_width_;
        for (; i < remaining; ++i) {
            int64_t delta = scalar_read_bits(blk_ptr, bit_pos, bit_width_);
            bit_pos += bit_width_;
            int64_t val = delta + prev + delta_min_;
            prev = val;
            out[actual++] = val;
        }

        first_value_ = prev;
        current_index_ = 0;
    }

    return common::E_OK;
}

// ============================================================================
// Skip: INT32 — read header only, jump over packed data
// ============================================================================

template <>
inline int TS2DIFFDecoder<int32_t>::skip_int32(int count, int& skipped,
                                               common::ByteStream& in) {
    skipped = 0;

    // If mid-block, finish current block per-value
    while (skipped < count && current_index_ != 0 && has_remaining(in)) {
        decode(in);
        ++skipped;
    }

    while (skipped < count && has_remaining(in)) {
        int32_t wi = 0, bw = 0, dm = 0, fv = 0;
        // The header reads must succeed as a group: a truncated stream
        // would otherwise leave stale stack values in wi/bw.
        int rc = common::SerializationUtil::read_i32(wi, in);
        if (rc == common::E_OK) {
            rc = common::SerializationUtil::read_i32(bw, in);
        }
        if (rc == common::E_OK) {
            rc = common::SerializationUtil::read_i32(dm, in);
        }
        if (rc == common::E_OK) {
            rc = common::SerializationUtil::read_i32(fv, in);
        }
        if (rc != common::E_OK) {
            return rc;
        }

        // Same availability bound as read_header (writeIndex is not
        // capped by BLOCK_DEFAULT_SIZE); computed in int64 so a corrupt
        // header cannot overflow the multiply.
        const int64_t skip_bytes_64 = (static_cast<int64_t>(wi) * bw + 7) / 8;
        if (wi < 0 || bw < 0 || bw > 32 ||
            skip_bytes_64 > static_cast<int64_t>(in.remaining_size())) {
            return common::E_DECODE_ERR;
        }
        const int32_t skip_bytes = static_cast<int32_t>(skip_bytes_64);

        int32_t block_vals = wi + 1;
        bits_left_ = 0;
        buffer_ = 0;

        if (count - skipped >= block_vals) {
            // Whole-block fast path: jump over packed body.
            in.wrapped_buf_advance_read_pos(skip_bytes);
            skipped += block_vals;
            current_index_ = 0;
            write_index_ = -1;
        } else {
            // Partial block: reinstate decoder state as if we'd just
            // emitted first_value_ from decode(), bump skipped by 1,
            // then per-value decode the remaining count, leaving the
            // rest of the block intact for the next decode() call.
            write_index_ = wi;
            bit_width_ = bw;
            delta_min_ = dm;
            first_value_ = fv;
            current_index_ = (wi == 0) ? 0 : 1;
            ++skipped;
            while (skipped < count && current_index_ != 0 &&
                   has_remaining(in)) {
                decode(in);
                ++skipped;
            }
        }
    }

    return common::E_OK;
}

// ============================================================================
// Skip: INT64
// ============================================================================

template <>
inline int TS2DIFFDecoder<int64_t>::skip_int64(int count, int& skipped,
                                               common::ByteStream& in) {
    skipped = 0;

    while (skipped < count && current_index_ != 0 && has_remaining(in)) {
        decode(in);
        ++skipped;
    }

    while (skipped < count && has_remaining(in)) {
        int32_t wi = 0, bw = 0;
        int64_t dm = 0, fv = 0;
        // The header reads must succeed as a group: a truncated stream
        // would otherwise leave stale stack values in wi/bw.
        int rc = common::SerializationUtil::read_i32(wi, in);
        if (rc == common::E_OK) {
            rc = common::SerializationUtil::read_i32(bw, in);
        }
        if (rc == common::E_OK) {
            rc = common::SerializationUtil::read_i64(dm, in);
        }
        if (rc == common::E_OK) {
            rc = common::SerializationUtil::read_i64(fv, in);
        }
        if (rc != common::E_OK) {
            return rc;
        }

        // Same availability bound as read_header (writeIndex is not
        // capped by BLOCK_DEFAULT_SIZE); computed in int64 so a corrupt
        // header cannot overflow the multiply.
        const int64_t skip_bytes_64 = (static_cast<int64_t>(wi) * bw + 7) / 8;
        if (wi < 0 || bw < 0 || bw > 64 ||
            skip_bytes_64 > static_cast<int64_t>(in.remaining_size())) {
            return common::E_DECODE_ERR;
        }
        const int32_t skip_bytes = static_cast<int32_t>(skip_bytes_64);

        int32_t block_vals = wi + 1;
        bits_left_ = 0;
        buffer_ = 0;

        if (count - skipped >= block_vals) {
            in.wrapped_buf_advance_read_pos(skip_bytes);
            skipped += block_vals;
            current_index_ = 0;
            write_index_ = -1;
        } else {
            write_index_ = wi;
            bit_width_ = bw;
            delta_min_ = dm;
            first_value_ = fv;
            current_index_ = (wi == 0) ? 0 : 1;
            ++skipped;
            while (skipped < count && current_index_ != 0 &&
                   has_remaining(in)) {
                decode(in);
                ++skipped;
            }
        }
    }

    return common::E_OK;
}

// ============================================================================
// Block-level filter check: peek header and compute value range
// ============================================================================

template <>
inline bool TS2DIFFDecoder<int64_t>::peek_next_block_range_int64(
    common::ByteStream& in, int64_t& block_min, int64_t& block_max,
    int& block_count) {
    // Precondition: this must only be driven on the monotonically-increasing
    // time column (all callers invoke it via time_decoder_).  The block_min =
    // first_value / block_max = next-block-first_value shortcuts below rely on
    // that ordering; an unsorted INT64 *value* column that happens to use
    // TS_2DIFF would get a wrong range here, so it must never be called on a
    // value decoder (value decoders decode normally and never call this).
    if (current_index_ != 0 || !has_remaining(in)) return false;

    if (read_header(in) != common::E_OK) {
        // Reports "no next block with a usable range", so the caller uses
        // the regular per-value path.  This is deliberately a bool: an
        // error code would convert to true and make callers act on an
        // unset range.
        return false;
    }
    int fixed_ret = common::SerializationUtil::read_i64(delta_min_, in);
    if (fixed_ret == common::E_OK) {
        fixed_ret = common::SerializationUtil::read_i64(first_value_, in);
    }
    if (fixed_ret != common::E_OK) {
        read_error_ = fixed_ret;
        return false;
    }
    bits_left_ = 0;
    buffer_ = 0;

    block_min = first_value_;
    block_count = write_index_ + 1;

    // Look-ahead: since timestamps are monotonically increasing, the true
    // block_max is the last timestamp, which equals next block's first_value_.
    // The next block header starts at read_pos + packed_bytes. first_value_ is
    // at offset 16 within the header
    // (write_index_(4)+bit_width_(4)+delta_min_(8)). We read it via raw pointer
    // so the stream position is not consumed.
    // int64 arithmetic, matching skip_peeked_block_int64: read_header bounds
    // the packed size by the stream length only, so write_index_ * bit_width_
    // can exceed INT32_MAX on a huge page.
    const int64_t packed_bytes =
        (static_cast<int64_t>(write_index_) * bit_width_ + 7) / 8;
    if (in.remaining_size() >= static_cast<uint64_t>(packed_bytes) + 24) {
        char* next_fv_ptr =
            in.get_wrapped_buf() + in.read_pos() + packed_bytes + 16;
        block_max = (int64_t)common::SerializationUtil::read_ui64(next_fv_ptr);
    } else {
        // Last block in page: fall back to conservative estimate.
        if (write_index_ == 0 || bit_width_ == 0) {
            block_max = first_value_ + (int64_t)write_index_ * delta_min_;
        } else if (bit_width_ >= 63) {
            block_max = INT64_MAX;
        } else {
            int64_t max_delta = delta_min_ + ((1LL << bit_width_) - 1);
            block_max = first_value_ + (int64_t)write_index_ * max_delta;
        }
    }

    header_peeked_ = true;
    return true;
}

template <>
inline int TS2DIFFDecoder<int64_t>::skip_peeked_block_int64(
    common::ByteStream& in, int& skipped) {
    skipped = write_index_ + 1;
    // int64 arithmetic: read_header admits blocks whose packed size is
    // only bounded by the stream length, and write_index_ * bit_width_
    // can exceed INT32_MAX on a huge page.
    const int64_t skip_bytes_64 =
        (static_cast<int64_t>(write_index_) * bit_width_ + 7) / 8;
    in.wrapped_buf_advance_read_pos(static_cast<uint64_t>(skip_bytes_64));
    header_peeked_ = false;
    bits_left_ = 0;
    buffer_ = 0;
    current_index_ = 0;
    write_index_ = -1;
    return common::E_OK;
}

// INT32 specialization: not applicable (timestamps are always INT64)
template <>
inline bool TS2DIFFDecoder<int32_t>::peek_next_block_range_int64(
    common::ByteStream& in, int64_t& block_min, int64_t& block_max,
    int& block_count) {
    return false;
}

template <>
inline int TS2DIFFDecoder<int32_t>::skip_peeked_block_int64(
    common::ByteStream& in, int& skipped) {
    return common::E_NOT_SUPPORT;
}

// ============================================================================
// Default (unsupported type) batch/skip — fall back to base class
// ============================================================================

template <>
inline int TS2DIFFDecoder<int32_t>::read_batch_int64(int64_t* out, int capacity,
                                                     int& actual,
                                                     common::ByteStream& in) {
    return Decoder::read_batch_int64(out, capacity, actual, in);
}

template <>
inline int TS2DIFFDecoder<int32_t>::skip_int64(int count, int& skipped,
                                               common::ByteStream& in) {
    return Decoder::skip_int64(count, skipped, in);
}

template <>
inline int TS2DIFFDecoder<int64_t>::read_batch_int32(int32_t* out, int capacity,
                                                     int& actual,
                                                     common::ByteStream& in) {
    return Decoder::read_batch_int32(out, capacity, actual, in);
}

template <>
inline int TS2DIFFDecoder<int64_t>::skip_int32(int count, int& skipped,
                                               common::ByteStream& in) {
    return Decoder::skip_int32(count, skipped, in);
}

// ============================================================================
// Float / Double wrapper decoders (unchanged)
// ============================================================================

class FloatTS2DIFFDecoder : public TS2DIFFDecoder<int32_t> {
   public:
    FloatTS2DIFFDecoder() = default;
    // PageReader invokes reset() at every page boundary; the page-level
    // FLOAT/DOUBLE metadata (maxPointNumber, page-wide bitmaps, page value
    // position) is parsed once per page and survives block transitions.
    void reset() override {
        TS2DIFFDecoder<int32_t>::reset();
        page_meta_parsed_ = false;
        max_point_value_ = 1.0;
        page_pos_ = 0;
        page_value_count_ = 0;
        scaled_bm_.clear();
        raw_bm_.clear();
    }
    float decode(common::ByteStream& in) {
        int32_t value_int = TS2DIFFDecoder<int32_t>::decode(in);
        return common::int_to_float(value_int);
    }

    int read_boolean(bool& ret_value, common::ByteStream& in) override;
    int read_int32(int32_t& ret_value, common::ByteStream& in) override;
    int read_int64(int64_t& ret_value, common::ByteStream& in) override;
    int read_float(float& ret_value, common::ByteStream& in) override;
    int read_double(double& ret_value, common::ByteStream& in) override;

    int read_batch_float(float* out, int capacity, int& actual,
                         common::ByteStream& in) override;
    int read_batch_int32(int32_t* out, int capacity, int& actual,
                         common::ByteStream& in) override;

   private:
    // Parses the page metadata on the first value of a page.  Returns
    // E_OK and leaves the stream positioned at the first integer block.
    int ensure_page_meta(common::ByteStream& in) {
        if (page_meta_parsed_) {
            return common::E_OK;
        }
        ts2diff_java_detail::PageMeta meta;
        int ret = ts2diff_java_detail::read_page_meta(in, meta);
        if (RET_FAIL(ret)) {
            return ret;
        }
        max_point_value_ =
            meta.max_point_number <= 0
                ? 1.0
                : std::pow(10.0, static_cast<double>(meta.max_point_number));
        page_value_count_ = meta.page_value_count;
        if (page_value_count_ > 0) {
            TS2DIFFDecoder<int32_t>::set_max_values(page_value_count_);
        }
        scaled_bm_ = std::move(meta.scaled_bm);
        raw_bm_ = std::move(meta.raw_bm);
        page_pos_ = 0;
        page_meta_parsed_ = true;
        return common::E_OK;
    }

    float value_at(int32_t value_int) const {
        if (!raw_bm_.empty() &&
            ts2diff_java_detail::bitmap_marked(raw_bm_, page_pos_)) {
            return common::int_to_float(value_int);
        }
        const bool use_scaled =
            scaled_bm_.empty() ||
            ts2diff_java_detail::bitmap_marked(scaled_bm_, page_pos_);
        const double divisor = use_scaled ? max_point_value_ : 1.0;
        return static_cast<float>(static_cast<double>(value_int) / divisor);
    }

    double max_point_value_{1.0};
    int page_pos_{0};
    int page_value_count_{0};
    bool page_meta_parsed_{false};
    std::vector<uint8_t> scaled_bm_;
    std::vector<uint8_t> raw_bm_;
};

class DoubleTS2DIFFDecoder : public TS2DIFFDecoder<int64_t> {
   public:
    DoubleTS2DIFFDecoder() = default;
    void reset() override {
        TS2DIFFDecoder<int64_t>::reset();
        page_meta_parsed_ = false;
        max_point_value_ = 1.0;
        page_pos_ = 0;
        page_value_count_ = 0;
        scaled_bm_.clear();
        raw_bm_.clear();
    }
    double decode(common::ByteStream& in) {
        int64_t value_long = TS2DIFFDecoder<int64_t>::decode(in);
        return common::long_to_double(value_long);
    }

    int read_boolean(bool& ret_value, common::ByteStream& in) override;
    int read_int32(int32_t& ret_value, common::ByteStream& in) override;
    int read_int64(int64_t& ret_value, common::ByteStream& in) override;
    int read_float(float& ret_value, common::ByteStream& in) override;
    int read_double(double& ret_value, common::ByteStream& in) override;

    int read_batch_double(double* out, int capacity, int& actual,
                          common::ByteStream& in) override;
    int read_batch_int64(int64_t* out, int capacity, int& actual,
                         common::ByteStream& in) override;

   private:
    int ensure_page_meta(common::ByteStream& in) {
        if (page_meta_parsed_) {
            return common::E_OK;
        }
        ts2diff_java_detail::PageMeta meta;
        int ret = ts2diff_java_detail::read_page_meta(in, meta);
        if (RET_FAIL(ret)) {
            return ret;
        }
        max_point_value_ =
            meta.max_point_number <= 0
                ? 1.0
                : std::pow(10.0, static_cast<double>(meta.max_point_number));
        page_value_count_ = meta.page_value_count;
        if (page_value_count_ > 0) {
            TS2DIFFDecoder<int64_t>::set_max_values(page_value_count_);
        }
        scaled_bm_ = std::move(meta.scaled_bm);
        raw_bm_ = std::move(meta.raw_bm);
        page_pos_ = 0;
        page_meta_parsed_ = true;
        return common::E_OK;
    }

    double value_at(int64_t value_long) const {
        if (!raw_bm_.empty() &&
            ts2diff_java_detail::bitmap_marked(raw_bm_, page_pos_)) {
            return common::long_to_double(value_long);
        }
        const bool use_scaled =
            scaled_bm_.empty() ||
            ts2diff_java_detail::bitmap_marked(scaled_bm_, page_pos_);
        const double divisor = use_scaled ? max_point_value_ : 1.0;
        return static_cast<double>(value_long) / divisor;
    }

    double max_point_value_{1.0};
    int page_pos_{0};
    int page_value_count_{0};
    bool page_meta_parsed_{false};
    std::vector<uint8_t> scaled_bm_;
    std::vector<uint8_t> raw_bm_;
};

typedef TS2DIFFDecoder<int32_t> IntTS2DIFFDecoder;
typedef TS2DIFFDecoder<int64_t> LongTS2DIFFDecoder;

// wrap as Decoder interface
template <>
FORCE_INLINE int IntTS2DIFFDecoder::read_boolean(bool& ret_value,
                                                 common::ByteStream& in) {
    ASSERT(false);
    return common::E_NOT_SUPPORT;
}
template <>
FORCE_INLINE int IntTS2DIFFDecoder::read_int32(int32_t& ret_value,
                                               common::ByteStream& in) {
    ret_value = decode(in);
    return read_error_;
}
template <>
FORCE_INLINE int IntTS2DIFFDecoder::read_int64(int64_t& ret_value,
                                               common::ByteStream& in) {
    ASSERT(false);
    return common::E_NOT_SUPPORT;
}
template <>
FORCE_INLINE int IntTS2DIFFDecoder::read_float(float& ret_value,
                                               common::ByteStream& in) {
    ASSERT(false);
    return common::E_NOT_SUPPORT;
}
template <>
FORCE_INLINE int IntTS2DIFFDecoder::read_double(double& ret_value,
                                                common::ByteStream& in) {
    ASSERT(false);
    return common::E_NOT_SUPPORT;
}
template <>
FORCE_INLINE int IntTS2DIFFDecoder::read_String(common::String& ret_value,
                                                common::PageArena& pa,
                                                common::ByteStream& in) {
    ASSERT(false);
    return common::E_NOT_SUPPORT;
}
template <>
FORCE_INLINE int LongTS2DIFFDecoder::read_boolean(bool& ret_value,
                                                  common::ByteStream& in) {
    ASSERT(false);
    return common::E_NOT_SUPPORT;
}
template <>
FORCE_INLINE int LongTS2DIFFDecoder::read_int32(int32_t& ret_value,
                                                common::ByteStream& in) {
    ASSERT(false);
    return common::E_NOT_SUPPORT;
}
template <>
FORCE_INLINE int LongTS2DIFFDecoder::read_int64(int64_t& ret_value,
                                                common::ByteStream& in) {
    ret_value = decode(in);
    return read_error_;
}
template <>
FORCE_INLINE int LongTS2DIFFDecoder::read_float(float& ret_value,
                                                common::ByteStream& in) {
    ASSERT(false);
    return common::E_NOT_SUPPORT;
}
template <>
FORCE_INLINE int LongTS2DIFFDecoder::read_double(double& ret_value,
                                                 common::ByteStream& in) {
    ASSERT(false);
    return common::E_NOT_SUPPORT;
}
template <>
FORCE_INLINE int LongTS2DIFFDecoder::read_String(common::String& ret_value,
                                                 common::PageArena& pa,
                                                 common::ByteStream& in) {
    ASSERT(false);
    return common::E_NOT_SUPPORT;
}
FORCE_INLINE int FloatTS2DIFFDecoder::read_boolean(bool& ret_value,
                                                   common::ByteStream& in) {
    ASSERT(false);
    return common::E_NOT_SUPPORT;
}
FORCE_INLINE int FloatTS2DIFFDecoder::read_int32(int32_t& ret_value,
                                                 common::ByteStream& in) {
    ASSERT(false);
    return common::E_NOT_SUPPORT;
}
FORCE_INLINE int FloatTS2DIFFDecoder::read_int64(int64_t& ret_value,
                                                 common::ByteStream& in) {
    ASSERT(false);
    return common::E_NOT_SUPPORT;
}
FORCE_INLINE int FloatTS2DIFFDecoder::read_float(float& ret_value,
                                                 common::ByteStream& in) {
    int ret = common::E_OK;
    if (RET_FAIL(ensure_page_meta(in))) {
        return ret;
    }
    int32_t value_int = TS2DIFFDecoder<int32_t>::decode(in);
    if (TS2DIFFDecoder<int32_t>::read_error_ != common::E_OK) {
        return TS2DIFFDecoder<int32_t>::read_error_;
    }
    ret_value = value_at(value_int);
    page_pos_++;
    return common::E_OK;
}
FORCE_INLINE int FloatTS2DIFFDecoder::read_double(double& ret_value,
                                                  common::ByteStream& in) {
    ASSERT(false);
    return common::E_NOT_SUPPORT;
}
// Page-level metadata is parsed once, then the integer blocks are decoded
// with the integer batch decoder (SIMD fast path where available) and the
// page-wide bitmaps are applied afterwards using the page position.
FORCE_INLINE int FloatTS2DIFFDecoder::read_batch_float(float* out, int capacity,
                                                       int& actual,
                                                       common::ByteStream& in) {
    int ret = common::E_OK;
    actual = 0;
    if (RET_FAIL(ensure_page_meta(in))) {
        return ret;
    }
    constexpr int kIntsPerBatch = 128;
    int32_t ints[kIntsPerBatch];
    while (actual < capacity) {
        int block_actual = 0;
        const int want = capacity - actual;
        const int request = want < kIntsPerBatch ? want : kIntsPerBatch;
        if (RET_FAIL(TS2DIFFDecoder<int32_t>::read_batch_int32(
                ints, request, block_actual, in))) {
            return ret;
        }
        if (block_actual == 0) {
            break;
        }
        for (int i = 0; i < block_actual; i++) {
            out[actual + i] = value_at(ints[i]);
            page_pos_++;
        }
        actual += block_actual;
    }
    return common::E_OK;
}
FORCE_INLINE int FloatTS2DIFFDecoder::read_batch_int32(int32_t* out,
                                                       int capacity,
                                                       int& actual,
                                                       common::ByteStream& in) {
    ASSERT(false);
    return common::E_NOT_SUPPORT;
}
FORCE_INLINE int DoubleTS2DIFFDecoder::read_boolean(bool& ret_value,
                                                    common::ByteStream& in) {
    ASSERT(false);
    return common::E_NOT_SUPPORT;
}
FORCE_INLINE int DoubleTS2DIFFDecoder::read_int32(int32_t& ret_value,
                                                  common::ByteStream& in) {
    ASSERT(false);
    return common::E_NOT_SUPPORT;
}
FORCE_INLINE int DoubleTS2DIFFDecoder::read_int64(int64_t& ret_value,
                                                  common::ByteStream& in) {
    ASSERT(false);
    return common::E_NOT_SUPPORT;
}
FORCE_INLINE int DoubleTS2DIFFDecoder::read_float(float& ret_value,
                                                  common::ByteStream& in) {
    ASSERT(false);
    return common::E_NOT_SUPPORT;
}
FORCE_INLINE int DoubleTS2DIFFDecoder::read_double(double& ret_value,
                                                   common::ByteStream& in) {
    int ret = common::E_OK;
    if (RET_FAIL(ensure_page_meta(in))) {
        return ret;
    }
    int64_t value_long = TS2DIFFDecoder<int64_t>::decode(in);
    if (TS2DIFFDecoder<int64_t>::read_error_ != common::E_OK) {
        return TS2DIFFDecoder<int64_t>::read_error_;
    }
    ret_value = value_at(value_long);
    page_pos_++;
    return common::E_OK;
}
// See FloatTS2DIFFDecoder::read_batch_float for the layout rationale.
FORCE_INLINE int DoubleTS2DIFFDecoder::read_batch_double(
    double* out, int capacity, int& actual, common::ByteStream& in) {
    int ret = common::E_OK;
    actual = 0;
    if (RET_FAIL(ensure_page_meta(in))) {
        return ret;
    }
    constexpr int kIntsPerBatch = 128;
    int64_t ints[kIntsPerBatch];
    while (actual < capacity) {
        int block_actual = 0;
        const int want = capacity - actual;
        const int request = want < kIntsPerBatch ? want : kIntsPerBatch;
        if (RET_FAIL(TS2DIFFDecoder<int64_t>::read_batch_int64(
                ints, request, block_actual, in))) {
            return ret;
        }
        if (block_actual == 0) {
            break;
        }
        for (int i = 0; i < block_actual; i++) {
            out[actual + i] = value_at(ints[i]);
            page_pos_++;
        }
        actual += block_actual;
    }
    return common::E_OK;
}
FORCE_INLINE int DoubleTS2DIFFDecoder::read_batch_int64(
    int64_t* out, int capacity, int& actual, common::ByteStream& in) {
    ASSERT(false);
    return common::E_NOT_SUPPORT;
}

}  // end namespace storage
#endif  // ENCODING_TS2DIFF_DECODER_H
