sparrow ..
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
24#include "sparrow/u8_buffer.hpp"
27
28namespace sparrow
29{
30 template <trivial_copyable_type T>
32
33 template <trivial_copyable_type T>
53
54 namespace detail
55 {
56 template <class T>
58
59 template <trivial_copyable_type T>
61 {
62 [[nodiscard]] static constexpr sparrow::data_type get()
63 {
65 }
66 };
67 }
68
96 template <trivial_copyable_type T>
97 class primitive_array_impl final : public mutable_array_bitmap_base<primitive_array_impl<T>>,
99 {
100 public:
101
105 using size_type = std::size_t;
106
108 using inner_value_type = typename inner_types::inner_value_type;
109 using inner_reference = typename inner_types::inner_reference;
110 using inner_const_reference = typename inner_types::inner_const_reference;
111
112 using pointer = typename inner_types::pointer;
113 using const_pointer = typename inner_types::const_pointer;
114
115 using value_iterator = typename base_type::value_iterator;
116 using const_value_iterator = typename base_type::const_value_iterator;
117
129
150 template <class... Args>
152 explicit primitive_array_impl(Args&&... args)
153 : base_type(create_proxy(std::forward<Args>(args)...))
154 , access_class_type(this->get_arrow_proxy(), DATA_BUFFER_INDEX)
155 {
156 }
157
172 template <input_metadata_container METADATA_RANGE = std::vector<metadata_pair>>
174 std::initializer_list<inner_value_type> init,
175 bool nullable = true,
176 std::optional<std::string_view> name = std::nullopt,
177 std::optional<METADATA_RANGE> metadata = std::nullopt
178 )
179 : base_type(create_proxy(init, nullable, std::move(name), std::move(metadata)))
180 , access_class_type(this->get_arrow_proxy(), DATA_BUFFER_INDEX)
181 {
182 }
183
194
207
218
230 constexpr primitive_array_impl& operator=(primitive_array_impl&&) noexcept;
231
232 private:
233
250 template <
251 validity_bitmap_input VALIDITY_RANGE = validity_bitmap,
252 input_metadata_container METADATA_RANGE = std::vector<metadata_pair>>
253 [[nodiscard]] static auto create_proxy(
254 u8_buffer<T>&& data_buffer,
255 size_t size,
256 VALIDITY_RANGE&& bitmaps,
257 std::optional<std::string_view> name = std::nullopt,
258 std::optional<METADATA_RANGE> metadata = std::nullopt
259 ) -> arrow_proxy;
260
279 template <
280 validity_bitmap_input VALIDITY_RANGE = validity_bitmap,
281 input_metadata_container METADATA_RANGE = std::vector<metadata_pair>>
282 [[nodiscard]] static auto create_proxy(
283 u8_buffer<T>&& data_buffer,
284 size_t size,
285 bool nullable = true,
286 std::optional<std::string_view> name = std::nullopt,
287 std::optional<METADATA_RANGE> metadata = std::nullopt
288 ) -> arrow_proxy;
289
308 template <std::ranges::input_range R, input_metadata_container METADATA_RANGE = std::vector<metadata_pair>>
309 requires(std::convertible_to<std::ranges::range_value_t<R>, T> && !mpl::is_type_instance_of_v<R, u8_buffer>)
310 [[nodiscard]] static auto create_proxy(
311 R&& range,
312 bool nullable = true,
313 std::optional<std::string_view> name = std::nullopt,
314 std::optional<METADATA_RANGE> metadata = std::nullopt
315 ) -> arrow_proxy;
316
335 template <class U, input_metadata_container METADATA_RANGE = std::vector<metadata_pair>>
336 requires std::convertible_to<U, T>
337 [[nodiscard]] static arrow_proxy create_proxy(
338 size_type n,
339 const U& value = U{},
340 bool nullable = true,
341 std::optional<std::string_view> name = std::nullopt,
342 std::optional<METADATA_RANGE> metadata = std::nullopt
343 );
344
366 template <
367 std::ranges::input_range R,
369 input_metadata_container METADATA_RANGE = std::vector<metadata_pair>>
370 requires(std::convertible_to<std::ranges::range_value_t<R>, T>)
371 [[nodiscard]] static arrow_proxy create_proxy(
372 R&&,
373 R2&&,
374 std::optional<std::string_view> name = std::nullopt,
375 std::optional<METADATA_RANGE> metadata = std::nullopt
376 );
377
395 template <std::ranges::input_range NULLABLE_RANGE, input_metadata_container METADATA_RANGE = std::vector<metadata_pair>>
396 requires std::is_same_v<std::ranges::range_value_t<NULLABLE_RANGE>, nullable<T>>
397 [[nodiscard]] static arrow_proxy create_proxy(
398 NULLABLE_RANGE&&,
399 std::optional<std::string_view> name = std::nullopt,
400 std::optional<METADATA_RANGE> metadata = std::nullopt
401 );
402
421 template <input_metadata_container METADATA_RANGE = std::vector<metadata_pair>>
422 [[nodiscard]] static arrow_proxy create_proxy_impl(
423 u8_buffer<T>&& data_buffer,
424 size_t size,
425 std::optional<validity_bitmap>&& bitmap,
426 std::optional<std::string_view> name = std::nullopt,
427 std::optional<METADATA_RANGE> metadata = std::nullopt
428 );
429
435
436 // Modifiers
437
442
443 static constexpr size_type DATA_BUFFER_INDEX = 1;
444
446 friend base_type;
449 };
450
451 /********************************************************
452 * primitive_array_impl implementation *
453 ********************************************************/
454
455 template <trivial_copyable_type T>
457 : base_type(std::move(proxy_param))
458 , access_class_type(this->get_arrow_proxy(), DATA_BUFFER_INDEX)
459 {
460 }
461
462 template <trivial_copyable_type T>
464 : base_type(rhs)
465 , access_class_type(this->get_arrow_proxy(), DATA_BUFFER_INDEX)
466 {
467 }
468
469 template <trivial_copyable_type T>
471 {
473 access_class_type::reset_proxy(this->get_arrow_proxy());
474 return *this;
475 }
476
477 template <trivial_copyable_type T>
479 : base_type(std::move(rhs))
480 , access_class_type(this->get_arrow_proxy(), DATA_BUFFER_INDEX)
481 {
482 }
483
484 template <trivial_copyable_type T>
486 {
487 base_type::operator=(std::move(rhs));
488 access_class_type::reset_proxy(this->get_arrow_proxy());
489 return *this;
490 }
491
492 template <trivial_copyable_type T>
493 template <validity_bitmap_input VALIDITY_RANGE, input_metadata_container METADATA_RANGE>
494 auto primitive_array_impl<T>::create_proxy(
495 u8_buffer<T>&& data_buffer,
496 size_t size,
497 VALIDITY_RANGE&& bitmap_input,
498 std::optional<std::string_view> name,
499 std::optional<METADATA_RANGE> metadata
500 ) -> arrow_proxy
501 {
502 return create_proxy_impl(
503 std::forward<u8_buffer<T>>(data_buffer),
504 size,
505 ensure_validity_bitmap(size, std::forward<VALIDITY_RANGE>(bitmap_input)),
506 std::move(name),
507 std::move(metadata)
508 );
509 }
510
511 template <trivial_copyable_type T>
512 template <std::ranges::input_range VALUE_RANGE, validity_bitmap_input VALIDITY_RANGE, input_metadata_container METADATA_RANGE>
513 requires(std::convertible_to<std::ranges::range_value_t<VALUE_RANGE>, T>)
514 arrow_proxy primitive_array_impl<T>::create_proxy(
515 VALUE_RANGE&& values,
516 VALIDITY_RANGE&& validity_input,
517 std::optional<std::string_view> name,
518 std::optional<METADATA_RANGE> metadata
519 )
520 {
521 auto size = static_cast<size_t>(std::ranges::distance(values));
523 std::forward<VALUE_RANGE>(values)
524 );
525 return create_proxy(
526 std::move(data_buffer),
527 size,
528 std::forward<VALIDITY_RANGE>(validity_input),
529 std::move(name),
530 std::move(metadata)
531 );
532 }
533
534 template <trivial_copyable_type T>
535 template <class U, input_metadata_container METADATA_RANGE>
536 requires std::convertible_to<U, T>
537 arrow_proxy primitive_array_impl<T>::create_proxy(
538 size_type n,
539 const U& value,
540 bool nullable,
541 std::optional<std::string_view> name,
542 std::optional<METADATA_RANGE> metadata
543 )
544 {
545 // create data_buffer
546 u8_buffer<T> data_buffer(n, value);
547 return create_proxy_impl(
548 std::move(data_buffer),
549 n,
550 nullable ? std::make_optional<validity_bitmap>(nullptr, 0) : std::nullopt,
551 std::move(name),
552 std::move(metadata)
553 );
554 }
555
556 template <trivial_copyable_type T>
557 template <validity_bitmap_input VALIDITY_RANGE, input_metadata_container METADATA_RANGE>
558 arrow_proxy primitive_array_impl<T>::create_proxy(
559 u8_buffer<T>&& data_buffer,
560 size_t size,
561 bool nullable,
562 std::optional<std::string_view> name,
563 std::optional<METADATA_RANGE> metadata
564 )
565 {
566 std::optional<validity_bitmap> bitmap = nullable ? std::make_optional<validity_bitmap>(nullptr, 0)
567 : std::nullopt;
568 return create_proxy_impl(
569 std::move(data_buffer),
570 size,
571 std::move(bitmap),
572 std::move(name),
573 std::move(metadata)
574 );
575 }
576
577 template <trivial_copyable_type T>
578 template <std::ranges::input_range R, input_metadata_container METADATA_RANGE>
579 requires(std::convertible_to<std::ranges::range_value_t<R>, T> && !mpl::is_type_instance_of_v<R, u8_buffer>)
580 arrow_proxy primitive_array_impl<T>::create_proxy(
581 R&& range,
582 bool nullable,
583 std::optional<std::string_view> name,
584 std::optional<METADATA_RANGE> metadata
585 )
586 {
587 auto data_buffer = details::primitive_data_access<T>::make_data_buffer(std::forward<R>(range));
588 auto distance = static_cast<size_t>(std::ranges::distance(range));
589 std::optional<validity_bitmap> bitmap = nullable ? std::make_optional<validity_bitmap>(nullptr, 0)
590 : std::nullopt;
591 return create_proxy_impl(
592 std::move(data_buffer),
593 distance,
594 std::move(bitmap),
595 std::move(name),
596 std::move(metadata)
597 );
598 }
599
600 // range of nullable values
601 template <trivial_copyable_type T>
602 template <std::ranges::input_range NULLABLE_RANGE, input_metadata_container METADATA_RANGE>
603 requires std::is_same_v<std::ranges::range_value_t<NULLABLE_RANGE>, nullable<T>>
604 arrow_proxy primitive_array_impl<T>::create_proxy(
605 NULLABLE_RANGE&& nullable_range,
606 std::optional<std::string_view> name,
607 std::optional<METADATA_RANGE> metadata
608 )
609 {
610 // split into values and is_non_null ranges
611 auto values = nullable_range
612 | std::views::transform(
613 [](const auto& v)
614 {
615 return v.get();
616 }
617 );
618 auto is_non_null = nullable_range
619 | std::views::transform(
620 [](const auto& v)
621 {
622 return v.has_value();
623 }
624 );
625 return self_type::create_proxy(values, is_non_null, std::move(name), std::move(metadata));
626 }
627
628 template <trivial_copyable_type T>
629 template <input_metadata_container METADATA_RANGE>
630 [[nodiscard]] arrow_proxy primitive_array_impl<T>::create_proxy_impl(
631 u8_buffer<T>&& data_buffer,
632 size_t size,
633 std::optional<validity_bitmap>&& bitmap,
634 std::optional<std::string_view> name,
635 std::optional<METADATA_RANGE> metadata
636 )
637 {
638 const bool bitmap_has_value = bitmap.has_value();
639 const auto null_count = bitmap_has_value ? bitmap->null_count() : 0;
640 const auto flags = bitmap_has_value
641 ? std::make_optional<std::unordered_set<sparrow::ArrowFlag>>({ArrowFlag::NULLABLE})
642 : std::nullopt;
643
644 // create arrow schema and array
645 ArrowSchema schema = make_arrow_schema(
647 std::move(name), // name
648 std::move(metadata), // metadata
649 flags, // flags
650 nullptr, // children
651 repeat_view<bool>(true, 0), // children_ownership
652 nullptr, // dictionary
653 true // dictionary ownership
654 );
655
656 buffer<uint8_t> bitmap_buffer = bitmap_has_value ? std::move(*bitmap).extract_storage()
657 : buffer<uint8_t>{nullptr, 0};
658
659 std::vector<buffer<uint8_t>> buffers(2);
660 buffers[0] = std::move(bitmap_buffer);
661 buffers[1] = std::move(data_buffer).extract_storage();
662
663 // create arrow array
664 ArrowArray arr = make_arrow_array(
665 static_cast<std::int64_t>(size), // length
666 static_cast<int64_t>(null_count),
667 0, // offset
668 std::move(buffers),
669 nullptr, // children
670 repeat_view<bool>(true, 0), // children_ownership
671 nullptr, // dictionary,
672 true // dictionary ownership
673 );
674 return arrow_proxy(std::move(arr), std::move(schema));
675 }
676}
constexpr 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
Object that owns a piece of contiguous memory.
Definition buffer.hpp:113
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)
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
constexpr void reset_proxy(arrow_proxy &proxy)
pointer_iterator< inner_const_pointer > const_value_iterator
static constexpr u8_buffer< T > make_data_buffer(RANGE &&r)
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
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.
primitive_array_impl(Args &&... args)
Constructs an array of trivial copyable type with values and optional bitmap.
mutable_array_bitmap_base< primitive_array_impl< T > > base_type
primitive_array_impl(arrow_proxy)
Constructs a primitive array from an existing Arrow proxy.
constexpr primitive_array_impl(primitive_array_impl &&) noexcept
Move constructor.
typename inner_types::inner_reference inner_reference
typename inner_types::inner_const_reference inner_const_reference
constexpr primitive_array_impl & operator=(const primitive_array_impl &)
Copy assignment operator.
typename inner_types::const_pointer const_pointer
details::primitive_data_access< T > access_class_type
typename inner_types::inner_value_type inner_value_type
constexpr primitive_array_impl(const primitive_array_impl &)
Copy constructor.
A view that repeats a value a given number of times.
This buffer class is used as storage buffer for all sparrow arrays.
Concept for input containers that can provide metadata pairs.
Definition metadata.hpp:304
Concept defining valid input types for validity bitmap creation.
constexpr bool excludes_copy_and_move_ctor_v
Convenience variable template for excludes_copy_and_move_ctor.
constexpr bool is_type_instance_of_v
Variable template for convenient access to is_type_instance_of.
Definition mp_utils.hpp:102
array_bitmap_base_impl< D, true > mutable_array_bitmap_base
Convenient alias for arrays with mutable validity bitmaps.
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_to_format(data_type type)
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
Type alias for a validity bitmap using 8-bit storage blocks.
validity_bitmap ensure_validity_bitmap(std::size_t size, R &&validity_input)
Ensures a validity bitmap of the specified size from various input types.
std::pair< metadata_key, metadata_value > metadata_pair
Type alias for metadata key-value pairs.
Definition metadata.hpp:61
data_type
Runtime identifier of arrow data types, usually associated with raw bytes with the associated value.
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 specializations.
Traits class that must be specialized by array implementations.
Metafunction for retrieving the data_type of a typed array.