blob: adbe54160427372f85ac8a969973f6365239ff04 [file]
/*
* 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.
*/
#pragma once
#include <cstdint>
#include <memory>
#include <string_view>
#include <vector>
#include "arrow/array/array_base.h"
#include "arrow/util/bit_util.h"
namespace arrow {
class StructArray;
} // namespace arrow
namespace paimon {
class MemoryPool;
/// Pre-cached column metadata for fast access without virtual function calls or checked_cast.
struct CachedColumnMeta {
/// Null bitmap pointer. nullptr means no nulls (all valid).
const uint8_t* null_bitmap = nullptr;
/// Arrow array offset (for sliced arrays).
int64_t array_offset = 0;
/// For fixed-width types: raw pointer to values buffer (buffer[1]).
/// For variable-length types (STRING/BINARY): raw pointer to data buffer (buffer[2]).
const uint8_t* values_data = nullptr;
/// For variable-length types (STRING/BINARY): raw pointer to offsets buffer (buffer[1]).
const int32_t* offsets = nullptr;
/// Fast null check: directly reads validity bitmap bit.
inline bool IsNull(int64_t row_id) const {
return null_bitmap != nullptr &&
!arrow::bit_util::GetBit(null_bitmap, array_offset + row_id);
}
/// Fast fixed-width value access (INT8/INT16/INT32/INT64/FLOAT/DOUBLE/DATE32/TIMESTAMP).
template <typename T>
inline T GetFixed(int64_t row_id) const {
return reinterpret_cast<const T*>(values_data)[array_offset + row_id];
}
/// Fast boolean value access (bit-packed in values buffer).
inline bool GetBool(int64_t row_id) const {
return arrow::bit_util::GetBit(values_data, array_offset + row_id);
}
/// Fast string_view access for non-dictionary STRING/BINARY columns.
inline std::string_view GetVarLenView(int64_t row_id) const {
int64_t idx = array_offset + row_id;
int32_t start = offsets[idx];
int32_t length = offsets[idx + 1] - start;
return {reinterpret_cast<const char*>(values_data) + start, static_cast<size_t>(length)};
}
};
struct ColumnarBatchContext {
ColumnarBatchContext(const arrow::ArrayVector& array_vec_in,
const std::shared_ptr<MemoryPool>& pool_in)
: pool(pool_in), array_vec(array_vec_in) {
BuildCachedMeta();
}
std::shared_ptr<MemoryPool> pool;
arrow::ArrayVector array_vec;
/// Pre-cached metadata per column for fast access.
std::vector<CachedColumnMeta> cached_meta;
private:
void BuildCachedMeta() {
cached_meta.resize(array_vec.size());
for (size_t i = 0; i < array_vec.size(); i++) {
const auto* array = array_vec[i].get();
auto& meta = cached_meta[i];
meta.array_offset = array->offset();
// Cache null bitmap
if (array->null_count() != 0) {
meta.null_bitmap = array->null_bitmap_data();
}
// Cache data pointers based on type
const auto& array_data = array->data();
switch (array->type_id()) {
case arrow::Type::BOOL:
case arrow::Type::INT8:
case arrow::Type::INT16:
case arrow::Type::INT32:
case arrow::Type::DATE32:
case arrow::Type::INT64:
case arrow::Type::FLOAT:
case arrow::Type::DOUBLE: {
// Fixed-width: values in buffer[1]
if (array_data->buffers.size() > 1 && array_data->buffers[1]) {
meta.values_data = array_data->buffers[1]->data();
}
break;
}
case arrow::Type::STRING:
case arrow::Type::BINARY: {
// Variable-length: offsets in buffer[1], data in buffer[2]
if (array_data->buffers.size() > 2) {
if (array_data->buffers[1]) {
meta.offsets =
reinterpret_cast<const int32_t*>(array_data->buffers[1]->data());
}
if (array_data->buffers[2]) {
meta.values_data = array_data->buffers[2]->data();
}
}
break;
}
default:
// TIMESTAMP, DECIMAL, DICTIONARY, LIST, MAP, STRUCT — not cached, use array_vec
// fallback
break;
}
}
}
};
} // namespace paimon