sparrow 0.3.0
Loading...
Searching...
No Matches
arrow_array_schema_utils.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#pragma once
16
17#include <algorithm>
18#include <optional>
19#include <ranges>
20#include <tuple>
21#include <type_traits>
22#include <vector>
23
27
28namespace sparrow
29{
30 /*
31 * Class for tracking ownership of children of an `ArrowArray` or
32 * an `ArrowSchema` allocated by sparrow.
33 */
35 {
36 public:
37
38 [[nodiscard]] constexpr std::size_t children_size() const noexcept;
39 constexpr void set_child_ownership(std::size_t child, bool ownership);
40 [[nodiscard]] constexpr bool has_child_ownership(std::size_t child) const;
41
42 constexpr void resize_children(std::size_t size);
43
44 protected:
45
46 constexpr explicit children_ownership(std::size_t size = 0);
47
48 private:
49
50 using children_owner_list = std::vector<bool>;
51 children_owner_list m_children = {};
52 };
53
60 template <class T>
61 requires std::same_as<T, ArrowArray> || std::same_as<T, ArrowSchema>
62 void release_common_arrow(T& t);
63
74 template <class T>
75 [[nodiscard]] constexpr int64_t ssize(const T& value);
76
89 template <typename T, typename U>
90 [[nodiscard]] constexpr T* get_raw_ptr(U& var);
91
102 template <class T, std::ranges::input_range Range, class Allocator = std::allocator<T*>>
103 requires(!std::ranges::view<Range>)
104 [[nodiscard]] constexpr std::vector<T*, Allocator> to_raw_ptr_vec(Range& range);
105
116 template <class T, class Optional, class Allocator = std::allocator<T*>>
118 [[nodiscard]] constexpr std::vector<T*, Allocator> to_raw_ptr_vec(Optional& optional);
119
132 template <class T, class Tuple, class Allocator = std::allocator<T*>>
134 [[nodiscard]] constexpr std::vector<T*, Allocator> to_raw_ptr_vec(Tuple& tuple);
135
140 template <class T>
141 requires std::same_as<T, std::nullopt_t>
144 || (std::ranges::range<T> && mpl::testable<std::ranges::range_value_t<T>>)
145 [[nodiscard]] constexpr bool all_element_are_true(const T& elements);
146
147 /******************
148 * Implementation *
149 ******************/
150
151 constexpr children_ownership::children_ownership(std::size_t size)
152 : m_children(size, true)
153 {
154 }
155
156 [[nodiscard]] constexpr std::size_t children_ownership::children_size() const noexcept
157 {
158 return m_children.size();
159 }
160
161 constexpr void children_ownership::set_child_ownership(std::size_t child, bool ownership)
162 {
163 m_children[child] = ownership;
164 }
165
166 [[nodiscard]] constexpr bool children_ownership::has_child_ownership(std::size_t child) const
167 {
168 return m_children[child];
169 }
170
171 constexpr void children_ownership::resize_children(std::size_t size)
172 {
173 m_children.resize(size);
174 }
175
176 template <class T>
177 requires std::same_as<T, ArrowArray> || std::same_as<T, ArrowSchema>
179 {
180 if (t.release == nullptr)
181 {
182 return;
183 }
184
185 if (t.dictionary)
186 {
187 if (t.dictionary->release)
188 {
189 t.dictionary->release(t.dictionary);
190 }
191 }
192
193 if (t.children)
194 {
195 for (int64_t i = 0; i < t.n_children; ++i)
196 {
197 T* child = t.children[i];
198 if (child)
199 {
200 if (child->release)
201 {
202 SPARROW_ASSERT_TRUE(t.private_data != nullptr);
203 children_ownership* own = static_cast<children_ownership*>(t.private_data);
204 if (own->has_child_ownership(static_cast<std::size_t>(i)))
205 {
206 child->release(child);
207 delete child;
208 child = nullptr;
209 }
210 }
211 }
212 }
213 delete[] t.children;
214 t.children = nullptr;
215 }
216 t.release = nullptr;
217 }
218
219 template <class T>
220 constexpr int64_t ssize(const T& value)
221 {
222 if constexpr (std::ranges::sized_range<T>)
223 {
224 return static_cast<int64_t>(std::ranges::size(value));
225 }
227 {
228 return std::tuple_size_v<T>;
229 }
231 {
232 if (value.has_value())
233 {
234 return ssize(*value);
235 }
236 else
237 {
238 return 0;
239 }
240 }
241 else
242 {
243 return 0;
244 }
245 }
246
247 template <typename T, typename U>
248 constexpr T* get_raw_ptr(U& var)
249 {
250 if constexpr (std::is_pointer_v<U>)
251 {
252 return var;
253 }
254 else if constexpr (requires { typename U::element_type; })
255 {
256 if constexpr (mpl::smart_ptr<U> || std::is_base_of_v<std::shared_ptr<typename U::element_type>, U>
258 {
259 if constexpr (std::ranges::contiguous_range<typename U::element_type>)
260 {
261 return std::ranges::data(*var.get());
262 }
263 else if constexpr (std::same_as<typename U::element_type, T> || std::same_as<T, void>)
264 {
265 return var.get();
266 }
267 }
268 }
269 else if constexpr (std::ranges::contiguous_range<U>)
270 {
271 return std::ranges::data(var);
272 }
273 else if constexpr (std::same_as<T, U> || std::same_as<T, void>)
274 {
275 return &var;
276 }
277 else
278 {
279 static_assert(mpl::dependent_false<T, U>::value, "get_raw_ptr: unsupported type.");
281 }
282 }
283
284 template <class T, std::ranges::input_range Range, class Allocator>
285 requires(!std::ranges::view<Range>)
286 constexpr std::vector<T*, Allocator> to_raw_ptr_vec(Range& range)
287 {
288 std::vector<T*, Allocator> raw_ptr_vec;
289 raw_ptr_vec.reserve(range.size());
290 std::ranges::transform(
291 range,
292 std::back_inserter(raw_ptr_vec),
293 [](auto& elem) -> T*
294 {
295 return get_raw_ptr<T>(elem);
296 }
297 );
298 return raw_ptr_vec;
299 }
300
301 template <class T, class Optional, class Allocator>
303 constexpr std::vector<T*, Allocator> to_raw_ptr_vec(Optional& optional)
304 {
305 if (!optional.has_value())
306 {
307 return {};
308 }
309 return to_raw_ptr_vec<T>(*optional);
310 }
311
312 template <class T, class Tuple, class Allocator>
314 constexpr std::vector<T*, Allocator> to_raw_ptr_vec(Tuple& tuple)
315 {
316 std::vector<T*, Allocator> raw_ptr_vec;
317 raw_ptr_vec.reserve(std::tuple_size_v<Tuple>);
318 std::apply(
319 [&raw_ptr_vec](auto&&... args)
320 {
321 (raw_ptr_vec.push_back(get_raw_ptr<T>(args)), ...);
322 },
323 tuple
324 );
325 return raw_ptr_vec;
326 }
327
328 template <class T>
329 requires std::same_as<T, std::nullopt_t>
331 && mpl::testable<std::ranges::range_value_t<typename T::value_type>>)
332 || (std::ranges::range<T> && mpl::testable<std::ranges::range_value_t<T>>)
333 constexpr bool all_element_are_true(const T& elements)
334 {
335 if constexpr (!std::same_as<T, std::nullopt_t>)
336 {
338 {
339 if (elements.has_value())
340 {
341 return std::ranges::all_of(
342 *elements,
343 [](const auto& child)
344 {
345 return bool(child);
346 }
347 );
348 }
349 else
350 {
351 return true;
352 }
353 }
354 else
355 {
356 return std::ranges::all_of(
357 elements,
358 [](const auto& element)
359 {
360 return bool(element);
361 }
362 );
363 }
364 }
365 else
366 {
367 return true;
368 }
369 }
370
371}
constexpr children_ownership(std::size_t size=0)
constexpr std::size_t children_size() const noexcept
constexpr bool has_child_ownership(std::size_t child) const
constexpr void set_child_ownership(std::size_t child, bool ownership)
constexpr void resize_children(std::size_t size)
#define SPARROW_ASSERT_TRUE(expr__)
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
void unreachable()
Invokes undefined behavior.
Definition mp_utils.hpp:425
constexpr int64_t ssize(const T &value)
Get the size of a range, a tuple or an optional.
constexpr std::vector< T *, Allocator > to_raw_ptr_vec(Range &range)
Create a vector of pointers to elements from a range.
void release_common_arrow(T &t)
Release the children and dictionnary of an ArrowArray or ArrowSchema.
constexpr bool all_element_are_true(const T &elements)
Check if all elements of a range or std::optional<range> are valid by caling their bool operator.
constexpr T * get_raw_ptr(U &var)
Get a raw pointer from a smart pointer, a range, an object or a pointer.
ownership
Specifies the ownership model when passing Arrow data to another system.
Workaround to replace static_assert(false) in template code.
Definition mp_utils.hpp:33