sparrow 0.9.0
Loading...
Searching...
No Matches
primitive_array_impl.hpp
Go to the documentation of this file.
1// Copyright 2024 Man Group Operations Limited
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15
16#pragma once
17
26
27namespace sparrow
28{
29 template <trivial_copyable_type T>
31
32 template <trivial_copyable_type T>
52
53 template <trivial_copyable_type T>
54 class primitive_array_impl final : public mutable_array_bitmap_base<primitive_array_impl<T>>,
56 {
57 public:
58
62 using size_type = std::size_t;
63
65 using inner_value_type = typename inner_types::inner_value_type;
66 using inner_reference = typename inner_types::inner_reference;
67 using inner_const_reference = typename inner_types::inner_const_reference;
68
69 using pointer = typename inner_types::pointer;
70 using const_pointer = typename inner_types::const_pointer;
71
72 using value_iterator = typename base_type::value_iterator;
73 using const_value_iterator = typename base_type::const_value_iterator;
74
76
101 template <class... Args>
103 explicit primitive_array_impl(Args&&... args)
104 : base_type(create_proxy(std::forward<Args>(args)...))
105 , access_class_type(this->get_arrow_proxy(), DATA_BUFFER_INDEX)
106 {
107 }
108
112 template <input_metadata_container METADATA_RANGE = std::vector<metadata_pair>>
114 std::initializer_list<inner_value_type> init,
115 bool nullable = true,
116 std::optional<std::string_view> name = std::nullopt,
117 std::optional<METADATA_RANGE> metadata = std::nullopt
118 )
119 : base_type(create_proxy(init, nullable, std::move(name), std::move(metadata)))
120 , access_class_type(this->get_arrow_proxy(), DATA_BUFFER_INDEX)
121 {
122 }
123
126
129
130 private:
131
132 template <
133 validity_bitmap_input VALIDITY_RANGE = validity_bitmap,
134 input_metadata_container METADATA_RANGE = std::vector<metadata_pair>>
135 [[nodiscard]] static auto create_proxy(
136 u8_buffer<T>&& data_buffer,
137 size_t size,
138 VALIDITY_RANGE&& bitmaps,
139 std::optional<std::string_view> name = std::nullopt,
140 std::optional<METADATA_RANGE> metadata = std::nullopt
141 ) -> arrow_proxy;
142
143 template <
144 validity_bitmap_input VALIDITY_RANGE = validity_bitmap,
145 input_metadata_container METADATA_RANGE = std::vector<metadata_pair>>
146 [[nodiscard]] static auto create_proxy(
147 u8_buffer<T>&& data_buffer,
148 size_t size,
149 bool nullable = true,
150 std::optional<std::string_view> name = std::nullopt,
151 std::optional<METADATA_RANGE> metadata = std::nullopt
152 ) -> arrow_proxy;
153
154 // range of values (no missing values)
155 template <std::ranges::input_range R, input_metadata_container METADATA_RANGE = std::vector<metadata_pair>>
156 requires(std::convertible_to<std::ranges::range_value_t<R>, T> && !mpl::is_type_instance_of_v<R, u8_buffer>)
157 [[nodiscard]] static auto create_proxy(
158 R&& range,
159 bool nullable = true,
160 std::optional<std::string_view> name = std::nullopt,
161 std::optional<METADATA_RANGE> metadata = std::nullopt
162 ) -> arrow_proxy;
163
164 template <class U, input_metadata_container METADATA_RANGE = std::vector<metadata_pair>>
165 requires std::convertible_to<U, T>
166 [[nodiscard]] static arrow_proxy create_proxy(
167 size_type n,
168 const U& value = U{},
169 bool nullable = true,
170 std::optional<std::string_view> name = std::nullopt,
171 std::optional<METADATA_RANGE> metadata = std::nullopt
172 );
173
174 // range of values, validity_bitmap_input
175 template <
176 std::ranges::input_range R,
178 input_metadata_container METADATA_RANGE = std::vector<metadata_pair>>
179 requires(std::convertible_to<std::ranges::range_value_t<R>, T>)
180 [[nodiscard]] static arrow_proxy create_proxy(
181 R&&,
182 R2&&,
183 std::optional<std::string_view> name = std::nullopt,
184 std::optional<METADATA_RANGE> metadata = std::nullopt
185 );
186
187 // range of nullable values
188 template <std::ranges::input_range NULLABLE_RANGE, input_metadata_container METADATA_RANGE = std::vector<metadata_pair>>
189 requires std::is_same_v<std::ranges::range_value_t<NULLABLE_RANGE>, nullable<T>>
190 [[nodiscard]] static arrow_proxy create_proxy(
191 NULLABLE_RANGE&&,
192 std::optional<std::string_view> name = std::nullopt,
193 std::optional<METADATA_RANGE> metadata = std::nullopt
194 );
195
196 template <input_metadata_container METADATA_RANGE = std::vector<metadata_pair>>
197 [[nodiscard]] static arrow_proxy create_proxy_impl(
198 u8_buffer<T>&& data_buffer,
199 size_t size,
200 std::optional<validity_bitmap>&& bitmap,
201 std::optional<std::string_view> name = std::nullopt,
202 std::optional<METADATA_RANGE> metadata = std::nullopt
203 );
204
210
211 // Modifiers
212
217
218 static constexpr size_type DATA_BUFFER_INDEX = 1;
219
221 friend base_type;
224 };
225
226 /********************************************************
227 * primitive_array_impl implementation *
228 ********************************************************/
229
230 template <trivial_copyable_type T>
232 : base_type(std::move(proxy_param))
233 , access_class_type(this->get_arrow_proxy(), DATA_BUFFER_INDEX)
234 {
235 }
236
237 template <trivial_copyable_type T>
239 : base_type(rhs)
240 , access_class_type(this->get_arrow_proxy(), DATA_BUFFER_INDEX)
241 {
242 }
243
244 template <trivial_copyable_type T>
246 {
248 access_class_type::reset_proxy(this->get_arrow_proxy());
249 return *this;
250 }
251
252 template <trivial_copyable_type T>
254 : base_type(std::move(rhs))
255 , access_class_type(this->get_arrow_proxy(), DATA_BUFFER_INDEX)
256 {
257 }
258
259 template <trivial_copyable_type T>
261 {
262 base_type::operator=(std::move(rhs));
263 access_class_type::reset_proxy(this->get_arrow_proxy());
264 return *this;
265 }
266
267 template <trivial_copyable_type T>
268 template <validity_bitmap_input VALIDITY_RANGE, input_metadata_container METADATA_RANGE>
269 auto primitive_array_impl<T>::create_proxy(
270 u8_buffer<T>&& data_buffer,
271 size_t size,
272 VALIDITY_RANGE&& bitmap_input,
273 std::optional<std::string_view> name,
274 std::optional<METADATA_RANGE> metadata
275 ) -> arrow_proxy
276 {
277 return create_proxy_impl(
278 std::forward<u8_buffer<T>>(data_buffer),
279 size,
280 ensure_validity_bitmap(size, std::forward<VALIDITY_RANGE>(bitmap_input)),
281 std::move(name),
282 std::move(metadata)
283 );
284 }
285
286 template <trivial_copyable_type T>
287 template <std::ranges::input_range VALUE_RANGE, validity_bitmap_input VALIDITY_RANGE, input_metadata_container METADATA_RANGE>
288 requires(std::convertible_to<std::ranges::range_value_t<VALUE_RANGE>, T>)
289 arrow_proxy primitive_array_impl<T>::create_proxy(
290 VALUE_RANGE&& values,
291 VALIDITY_RANGE&& validity_input,
292 std::optional<std::string_view> name,
293 std::optional<METADATA_RANGE> metadata
294 )
295 {
296 auto size = static_cast<size_t>(std::ranges::distance(values));
298 std::forward<VALUE_RANGE>(values)
299 );
300 return create_proxy(
301 std::move(data_buffer),
302 size,
303 std::forward<VALIDITY_RANGE>(validity_input),
304 std::move(name),
305 std::move(metadata)
306 );
307 }
308
309 template <trivial_copyable_type T>
310 template <class U, input_metadata_container METADATA_RANGE>
311 requires std::convertible_to<U, T>
312 arrow_proxy primitive_array_impl<T>::create_proxy(
313 size_type n,
314 const U& value,
315 bool nullable,
316 std::optional<std::string_view> name,
317 std::optional<METADATA_RANGE> metadata
318 )
319 {
320 // create data_buffer
321 u8_buffer<T> data_buffer(n, value);
322 return create_proxy_impl(
323 std::move(data_buffer),
324 n,
325 nullable ? std::make_optional<validity_bitmap>(nullptr, 0) : std::nullopt,
326 std::move(name),
327 std::move(metadata)
328 );
329 }
330
331 template <trivial_copyable_type T>
332 template <validity_bitmap_input VALIDITY_RANGE, input_metadata_container METADATA_RANGE>
333 arrow_proxy primitive_array_impl<T>::create_proxy(
334 u8_buffer<T>&& data_buffer,
335 size_t size,
336 bool nullable,
337 std::optional<std::string_view> name,
338 std::optional<METADATA_RANGE> metadata
339 )
340 {
341 std::optional<validity_bitmap> bitmap = nullable ? std::make_optional<validity_bitmap>(nullptr, 0)
342 : std::nullopt;
343 return create_proxy_impl(
344 std::move(data_buffer),
345 size,
346 std::move(bitmap),
347 std::move(name),
348 std::move(metadata)
349 );
350 }
351
352 template <trivial_copyable_type T>
353 template <std::ranges::input_range R, input_metadata_container METADATA_RANGE>
354 requires(std::convertible_to<std::ranges::range_value_t<R>, T> && !mpl::is_type_instance_of_v<R, u8_buffer>)
355 arrow_proxy primitive_array_impl<T>::create_proxy(
356 R&& range,
357 bool nullable,
358 std::optional<std::string_view> name,
359 std::optional<METADATA_RANGE> metadata
360 )
361 {
362 auto data_buffer = details::primitive_data_access<T>::make_data_buffer(std::forward<R>(range));
363 auto distance = static_cast<size_t>(std::ranges::distance(range));
364 std::optional<validity_bitmap> bitmap = nullable ? std::make_optional<validity_bitmap>(nullptr, 0)
365 : std::nullopt;
366 return create_proxy_impl(
367 std::move(data_buffer),
368 distance,
369 std::move(bitmap),
370 std::move(name),
371 std::move(metadata)
372 );
373 }
374
375 // range of nullable values
376 template <trivial_copyable_type T>
377 template <std::ranges::input_range NULLABLE_RANGE, input_metadata_container METADATA_RANGE>
378 requires std::is_same_v<std::ranges::range_value_t<NULLABLE_RANGE>, nullable<T>>
379 arrow_proxy primitive_array_impl<T>::create_proxy(
380 NULLABLE_RANGE&& nullable_range,
381 std::optional<std::string_view> name,
382 std::optional<METADATA_RANGE> metadata
383 )
384 {
385 // split into values and is_non_null ranges
386 auto values = nullable_range
387 | std::views::transform(
388 [](const auto& v)
389 {
390 return v.get();
391 }
392 );
393 auto is_non_null = nullable_range
394 | std::views::transform(
395 [](const auto& v)
396 {
397 return v.has_value();
398 }
399 );
400 return self_type::create_proxy(values, is_non_null, std::move(name), std::move(metadata));
401 }
402
403 template <trivial_copyable_type T>
404 template <input_metadata_container METADATA_RANGE>
405 [[nodiscard]] arrow_proxy primitive_array_impl<T>::create_proxy_impl(
406 u8_buffer<T>&& data_buffer,
407 size_t size,
408 std::optional<validity_bitmap>&& bitmap,
409 std::optional<std::string_view> name,
410 std::optional<METADATA_RANGE> metadata
411 )
412 {
413 const bool bitmap_has_value = bitmap.has_value();
414 const auto null_count = bitmap_has_value ? bitmap->null_count() : 0;
415 const auto flags = bitmap_has_value
416 ? std::make_optional<std::unordered_set<sparrow::ArrowFlag>>({ArrowFlag::NULLABLE})
417 : std::nullopt;
418
419 // create arrow schema and array
420 ArrowSchema schema = make_arrow_schema(
422 std::move(name), // name
423 std::move(metadata), // metadata
424 flags, // flags
425 nullptr, // children
426 repeat_view<bool>(true, 0), // children_ownership
427 nullptr, // dictionary
428 true // dictionary ownership
429 );
430
431 buffer<uint8_t> bitmap_buffer = bitmap_has_value ? std::move(*bitmap).extract_storage()
432 : buffer<uint8_t>{nullptr, 0};
433
434 std::vector<buffer<uint8_t>> buffers(2);
435 buffers[0] = std::move(bitmap_buffer);
436 buffers[1] = std::move(data_buffer).extract_storage();
437
438 // create arrow array
439 ArrowArray arr = make_arrow_array(
440 static_cast<std::int64_t>(size), // length
441 static_cast<int64_t>(null_count),
442 0, // offset
443 std::move(buffers),
444 nullptr, // children
445 repeat_view<bool>(true, 0), // children_ownership
446 nullptr, // dictionary,
447 true // dictionary ownership
448 );
449 return arrow_proxy(std::move(arr), std::move(schema));
450 }
451}
array_bitmap_base_impl & operator=(const array_bitmap_base_impl &)
std::conditional_t< is_mutable, mutable_array_base< D >, array_crtp_base< D > > base_type
Proxy class over ArrowArray and ArrowSchema.
Object that owns a piece of contiguous memory.
Definition buffer.hpp:112
Data access class for trivial copyable types.
constexpr void resize_values(size_t new_length, const T &value)
constexpr value_iterator erase_values(const_value_iterator pos, size_t count)
static u8_buffer< T > make_data_buffer(RANGE &&r)
constexpr inner_reference value(size_t i)
constexpr value_iterator insert_values(const_value_iterator pos, InputIt first, InputIt last)
constexpr const_value_iterator value_cend() const
pointer_iterator< inner_const_pointer > const_value_iterator
constexpr value_iterator insert_value(const_value_iterator pos, T value, size_t count)
pointer_iterator< inner_pointer > value_iterator
constexpr const_value_iterator value_cbegin() const
The nullable class models a value or a reference that can be "null", or missing, like values traditio...
Definition nullable.hpp:281
typename base_type::value_iterator value_iterator
typename base_type::const_value_iterator const_value_iterator
primitive_array_impl(std::initializer_list< inner_value_type > init, bool nullable=true, std::optional< std::string_view > name=std::nullopt, std::optional< METADATA_RANGE > metadata=std::nullopt)
Constructs a primitive array from an initializer_list of raw values.
typename inner_types::pointer pointer
primitive_array_impl< T > self_type
primitive_array_impl(Args &&... args)
Constructs an array of trivial copyable type, with the passed range of values and an optional bitmap.
mutable_array_bitmap_base< primitive_array_impl< T > > base_type
primitive_array_impl(primitive_array_impl &&) noexcept
typename inner_types::inner_reference inner_reference
primitive_array_impl(const primitive_array_impl &)
typename inner_types::inner_const_reference inner_const_reference
typename inner_types::const_pointer const_pointer
array_inner_types< self_type > inner_types
details::primitive_data_access< T > access_class_type
typename inner_types::inner_value_type inner_value_type
primitive_array_impl & operator=(const primitive_array_impl &)
A view that repeats a value a given number of times.
This buffer class is use as storage buffer for all sparrow arrays.
Definition u8_buffer.hpp:75
constexpr bool excludes_copy_and_move_ctor_v
Definition mp_utils.hpp:507
constexpr bool is_type_instance_of_v
true if T is a concrete type template instanciation of U which is a type template.
Definition mp_utils.hpp:50
array_bitmap_base_impl< D, true > mutable_array_bitmap_base
Convenient typedef to be used as a crtp base class for arrays using a mutable validity buffer.
ArrowSchema make_arrow_schema(F format, N name, std::optional< M > metadata, std::optional< std::unordered_set< ArrowFlag > > flags, ArrowSchema **children, const CHILDREN_OWNERSHIP &children_ownership, ArrowSchema *dictionary, bool dictionary_ownership)
Creates an ArrowSchema owned by a unique_ptr and holding the provided data.
constexpr std::string_view data_type_format_of()
ArrowArray make_arrow_array(int64_t length, int64_t null_count, int64_t offset, B buffers, ArrowArray **children, const CHILDREN_OWNERSHIP &children_ownership, ArrowArray *dictionary, bool dictionary_ownership)
Creates an ArrowArray.
dynamic_bitset< std::uint8_t > validity_bitmap
validity_bitmap ensure_validity_bitmap(std::size_t size, R &&validity_input)
std::pair< metadata_key, metadata_value > metadata_pair
Definition metadata.hpp:39
typename data_access_type::inner_value_type inner_value_type
typename data_access_type::value_iterator value_iterator
typename data_access_type::inner_const_pointer const_pointer
typename data_access_type::inner_const_reference inner_const_reference
typename data_access_type::inner_reference inner_reference
typename data_access_type::const_value_iterator const_value_iterator
nullable< inner_const_reference, bitmap_const_reference > const_reference
Base class for array_inner_types specialization.
Traits class that must be specialized by array classes inheriting from array_crtp_base.