sparrow-ipc 0.3.0
Loading...
Searching...
No Matches
deserialize_decimal_array.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <span>
4
5#include <sparrow/arrow_interface/arrow_array_schema_proxy.hpp>
6#include <sparrow/buffer/buffer.hpp>
7#include <sparrow/decimal_array.hpp>
8
13
14namespace sparrow_ipc
15{
16 template <sparrow::decimal_type T>
17 [[nodiscard]] sparrow::decimal_array<T> deserialize_decimal_array(
19 const field_descriptor& field_desc,
20 int32_t scale,
21 int32_t precision
22 )
23 {
24 constexpr std::size_t sizeof_decimal = sizeof(typename T::integer_type);
25 std::string format_str = "d:" + std::to_string(precision) + "," + std::to_string(scale);
26 if constexpr (sizeof_decimal != 16) // We don't need to specify the size for 128-bit
27 // decimals
28 {
29 format_str += "," + std::to_string(sizeof_decimal * 8);
30 }
31
32 ArrowSchema schema = make_non_owning_arrow_schema(
33 format_str,
34 field_desc.name,
35 field_desc.metadata,
36 field_desc.flags,
37 0,
38 nullptr,
39 nullptr
40 );
41
42 const auto compression = context.record_batch.compression();
43 std::vector<arrow_array_private_data::optionally_owned_buffer> buffers;
44 constexpr auto nb_buffers = 2;
45 buffers.reserve(nb_buffers);
46
47 {
48 auto validity_buffer_span = utils::get_buffer(context.record_batch, context.body, context.buffer_index);
49 auto data_buffer_span = utils::get_buffer(context.record_batch, context.body, context.buffer_index);
50
51 if (compression)
52 {
53 buffers.push_back(utils::get_decompressed_buffer(validity_buffer_span, compression));
54
55 // For decimal types, we need to ensure proper alignment of the decompressed data.
56 // The decompressed buffer itself is aligned, but we need to copy it to ensure
57 // the decimal values (especially int128 and int256) start at a properly aligned address.
58 auto decompressed_data = utils::get_decompressed_buffer(data_buffer_span, compression);
59 std::visit([&buffers](auto&& arg) {
60 using variant_type = std::decay_t<decltype(arg)>;
61 if constexpr (std::is_same_v<variant_type, sparrow::buffer<std::uint8_t>>)
62 {
63 // Already a buffer, move it
64 buffers.push_back(std::move(arg));
65 }
66 else
67 {
68 // It's a span, copy to ensure alignment
69 sparrow::buffer<std::uint8_t> aligned_buffer(arg.begin(), arg.end(), sparrow::buffer<std::uint8_t>::default_allocator());
70 buffers.push_back(std::move(aligned_buffer));
71 }
72 }, std::move(decompressed_data));
73 }
74 else
75 {
76 buffers.push_back(std::move(validity_buffer_span));
77 sparrow::buffer<std::uint8_t> data_buffer_copy(data_buffer_span.begin(), data_buffer_span.end(), sparrow::buffer<std::uint8_t>::default_allocator());
78 buffers.push_back(std::move(data_buffer_copy));
79 }
80 }
81
82 const auto null_count = std::visit(
83 [length = field_desc.length](const auto& arg) {
84 std::span<const uint8_t> span(arg.data(), arg.size());
85 return utils::get_bitmap_pointer_and_null_count(span, length).second;
86 },
87 buffers[0]
88 );
89
91 field_desc.length,
92 null_count,
93 0,
94 0,
95 nullptr,
96 nullptr,
97 std::move(buffers)
98 );
99 sparrow::arrow_proxy ap{std::move(array), std::move(schema)};
100 return sparrow::decimal_array<T>(std::move(ap));
101 }
102}
std::span< const uint8_t > get_buffer(const org::apache::arrow::flatbuf::RecordBatch &record_batch, std::span< const uint8_t > body, size_t &buffer_index)
Extracts a buffer from a RecordBatch's body.
std::variant< sparrow::buffer< std::uint8_t >, std::span< const std::uint8_t > > get_decompressed_buffer(std::span< const uint8_t > buffer_span, const org::apache::arrow::flatbuf::BodyCompression *compression)
Retrieves a decompressed buffer or a view of the original buffer.
sparrow::decimal_array< T > deserialize_decimal_array(deserialization_context &context, const field_descriptor &field_desc, int32_t scale, int32_t precision)
ArrowSchema make_non_owning_arrow_schema(std::string_view format, std::string_view name, std::optional< M > metadata, std::optional< std::unordered_set< sparrow::ArrowFlag > > flags, size_t children_count, ArrowSchema **children, ArrowSchema *dictionary)
ArrowArray make_arrow_array(int64_t length, int64_t null_count, int64_t offset, size_t children_count, ArrowArray **children, ArrowArray *dictionary, Arg &&private_data_arg)
Encapsulates the context required for deserialization.
const org::apache::arrow::flatbuf::RecordBatch & record_batch
Encapsulates the description of a field to be deserialized.
std::optional< std::vector< sparrow::metadata_pair > > metadata
std::optional< std::unordered_set< sparrow::ArrowFlag > > flags