41 template <
class DERIVED>
53 requires std::same_as<T, list_array_impl<false>> || std::same_as<T, list_array_impl<true>>
60 requires std::same_as<T, list_view_array_impl<false>> || std::same_as<T, list_view_array_impl<true>>
63 return "list_view_array";
112 return "fixed_sized_list_array";
177 template <input_metadata_container METADATA_RANGE = std::vector<metadata_pair>>
181 std::optional<std::string_view> name,
182 std::optional<METADATA_RANGE> metadata,
187 std::optional<std::unordered_set<ArrowFlag>>
192 child_schemas[0] =
new ArrowSchema(std::move(flat_schema));
209 std::int64_t null_count,
217 child_arrays[0] =
new ArrowArray(std::move(flat_arr));
222 std::move(arr_buffs),
290 template <
class DERIVED>
405 using list_size_type =
inner_types::list_size_type;
409 template <
std::input_iterator InputIt>
416 [[nodiscard]]
array make_flat_array();
443 using offset_type = std::conditional_t<BIG, const std::int64_t, const std::int32_t>;
499 template <class... ARGS>
523 template <std::ranges::range SIZES_RANGE>
554 std::optional<std::string_view> name = std::nullopt,
555 std::optional<METADATA_RANGE> metadata = std::nullopt
578 std::ranges::input_range OFFSET_BUFFER_RANGE,
580 requires std::convertible_to<std::ranges::range_value_t<OFFSET_BUFFER_RANGE>,
offset_type>
583 OFFSET_BUFFER_RANGE&& list_offsets_range,
585 std::optional<std::string_view> name = std::nullopt,
586 std::optional<METADATA_RANGE> metadata = std::nullopt
589 offset_buffer_type list_offsets{std::forward<OFFSET_BUFFER_RANGE>(list_offsets_range)};
590 return list_array_impl<BIG>::create_proxy(
591 std::move(flat_values),
592 std::move(list_offsets),
593 std::forward<VB>(validity_input),
594 std::forward<std::optional<std::string_view>>(name),
595 std::forward<std::optional<METADATA_RANGE>>(metadata)
601 input_metadata_container METADATA_RANGE = std::vector<metadata_pair>>
602 [[nodiscard]]
static arrow_proxy create_proxy(
604 offset_buffer_type&& list_offsets,
605 bool nullable =
true,
606 std::optional<std::string_view> name = std::nullopt,
607 std::optional<METADATA_RANGE> metadata = std::nullopt
612 std::ranges::input_range OFFSET_BUFFER_RANGE,
613 input_metadata_container METADATA_RANGE = std::vector<metadata_pair>>
614 requires std::convertible_to<std::ranges::range_value_t<OFFSET_BUFFER_RANGE>, offset_type>
615 [[nodiscard]]
static arrow_proxy create_proxy(
617 OFFSET_BUFFER_RANGE&& list_offsets_range,
618 bool nullable =
true,
619 std::optional<std::string_view> name = std::nullopt,
620 std::optional<METADATA_RANGE> metadata = std::nullopt
623 offset_buffer_type list_offsets{std::forward<OFFSET_BUFFER_RANGE>(list_offsets_range)};
624 return list_array_impl<BIG>::create_proxy(
625 std::move(flat_values),
626 std::move(list_offsets),
628 std::forward<std::optional<std::string_view>>(name),
629 std::forward<std::optional<METADATA_RANGE>>(metadata)
633 static constexpr std::size_t OFFSET_BUFFER_INDEX = 1;
634 [[nodiscard]]
constexpr std::pair<offset_type, offset_type> offset_range(
size_type i)
const;
636 [[nodiscard]]
constexpr offset_type* make_list_offsets();
638 void replace_value(
size_type index,
const list_value& value);
667 using offset_type = std::conditional_t<BIG, const std::int64_t, const std::int32_t>;
725 template <
class... ARGS>
728 :
self_type(create_proxy(std::forward<ARGS>(args)...))
758 std::ranges::input_range OFFSET_BUFFER_RANGE,
759 std::ranges::input_range SIZE_RANGE,
763 std::convertible_to<std::ranges::range_value_t<OFFSET_BUFFER_RANGE>, offset_type>
764 && std::convertible_to<std::ranges::range_value_t<SIZE_RANGE>, list_size_type>
768 OFFSET_BUFFER_RANGE&& list_offsets,
769 SIZE_RANGE&& list_sizes,
771 std::optional<std::string_view> name = std::nullopt,
772 std::optional<METADATA_RANGE> metadata = std::nullopt
775 return list_view_array_impl<BIG>::create_proxy(
776 std::move(flat_values),
777 offset_buffer_type(std::forward<OFFSET_BUFFER_RANGE>(list_offsets)),
778 size_buffer_type(std::forward<SIZE_RANGE>(list_sizes)),
779 std::forward<VB>(validity_input),
786 validity_bitmap_input VB = validity_bitmap,
787 input_metadata_container METADATA_RANGE = std::vector<metadata_pair>>
788 [[nodiscard]]
static arrow_proxy create_proxy(
790 offset_buffer_type&& list_offsets,
791 size_buffer_type&& list_sizes,
793 std::optional<std::string_view> name = std::nullopt,
794 std::optional<METADATA_RANGE> metadata = std::nullopt
798 std::ranges::input_range OFFSET_BUFFER_RANGE,
799 std::ranges::input_range SIZE_RANGE,
800 input_metadata_container METADATA_RANGE = std::vector<metadata_pair>>
802 std::convertible_to<std::ranges::range_value_t<OFFSET_BUFFER_RANGE>, offset_type>
803 && std::convertible_to<std::ranges::range_value_t<SIZE_RANGE>, list_size_type>
805 [[nodiscard]]
static arrow_proxy create_proxy(
807 OFFSET_BUFFER_RANGE&& list_offsets,
808 SIZE_RANGE&& list_sizes,
809 bool nullable =
true,
810 std::optional<std::string_view> name = std::nullopt,
811 std::optional<METADATA_RANGE> metadata = std::nullopt
814 return list_view_array_impl<BIG>::create_proxy(
815 std::move(flat_values),
816 offset_buffer_type(std::forward<OFFSET_BUFFER_RANGE>(list_offsets)),
817 size_buffer_type(std::forward<SIZE_RANGE>(list_sizes)),
824 template <input_metadata_container METADATA_RANGE = std::vector<metadata_pair>>
825 [[nodiscard]]
static arrow_proxy create_proxy(
827 offset_buffer_type&& list_offsets,
828 size_buffer_type&& list_sizes,
829 bool nullable =
true,
830 std::optional<std::string_view> name = std::nullopt,
831 std::optional<METADATA_RANGE> metadata = std::nullopt
834 static constexpr std::size_t OFFSET_BUFFER_INDEX = 1;
835 static constexpr std::size_t SIZES_BUFFER_INDEX = 2;
836 [[nodiscard]]
constexpr std::pair<offset_type, offset_type> offset_range(size_type i)
const;
838 [[nodiscard]]
constexpr offset_type* make_list_offsets()
const;
839 [[nodiscard]]
constexpr const list_size_type* make_list_sizes()
const;
841 void replace_value(size_type index,
const list_value& value);
843 constexpr value_iterator
844 insert_value(const_value_iterator pos,
const list_value& value, size_type count);
846 template <std::input_iterator InputIt>
847 requires std::convertible_to<typename std::iterator_traits<InputIt>::value_type, list_value>
848 constexpr value_iterator insert_values(const_value_iterator pos, InputIt first, InputIt last);
850 constexpr value_iterator erase_values(const_value_iterator pos, size_type count);
852 offset_type* p_list_offsets;
906 template <
class... ARGS>
909 :
self_type(create_proxy(std::forward<ARGS>(args)...))
937 std::uint64_t list_size,
940 std::optional<std::string_view> name = std::nullopt,
941 std::optional<METADATA_RANGE> metadata = std::nullopt
966 std::uint64_t list_size,
969 std::optional<std::string_view> name = std::nullopt,
970 std::optional<METADATA_RANGE> metadata = std::nullopt
985 [[nodiscard]]
static uint64_t list_size_from_format(
const std::string_view format);
997 [[nodiscard]]
constexpr std::pair<offset_type, offset_type> offset_range(size_type i)
const;
999 [[nodiscard]]
constexpr size_type flat_element_count(size_type list_count)
const;
1001 void replace_value(size_type index,
const list_value& value);
1003 value_iterator insert_value(const_value_iterator pos,
const list_value& value, size_type count);
1005 value_iterator erase_values(const_value_iterator pos, size_type count);
1007 uint64_t m_list_size;
1021 template <
class DERIVED>
1024 , p_flat_array(make_flat_array())
1028 template <
class DERIVED>
1031 , p_flat_array(make_flat_array())
1035 template <
class DERIVED>
1039 p_flat_array = make_flat_array();
1043 template <
class DERIVED>
1046 return &p_flat_array;
1049 template <
class DERIVED>
1052 return &p_flat_array;
1055 template <
class DERIVED>
1058 if (this->get_arrow_proxy().offset() != 0)
1060 throw std::logic_error(std::string(operation) +
" does not support sliced arrays (non-zero offset)");
1064 template <
class DERIVED>
1070 template <
class DERIVED>
1079 template <
class DERIVED>
1088 template <
class DERIVED>
1097 template <
class DERIVED>
1098 constexpr auto list_array_crtp_base<DERIVED>::value(size_type i) -> inner_reference
1100 return inner_reference(&this->derived_cast(), i);
1103 template <
class DERIVED>
1104 constexpr auto list_array_crtp_base<DERIVED>::value(size_type i)
const -> inner_const_reference
1106 const auto r = this->derived_cast().offset_range(i);
1108 return list_value{&p_flat_array,
static_cast<st
>(r.first),
static_cast<st
>(r.second)};
1111 template <
class DERIVED>
1112 array list_array_crtp_base<DERIVED>::make_flat_array()
1114 auto& child_proxy = this->get_arrow_proxy().
children()[0];
1115 return array{&child_proxy.array(), &child_proxy.schema()};
1118 template <
class DERIVED>
1122 if (value.size() == 0)
1129 flat_array.
cbegin() +
static_cast<std::ptrdiff_t
>(flat_pos),
1130 value.flat_array()->cbegin() +
static_cast<std::ptrdiff_t
>(value.begin_index()),
1131 value.flat_array()->cbegin() +
static_cast<std::ptrdiff_t
>(value.end_index()),
1136 template <
class DERIVED>
1140 if (flat_count == 0)
1146 flat_array.
cbegin() +
static_cast<std::ptrdiff_t
>(flat_begin),
1147 flat_array.
cbegin() +
static_cast<std::ptrdiff_t
>(flat_begin + flat_count)
1151 template <
class DERIVED>
1152 constexpr void list_array_crtp_base<DERIVED>::resize_values(size_type new_length,
const list_value& value)
1154 DERIVED& derived =
static_cast<DERIVED&
>(*this);
1155 const size_type n = this->size();
1158 derived.erase_values(
1159 sparrow::next(this->value_cbegin(),
static_cast<std::ptrdiff_t
>(new_length)),
1163 else if (new_length > n)
1165 derived.insert_value(this->value_cend(), value, new_length - n);
1169 template <
class DERIVED>
1170 template <std::input_iterator InputIt>
1171 requires std::convertible_to<typename std::iterator_traits<InputIt>::value_type,
list_value>
1176 DERIVED& derived =
static_cast<DERIVED&
>(*this);
1179 for (
auto it = first; it != last; ++it, ++count)
1182 derived.insert_value(cur_pos, *it, 1);
1184 return sparrow::next(this->value_begin(),
static_cast<std::ptrdiff_t
>(idx));
1192# pragma GCC diagnostic push
1193# pragma GCC diagnostic ignored "-Wcast-align"
1199 , p_list_offsets(make_list_offsets())
1204 template <std::ranges::range SIZES_RANGE>
1208 std::forward<SIZES_RANGE>(sizes)
1213 template <val
idity_bitmap_input VB, input_metadata_container METADATA_RANGE>
1215 array&& flat_values,
1216 offset_buffer_type&& list_offsets,
1217 VB&& validity_input,
1218 std::optional<std::string_view> name,
1219 std::optional<METADATA_RANGE> metadata
1222 const auto size = list_offsets.size() - 1;
1224 const auto null_count = vbitmap.
null_count();
1229 BIG ? std::string(
"+L") : std::string(
"+l"),
1230 std::move(flat_schema),
1236 std::vector<buffer<std::uint8_t>> arr_buffs;
1237 arr_buffs.reserve(2);
1238 arr_buffs.emplace_back(std::move(vbitmap).extract_storage());
1239 arr_buffs.emplace_back(std::move(list_offsets).extract_storage());
1242 static_cast<std::int64_t
>(size),
1243 static_cast<std::int64_t
>(null_count),
1244 std::move(arr_buffs),
1248 return arrow_proxy{std::move(arr), std::move(schema)};
1252 template <val
idity_bitmap_input VB, input_metadata_container METADATA_RANGE>
1254 array&& flat_values,
1255 offset_buffer_type&& list_offsets,
1257 std::optional<std::string_view> name,
1258 std::optional<METADATA_RANGE> metadata
1263 return list_array_impl<BIG>::create_proxy(
1264 std::move(flat_values),
1265 std::move(list_offsets),
1272 const auto size = list_offsets.size() - 1;
1276 BIG ? std::string(
"+L") : std::string(
"+l"),
1277 std::move(flat_schema),
1283 std::vector<buffer<std::uint8_t>> arr_buffs;
1284 arr_buffs.reserve(2);
1286 arr_buffs.emplace_back(std::move(list_offsets).extract_storage());
1289 static_cast<std::int64_t
>(size),
1291 std::move(arr_buffs),
1295 return arrow_proxy{std::move(arr), std::move(schema)};
1301 , p_list_offsets(make_list_offsets())
1313 p_list_offsets = make_list_offsets();
1321 base_type::slice_inplace(start, end);
1322 p_list_offsets = make_list_offsets();
1326 constexpr auto list_array_impl<BIG>::offset_range(size_type i)
const -> std::pair<offset_type, offset_type>
1328 return std::make_pair(p_list_offsets[i], p_list_offsets[i + 1]);
1332 constexpr auto list_array_impl<BIG>::make_list_offsets() -> offset_type*
1334 return this->get_arrow_proxy().buffers()[OFFSET_BUFFER_INDEX].template data<offset_type>()
1335 +
static_cast<size_type
>(this->get_arrow_proxy().offset());
1340 list_array_impl<BIG>::insert_value(const_value_iterator pos,
const list_value& value, size_type count)
1343 using mutable_offset_type = std::remove_const_t<offset_type>;
1344 const auto idx =
static_cast<size_type
>(std::distance(this->value_cbegin(), pos));
1345 auto& proxy = this->get_arrow_proxy();
1347 this->throw_if_sliced_for_mutation(
"list_array_impl::insert_value");
1349 auto& offset_buffer = proxy.get_array_private_data()->buffers()[OFFSET_BUFFER_INDEX];
1351 const size_type n = offset_adaptor.size() - 1;
1354 const auto flat_insert_pos =
static_cast<size_type
>(p_list_offsets[idx]);
1355 this->insert_flat_elements(flat_insert_pos, value, count);
1358 const auto value_size = value.
size();
1359 const auto count_size =
count;
1362 const auto val_sz =
static_cast<mutable_offset_type
>(value_size);
1363 const auto count_mt =
static_cast<mutable_offset_type
>(count_size);
1364 const auto max_offset = std::numeric_limits<mutable_offset_type>::max();
1366 if (val_sz != mutable_offset_type{})
1370 const mutable_offset_type total_delta = count_mt * val_sz;
1372 const mutable_offset_type existing_max = offset_adaptor[n];
1375 offset_adaptor.resize(n + 1 + count, mutable_offset_type{});
1378 for (size_type i = n; i > idx; --i)
1380 offset_adaptor[i +
count] = offset_adaptor[i] + total_delta;
1383 const auto flat_insert_offset =
static_cast<mutable_offset_type
>(flat_insert_pos);
1385 for (size_type k = 1; k <=
count; ++k)
1387 offset_adaptor[idx + k] = flat_insert_offset +
static_cast<mutable_offset_type
>(k) * val_sz;
1390 proxy.update_buffers();
1391 p_list_offsets = make_list_offsets();
1392 return sparrow::next(this->value_begin(),
static_cast<std::ptrdiff_t
>(idx));
1396 constexpr auto list_array_impl<BIG>::erase_values(const_value_iterator pos, size_type count)
1399 using mutable_offset_type = std::remove_const_t<offset_type>;
1400 const size_type idx =
static_cast<size_type
>(std::distance(this->value_cbegin(), pos));
1401 const size_type n = this->
size();
1402 auto& proxy = this->get_arrow_proxy();
1406 return sparrow::next(this->value_begin(),
static_cast<std::ptrdiff_t
>(idx));
1409 this->throw_if_sliced_for_mutation(
"list_array_impl::erase_values");
1412 const mutable_offset_type flat_erase_begin = p_list_offsets[idx];
1413 const mutable_offset_type flat_erase_end = p_list_offsets[idx +
count];
1414 const mutable_offset_type flat_erase_count_val = flat_erase_end - flat_erase_begin;
1416 this->erase_flat_elements(
1417 static_cast<size_type
>(flat_erase_begin),
1418 static_cast<size_type
>(flat_erase_count_val)
1422 auto& offset_buffer = proxy.get_array_private_data()->buffers()[OFFSET_BUFFER_INDEX];
1425 offset_adaptor.begin() +
static_cast<std::ptrdiff_t
>(idx + count + 1),
1426 offset_adaptor.begin() +
static_cast<std::ptrdiff_t
>(n + 1),
1427 offset_adaptor.begin() +
static_cast<std::ptrdiff_t
>(idx + 1)
1429 auto delta_begin = offset_adaptor.begin() +
static_cast<std::ptrdiff_t
>(idx + 1);
1430 auto delta_end = offset_adaptor.begin() +
static_cast<std::ptrdiff_t
>(n + 1 -
count);
1435 [flat_erase_count_val](mutable_offset_type v)
1437 return v - flat_erase_count_val;
1440 offset_adaptor.resize(n + 1 - count);
1442 proxy.update_buffers();
1443 p_list_offsets = make_list_offsets();
1444 return sparrow::next(this->value_begin(),
static_cast<std::ptrdiff_t
>(idx));
1448 void list_array_impl<BIG>::replace_value(size_type index,
const list_value& value)
1450 using mutable_offset_type = std::remove_const_t<offset_type>;
1452 this->throw_if_sliced_for_mutation(
"list_array_impl::replace_value");
1453 const size_type new_size = value.size();
1456 const size_type n = this->
size();
1457 const auto [flat_begin, flat_end] = offset_range(index);
1458 const auto old_size =
static_cast<size_type
>(flat_end - flat_begin);
1459 const auto old_size_mt =
static_cast<mutable_offset_type
>(old_size);
1460 const auto new_size_mt =
static_cast<mutable_offset_type
>(new_size);
1463 const array* source = value.flat_array();
1464 if (source !=
nullptr && this->raw_flat_array() == source)
1466 source_owner = *source;
1467 source = &source_owner;
1470 if (old_size == new_size)
1478 const auto flat_begin_index =
static_cast<size_type
>(flat_begin);
1479 this->erase_flat_elements(flat_begin_index, old_size);
1480 this->insert_flat_elements(
1482 list_value{source, value.begin_index(), value.end_index()},
1485 auto& proxy_eq = this->get_arrow_proxy();
1486 proxy_eq.update_buffers();
1487 p_list_offsets = make_list_offsets();
1491 this->erase_flat_elements(
static_cast<size_type
>(flat_begin), old_size);
1495 this->insert_flat_elements(
1496 static_cast<size_type
>(flat_begin),
1497 list_value{source, value.begin_index(), value.end_index()},
1502 auto& proxy = this->get_arrow_proxy();
1503 auto& offset_buffer = proxy.get_array_private_data()->buffers()[OFFSET_BUFFER_INDEX];
1507 auto tail_begin = offset_adaptor.begin() +
static_cast<std::ptrdiff_t
>(index + 1);
1508 auto tail_end = offset_adaptor.begin() +
static_cast<std::ptrdiff_t
>(n + 1);
1509 if (new_size_mt > old_size_mt)
1511 const mutable_offset_type delta = new_size_mt - old_size_mt;
1512 const auto max_offset = std::numeric_limits<mutable_offset_type>::max();
1518 [delta](mutable_offset_type v)
1526 const mutable_offset_type delta = old_size_mt - new_size_mt;
1531 [delta](mutable_offset_type v)
1538 proxy.update_buffers();
1539 p_list_offsets = make_list_offsets();
1549 , p_list_offsets(make_list_offsets())
1550 , p_list_sizes(make_list_sizes())
1555 template <val
idity_bitmap_input VB, input_metadata_container METADATA_RANGE>
1556 arrow_proxy list_view_array_impl<BIG>::create_proxy(
1557 array&& flat_values,
1558 offset_buffer_type&& list_offsets,
1559 size_buffer_type&& list_sizes,
1560 VB&& validity_input,
1561 std::optional<std::string_view> name,
1562 std::optional<METADATA_RANGE> metadata
1565 SPARROW_ASSERT(list_offsets.size() == list_sizes.size(),
"sizes and offset must have the same size");
1566 const auto size = list_sizes.size();
1568 const auto null_count = vbitmap.
null_count();
1573 BIG ? std::string(
"+vL") : std::string(
"+vl"),
1574 std::move(flat_schema),
1580 std::vector<buffer<std::uint8_t>> arr_buffs;
1581 arr_buffs.reserve(3);
1582 arr_buffs.emplace_back(std::move(vbitmap).extract_storage());
1583 arr_buffs.emplace_back(std::move(list_offsets).extract_storage());
1584 arr_buffs.emplace_back(std::move(list_sizes).extract_storage());
1587 static_cast<std::int64_t
>(size),
1588 static_cast<std::int64_t
>(null_count),
1589 std::move(arr_buffs),
1593 return arrow_proxy{std::move(arr), std::move(schema)};
1597 template <input_metadata_container METADATA_RANGE>
1598 arrow_proxy list_view_array_impl<BIG>::create_proxy(
1599 array&& flat_values,
1600 offset_buffer_type&& list_offsets,
1601 size_buffer_type&& list_sizes,
1603 std::optional<std::string_view> name,
1604 std::optional<METADATA_RANGE> metadata
1609 return list_view_array_impl<BIG>::create_proxy(
1610 std::move(flat_values),
1611 std::move(list_offsets),
1612 std::move(list_sizes),
1619 SPARROW_ASSERT(list_offsets.size() == list_sizes.size(),
"sizes and offset must have the same size");
1620 const auto size = list_sizes.size();
1624 BIG ? std::string(
"+vL") : std::string(
"+vl"),
1625 std::move(flat_schema),
1631 std::vector<buffer<std::uint8_t>> arr_buffs;
1632 arr_buffs.reserve(3);
1634 arr_buffs.emplace_back(std::move(list_offsets).extract_storage());
1635 arr_buffs.emplace_back(std::move(list_sizes).extract_storage());
1638 static_cast<std::int64_t
>(size),
1640 std::move(arr_buffs),
1644 return arrow_proxy{std::move(arr), std::move(schema)};
1650 , p_list_offsets(make_list_offsets())
1651 , p_list_sizes(make_list_sizes())
1663 p_list_offsets = make_list_offsets();
1664 p_list_sizes = make_list_sizes();
1672 base_type::slice_inplace(start, end);
1673 p_list_offsets = make_list_offsets();
1674 p_list_sizes = make_list_sizes();
1678 inline constexpr auto list_view_array_impl<BIG>::offset_range(size_type i)
const
1679 -> std::pair<offset_type, offset_type>
1681 const auto offset = p_list_offsets[i];
1683 return std::make_pair(offset, offset +
static_cast<offset_type
>(p_list_sizes[i]));
1687 constexpr auto list_view_array_impl<BIG>::make_list_offsets() const -> offset_type*
1689 return this->get_arrow_proxy().buffers()[OFFSET_BUFFER_INDEX].template data<offset_type>()
1690 +
static_cast<size_type
>(this->get_arrow_proxy().offset());
1694 constexpr auto list_view_array_impl<BIG>::make_list_sizes() const -> const list_size_type*
1696 return this->get_arrow_proxy().buffers()[SIZES_BUFFER_INDEX].template data<list_size_type>()
1697 +
static_cast<size_type
>(this->get_arrow_proxy().offset());
1702 list_view_array_impl<BIG>::insert_value(const_value_iterator pos,
const list_value& value, size_type count)
1705 using mutable_offset_type = std::remove_const_t<offset_type>;
1706 using mutable_size_type = std::remove_const_t<list_size_type>;
1707 const size_type idx =
static_cast<size_type
>(std::distance(this->value_cbegin(), pos));
1709 this->throw_if_sliced_for_mutation(
"list_view_array_impl::insert_value");
1714 const mutable_offset_type val_sz =
static_cast<mutable_offset_type
>(value.size());
1715 const size_type flat_append_pos = this->raw_flat_array()->size();
1717 this->insert_flat_elements(flat_append_pos, value, count);
1719 auto& proxy = this->get_arrow_proxy();
1722 const size_type n = this->
size();
1724 auto& offset_buffer = proxy.get_array_private_data()->buffers()[OFFSET_BUFFER_INDEX];
1726 offset_adaptor.resize(n + count);
1728 auto& sizes_buffer = proxy.get_array_private_data()->buffers()[SIZES_BUFFER_INDEX];
1730 sizes_adaptor.resize(n + count);
1735 offset_adaptor.begin() +
static_cast<std::ptrdiff_t
>(idx),
1736 offset_adaptor.begin() +
static_cast<std::ptrdiff_t
>(n),
1737 offset_adaptor.begin() +
static_cast<std::ptrdiff_t
>(n + count)
1740 sizes_adaptor.begin() +
static_cast<std::ptrdiff_t
>(idx),
1741 sizes_adaptor.begin() +
static_cast<std::ptrdiff_t
>(n),
1742 sizes_adaptor.begin() +
static_cast<std::ptrdiff_t
>(n + count)
1747 if (count > 0 && val_sz > 0)
1749 const auto base_offset_ull =
static_cast<unsigned long long>(flat_append_pos);
1750 const auto step_ull =
static_cast<unsigned long long>(val_sz);
1751 const auto max_k_ull =
static_cast<unsigned long long>(
count - 1);
1752 const auto max_offset_ull =
static_cast<unsigned long long>(
1753 std::numeric_limits<mutable_offset_type>::max()
1755 const auto last_offset_ull = base_offset_ull + max_k_ull * step_ull;
1759 for (size_type k = 0; k <
count; ++k)
1761 offset_adaptor[idx + k] =
static_cast<mutable_offset_type
>(flat_append_pos)
1762 +
static_cast<mutable_offset_type
>(k) * val_sz;
1763 sizes_adaptor[idx + k] =
static_cast<mutable_size_type
>(val_sz);
1766 proxy.update_buffers();
1767 p_list_offsets = make_list_offsets();
1768 p_list_sizes = make_list_sizes();
1769 return sparrow::next(this->value_begin(),
static_cast<std::ptrdiff_t
>(idx));
1773 template <std::input_iterator InputIt>
1774 requires std::convertible_to<typename std::iterator_traits<InputIt>::value_type,
list_value>
1780 auto& proxy = this->get_arrow_proxy();
1781 const size_type original_size = this->size();
1782 if constexpr (std::forward_iterator<InputIt>)
1784 const auto count =
static_cast<size_type>(std::distance(first, last));
1787 return sparrow::next(this->value_begin(),
static_cast<std::ptrdiff_t
>(idx));
1791 proxy.set_length(original_size + count);
1792 for (
auto it = first; it != last; ++it)
1796 static_cast<std::ptrdiff_t
>(idx + inserted_count)
1798 insert_value(cur_pos, *it, 1);
1801 proxy.set_length(original_size);
1806 for (
auto it = first; it != last; ++it)
1810 static_cast<std::ptrdiff_t
>(idx + inserted_count)
1812 insert_value(cur_pos, *it, 1);
1814 proxy.set_length(original_size + inserted_count);
1816 proxy.set_length(original_size);
1818 return sparrow::next(this->value_begin(),
static_cast<std::ptrdiff_t
>(idx));
1822 constexpr auto list_view_array_impl<BIG>::erase_values(const_value_iterator pos, size_type count)
1825 using mutable_offset_type = std::remove_const_t<offset_type>;
1826 using mutable_size_type = std::remove_const_t<list_size_type>;
1827 const size_type idx =
static_cast<size_type
>(std::distance(this->value_cbegin(), pos));
1828 const size_type n = this->size();
1832 return sparrow::next(this->value_begin(),
static_cast<std::ptrdiff_t
>(idx));
1835 this->throw_if_sliced_for_mutation(
"list_view_array_impl::erase_values");
1837 auto& proxy = this->get_arrow_proxy();
1838 auto& offset_buffer = proxy.get_array_private_data()->buffers()[OFFSET_BUFFER_INDEX];
1841 auto& sizes_buffer = proxy.get_array_private_data()->buffers()[SIZES_BUFFER_INDEX];
1846 offset_adaptor.begin() +
static_cast<std::ptrdiff_t
>(idx + count),
1847 offset_adaptor.end(),
1848 offset_adaptor.begin() +
static_cast<std::ptrdiff_t
>(idx)
1851 sizes_adaptor.begin() +
static_cast<std::ptrdiff_t
>(idx + count),
1852 sizes_adaptor.end(),
1853 sizes_adaptor.begin() +
static_cast<std::ptrdiff_t
>(idx)
1855 offset_adaptor.resize(n - count);
1856 sizes_adaptor.resize(n - count);
1857 proxy.update_buffers();
1858 p_list_offsets = make_list_offsets();
1859 p_list_sizes = make_list_sizes();
1860 return sparrow::next(this->value_begin(),
static_cast<std::ptrdiff_t
>(idx));
1864 void list_view_array_impl<BIG>::replace_value(size_type index,
const list_value& value)
1866 using mutable_offset_type = std::remove_const_t<offset_type>;
1867 using mutable_size_type = std::remove_const_t<list_size_type>;
1869 this->throw_if_sliced_for_mutation(
"list_view_array_impl::replace_value");
1874 const auto value_size =
static_cast<mutable_offset_type
>(value.size());
1875 const size_type flat_append_pos = this->raw_flat_array()->size();
1878 this->insert_flat_elements(flat_append_pos, value, 1);
1880 auto& proxy = this->get_arrow_proxy();
1881 auto& offset_buffer = proxy.get_array_private_data()->buffers()[OFFSET_BUFFER_INDEX];
1883 auto& sizes_buffer = proxy.get_array_private_data()->buffers()[SIZES_BUFFER_INDEX];
1885 offset_adaptor[index] =
static_cast<mutable_offset_type
>(flat_append_pos);
1886 sizes_adaptor[index] =
static_cast<mutable_size_type
>(value_size);
1887 proxy.update_buffers();
1888 p_list_offsets = make_list_offsets();
1889 p_list_sizes = make_list_sizes();
1893# pragma GCC diagnostic pop
1900 inline auto fixed_sized_list_array::list_size_from_format(
const std::string_view format) -> uint64_t
1903 const auto n_digits = format.size() - 3;
1904 const auto list_size_str = format.substr(3, n_digits);
1905 return std::stoull(std::string(list_size_str));
1916 , m_list_size(rhs.m_list_size)
1927 m_list_size = rhs.m_list_size;
1932 constexpr auto fixed_sized_list_array::offset_range(size_type i)
const
1933 -> std::pair<offset_type, offset_type>
1935 const auto offset = (i + this->offset()) * m_list_size;
1936 return std::make_pair(offset, offset + m_list_size);
1939 constexpr auto fixed_sized_list_array::flat_element_count(size_type list_count)
const -> size_type
1941 const offset_type max_flat_count =
static_cast<offset_type
>(std::numeric_limits<size_type>::max());
1943 m_list_size == 0 ||
static_cast<offset_type
>(list_count) <= max_flat_count / m_list_size
1945 return static_cast<size_type
>(
static_cast<offset_type
>(list_count) * m_list_size);
1949 fixed_sized_list_array::insert_value(const_value_iterator pos,
const list_value& value, size_type count)
1953 const auto idx =
static_cast<size_type
>(std::distance(this->value_cbegin(), pos));
1955 this->throw_if_sliced_for_mutation(
"fixed_sized_list_array::insert_value");
1957 const size_type flat_insert_pos = flat_element_count(idx);
1959 this->insert_flat_elements(flat_insert_pos, value, count);
1961 return sparrow::next(this->value_begin(),
static_cast<std::ptrdiff_t
>(idx));
1964 inline auto fixed_sized_list_array::erase_values(const_value_iterator pos, size_type count) -> value_iterator
1966 const auto idx =
static_cast<size_type
>(std::distance(this->value_cbegin(), pos));
1969 return sparrow::next(this->value_begin(),
static_cast<std::ptrdiff_t
>(idx));
1972 this->throw_if_sliced_for_mutation(
"fixed_sized_list_array::erase_values");
1974 this->erase_flat_elements(flat_element_count(idx), flat_element_count(count));
1975 return sparrow::next(this->value_begin(),
static_cast<std::ptrdiff_t
>(idx));
1978 inline void fixed_sized_list_array::replace_value(size_type index,
const list_value& value)
1984 if (m_list_size == 0)
1990 const array* source = value.flat_array();
1993 source_owner = *source;
1994 source = &source_owner;
1998 const size_type flat_index = flat_element_count(index);
2000 this->
insert_flat_elements(flat_index, list_value{source, value.begin_index(), value.end_index()}, 1);
2003 template <val
idity_bitmap_input R, input_metadata_container METADATA_RANGE>
2004 inline arrow_proxy fixed_sized_list_array::create_proxy(
2005 std::uint64_t list_size,
2006 array&& flat_values,
2008 std::optional<std::string_view> name,
2009 std::optional<METADATA_RANGE> metadata
2012 const auto size = flat_values.size() /
static_cast<std::size_t
>(list_size);
2014 const auto null_count = vbitmap.null_count();
2018 std::string format =
"+w:" + std::to_string(list_size);
2021 std::move(flat_schema),
2027 std::vector<buffer<std::uint8_t>> arr_buffs;
2028 arr_buffs.reserve(1);
2029 arr_buffs.emplace_back(vbitmap.extract_storage());
2032 static_cast<std::int64_t
>(size),
2033 static_cast<std::int64_t
>(null_count),
2034 std::move(arr_buffs),
2038 return arrow_proxy{std::move(arr), std::move(schema)};
2041 template <val
idity_bitmap_input R, input_metadata_container METADATA_RANGE>
2042 inline arrow_proxy fixed_sized_list_array::create_proxy(
2043 std::uint64_t list_size,
2044 array&& flat_values,
2046 std::optional<std::string_view> name,
2047 std::optional<METADATA_RANGE> metadata
2052 return fixed_sized_list_array::create_proxy(
2054 std::move(flat_values),
2061 const auto size = flat_values.size() /
static_cast<std::size_t
>(list_size);
2064 std::string format =
"+w:" + std::to_string(list_size);
2067 std::move(flat_schema),
2073 std::vector<buffer<std::uint8_t>> arr_buffs;
2074 arr_buffs.reserve(1);
2078 static_cast<std::int64_t
>(size),
2080 std::move(arr_buffs),
2084 return arrow_proxy{std::move(arr), std::move(schema)};
typename base_type::const_bitmap_range const_bitmap_range
typename base_type::iterator_tag iterator_tag
constexpr array_bitmap_base_impl & operator=(const array_bitmap_base_impl &)
typename base_type::bitmap_const_reference bitmap_const_reference
typename base_type::bitmap_type bitmap_type
Dynamically typed array encapsulating an Arrow layout.
SPARROW_API iterator erase(const_iterator pos)
Inserts a copy of value before pos in the array, repeating the insertion count times.
SPARROW_API iterator insert(const_iterator pos, const_iterator first, const_iterator last)
Inserts elements from the range [first, last) before the element at the specified position.
SPARROW_API const_iterator cbegin() const
Returns a constant iterator to the beginning of the array.
Object that owns a piece of contiguous memory.
xsimd::aligned_allocator< T > default_allocator
constexpr size_type null_count() const noexcept
Returns the number of bits set to false (null/invalid).
typename storage_type::default_allocator default_allocator
friend class list_reference
typename base_type::value_iterator value_iterator
inner_types::list_size_type list_size_type
array_inner_types< self_type > inner_types
fixed_sized_list_array(arrow_proxy proxy)
Constructs fixed size list array from Arrow proxy.
fixed_sized_list_array(ARGS &&... args)
Generic constructor for creating fixed size list array.
list_array_crtp_base< self_type > base_type
fixed_sized_list_array self_type
fixed_sized_list_array & operator=(self_type &&)=default
typename base_type::const_value_iterator const_value_iterator
fixed_sized_list_array(self_type &&)=default
fixed_sized_list_array & operator=(const self_type &)
typename base_type::size_type size_type
std::uint64_t offset_type
CRTP base class for all list array implementations.
constexpr void throw_if_sliced_for_mutation(const char *operation) const
typename base_type::const_bitmap_range const_bitmap_range
constexpr list_array_crtp_base & operator=(const self_type &)
Copy assignment operator.
constexpr array * raw_flat_array()
Gets mutable access to the underlying flat array.
nullable< inner_const_reference, bitmap_const_reference > const_reference
typename inner_types::const_value_iterator const_value_iterator
list_value inner_value_type
typename base_type::bitmap_const_reference bitmap_const_reference
constexpr void insert_flat_elements(size_type flat_pos, const list_value &value, size_type count)
typename inner_types::inner_const_reference inner_const_reference
typename base_type::iterator_tag iterator_tag
mutable_array_bitmap_base< DERIVED > base_type
typename base_type::bitmap_reference bitmap_reference
list_array_crtp_base(arrow_proxy proxy)
Constructs list array base from Arrow proxy.
constexpr list_array_crtp_base(const self_type &)
Copy constructor.
constexpr const_value_iterator value_cbegin() const
constexpr void erase_flat_elements(size_type flat_begin, size_type flat_count)
typename inner_types::value_iterator value_iterator
constexpr const_value_iterator value_cend() const
typename base_type::bitmap_type bitmap_type
list_array_crtp_base< DERIVED > self_type
typename base_type::size_type size_type
array_inner_types< DERIVED > inner_types
nullable< inner_reference, bitmap_reference > reference
nullable< inner_value_type > value_type
typename inner_types::inner_reference inner_reference
constexpr value_iterator value_begin()
constexpr const array * raw_flat_array() const
Gets read-only access to the underlying flat array.
constexpr value_iterator value_end()
constexpr list_array_crtp_base(self_type &&) noexcept=default
list_array_impl< BIG > self_type
constexpr void slice_inplace(size_type start, size_type end)
constexpr list_array_impl(const self_type &)
Copy constructor.
std::conditional_t< BIG, const std::int64_t, const std::int32_t > offset_type
friend class list_reference
typename base_type::size_type size_type
constexpr list_array_impl & operator=(const self_type &)
Copy assignment operator.
typename base_type::value_iterator value_iterator
array_inner_types< self_type > inner_types
constexpr list_array_impl(self_type &&) noexcept=default
static constexpr auto offset_from_sizes(SIZES_RANGE &&sizes) -> offset_buffer_type
Creates offset buffer from list sizes.
typename base_type::const_value_iterator const_value_iterator
inner_types::list_size_type list_size_type
list_array_crtp_base< list_array_impl< BIG > > base_type
u8_buffer< std::remove_const_t< offset_type > > offset_buffer_type
list_array_impl(arrow_proxy proxy)
Constructs list array from Arrow proxy.
size_type size() const
Gets the number of elements in the list.
constexpr list_view_array_impl & operator=(self_type &&)=default
typename base_type::size_type size_type
constexpr void slice_inplace(size_type start, size_type end)
constexpr list_view_array_impl(self_type &&)=default
friend class list_reference
u8_buffer< std::remove_const_t< offset_type > > offset_buffer_type
list_view_array_impl(arrow_proxy proxy)
Constructs list view array from Arrow proxy.
std::conditional_t< BIG, const std::int64_t, const std::int32_t > offset_type
array_inner_types< self_type > inner_types
list_array_crtp_base< list_view_array_impl< BIG > > base_type
typename base_type::const_value_iterator const_value_iterator
typename base_type::value_iterator value_iterator
list_view_array_impl(ARGS &&... args)
Generic constructor for creating list view array from various inputs.
list_view_array_impl< BIG > self_type
constexpr list_view_array_impl(const self_type &)
Copy constructor.
inner_types::list_size_type list_size_type
u8_buffer< std::remove_const_t< list_size_type > > size_buffer_type
constexpr list_view_array_impl & operator=(const self_type &)
Copy assignment operator.
Base class definining common interface for arrays with a bitmap.
A view that repeats a value a given number of times.
This buffer class is used as storage buffer for all sparrow arrays.
#define SPARROW_ASSERT_TRUE(expr__)
#define SPARROW_ASSERT(expr__, message__)
SPARROW_API void increase(const std::string &key)
std::string key< fixed_sized_list_array >()
SPARROW_API int count(const std::string &key, int disabled_value=0)
ArrowArray make_list_arrow_array(std::int64_t size, std::int64_t null_count, std::vector< buffer< std::uint8_t > > &&arr_buffs, ArrowArray &&flat_arr)
ArrowSchema make_list_arrow_schema(std::string format, ArrowSchema &&flat_schema, std::optional< std::string_view > name, std::optional< METADATA_RANGE > metadata, bool nullable)
constexpr sparrow::u8_buffer< OFFSET_TYPE > offset_buffer_from_sizes(SIZES_RANGE &&sizes)
constexpr std::size_t size(typelist< T... >={})
Gets the count of types contained in a typelist.
constexpr bool excludes_copy_and_move_ctor_v
Convenience variable template for excludes_copy_and_move_ctor.
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 bool is_list_view_array_v
Checks whether T is a list_view_array type.
list_array_impl< false > list_array
A list array implementation.
constexpr InputIt next(InputIt it, Distance n)
constexpr bool is_fixed_sized_list_array_v
Checks whether T is a fixed_sized_list_array type.
list_view_array_impl< true > big_list_view_array
std::pair< ArrowArray, ArrowSchema > extract_arrow_structures(A &&a)
Extracts the internal ArrowArray and ArrowSchema structures from the given array or typed layout.
constexpr bool is_big_list_array_v
Checks whether T is a big_list_array 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.
list_view_array_impl< false > list_view_array
A list view array implementation.
dynamic_bitset< std::uint8_t > validity_bitmap
Type alias for a validity bitmap using 8-bit storage blocks.
constexpr bool is_list_array_v
Checks whether T is a list_array type.
list_array_impl< true > big_list_array
A big list array implementation.
auto make_buffer_adaptor(FromBufferRef &buf)
validity_bitmap ensure_validity_bitmap(std::size_t size, R &&validity_input)
Ensures a validity bitmap of the specified size from various input types.
constexpr bool is_big_list_view_array_v
Checks whether T is a big_list_view_array type.
data_type
Runtime identifier of arrow data types, usually associated with raw bytes with the associated value.
Extensions to the C++ standard library.
list_value inner_value_type
std::random_access_iterator_tag iterator_tag
functor_index_iterator< detail::layout_value_functor< const array_type, inner_const_reference > > const_value_iterator
fixed_sized_list_array array_type
list_value inner_const_reference
std::uint64_t list_size_type
list_reference< array_type > inner_reference
functor_index_iterator< detail::layout_value_functor< array_type, inner_reference > > value_iterator
std::conditional_t< BIG, std::uint64_t, std::uint32_t > list_size_type
functor_index_iterator< detail::layout_value_functor< const array_type, inner_const_reference > > const_value_iterator
std::random_access_iterator_tag iterator_tag
list_array_impl< BIG > array_type
functor_index_iterator< detail::layout_value_functor< array_type, inner_reference > > value_iterator
list_value inner_value_type
list_reference< array_type > inner_reference
list_value inner_const_reference
list_value inner_value_type
list_value inner_const_reference
list_reference< array_type > inner_reference
std::random_access_iterator_tag iterator_tag
functor_index_iterator< detail::layout_value_functor< array_type, inner_reference > > value_iterator
functor_index_iterator< detail::layout_value_functor< const array_type, inner_const_reference > > const_value_iterator
std::conditional_t< BIG, std::uint64_t, std::uint32_t > list_size_type
list_view_array_impl< BIG > array_type
Base class for array_inner_types specializations.
Traits class that must be specialized by array implementations.
static constexpr sparrow::data_type get()
static constexpr sparrow::data_type get()
static constexpr sparrow::data_type get()
Metafunction for retrieving the data_type of a typed array.