sparrow 2.3.0
C++20 idiomatic APIs for the Apache Arrow Columnar Format
Loading...
Searching...
No Matches
null_count_policy.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 <concepts>
18#include <cstddef>
19#include <cstdint>
20#include <utility>
21
23
24namespace sparrow
25{
34 [[nodiscard]] SPARROW_API std::size_t count_non_null(
35 const std::uint8_t* data,
36 std::size_t bit_size,
37 std::size_t byte_size,
38 std::size_t offset = 0
39 ) noexcept;
40
55 template <typename SizeType = std::size_t>
57 {
58 public:
59
60 static constexpr bool track_null_count = true;
61 using size_type = SizeType;
62
63 constexpr tracking_null_count() noexcept = default;
64
65 constexpr explicit tracking_null_count(size_type count) noexcept
66 : m_null_count(count)
67 {
68 }
69
78 template <std::integral BlockType>
80 const BlockType* data,
81 size_type bit_size,
82 size_type block_count,
83 size_type offset = 0
84 ) noexcept
85 {
86 recompute_null_count(data, bit_size, block_count, offset);
87 }
88
89 [[nodiscard]] constexpr size_type null_count() const noexcept
90 {
91 return m_null_count;
92 }
93
94 constexpr void set_null_count(size_type count) noexcept
95 {
96 m_null_count = count;
97 }
98
107 template <std::integral BlockType>
108 void
109 recompute_null_count(const BlockType* data, size_type bit_size, size_type block_count, size_type offset = 0) noexcept
110 {
111 const auto* byte_data = reinterpret_cast<const std::uint8_t*>(data);
112 const std::size_t byte_size = block_count * sizeof(BlockType);
113 m_null_count = static_cast<size_type>(bit_size)
114 - static_cast<size_type>(count_non_null(
115 byte_data,
116 static_cast<std::size_t>(bit_size),
117 byte_size,
118 static_cast<std::size_t>(offset)
119 ));
120 }
121
122 constexpr void update_null_count(bool old_value, bool new_value) noexcept
123 {
124 if (new_value && !old_value)
125 {
126 --m_null_count;
127 }
128 else if (!new_value && old_value)
129 {
130 ++m_null_count;
131 }
132 }
133
134 constexpr void swap_null_count(tracking_null_count& other) noexcept
135 {
136 std::swap(m_null_count, other.m_null_count);
137 }
138
139 constexpr void clear_null_count() noexcept
140 {
141 m_null_count = 0;
142 }
143
144 private:
145
146 size_type m_null_count = 0;
147 };
148
163 template <typename SizeType = std::size_t>
165 {
166 public:
167
168 static constexpr bool track_null_count = false;
169 using size_type = SizeType;
170
171 constexpr non_tracking_null_count() noexcept = default;
172
173 // Accepts and ignores a count for interface compatibility
174 constexpr explicit non_tracking_null_count(size_type /*count*/) noexcept
175 {
176 }
177
178 // null_count() is intentionally not provided
179
180 // No-op: non-tracking policy doesn't need to count bits
181 template <std::integral BlockType>
182 constexpr void initialize_null_count(
183 const BlockType* /*data*/,
184 size_type /*bit_size*/,
185 size_type /*block_count*/,
186 size_type /*offset*/ = 0
187 ) noexcept
188 {
189 }
190
191 constexpr void set_null_count(size_type /*count*/) noexcept
192 {
193 // No-op
194 }
195
196 // No-op: non-tracking policy doesn't need to recompute
197 template <std::integral BlockType>
198 constexpr void recompute_null_count(
199 const BlockType* /*data*/,
200 size_type /*bit_size*/,
201 size_type /*block_count*/,
202 size_type /*offset*/ = 0
203 ) noexcept
204 {
205 }
206
207 constexpr void update_null_count(bool /*old_value*/, bool /*new_value*/) noexcept
208 {
209 // No-op
210 }
211
212 constexpr void swap_null_count(non_tracking_null_count& /*other*/) noexcept
213 {
214 // No-op
215 }
216
217 constexpr void clear_null_count() noexcept
218 {
219 // No-op
220 }
221 };
222
232 template <typename P>
233 concept null_count_policy = requires(P p, P other, bool b, typename P::size_type s, const std::uint8_t* data) {
234 { P::track_null_count } -> std::convertible_to<bool>;
235 { p.update_null_count(b, b) } -> std::same_as<void>;
236 { p.swap_null_count(other) } -> std::same_as<void>;
237 { p.clear_null_count() } -> std::same_as<void>;
238 { p.set_null_count(s) } -> std::same_as<void>;
239 { p.initialize_null_count(data, s, s) } -> std::same_as<void>;
240 { p.recompute_null_count(data, s, s) } -> std::same_as<void>;
241 };
242
243} // namespace sparrow
constexpr void initialize_null_count(const BlockType *, size_type, size_type, size_type=0) noexcept
constexpr void recompute_null_count(const BlockType *, size_type, size_type, size_type=0) noexcept
constexpr void set_null_count(size_type) noexcept
constexpr void clear_null_count() noexcept
constexpr void update_null_count(bool, bool) noexcept
constexpr non_tracking_null_count() noexcept=default
constexpr void swap_null_count(non_tracking_null_count &) noexcept
void initialize_null_count(const BlockType *data, size_type bit_size, size_type block_count, size_type offset=0) noexcept
Initializes the null count by counting bits in the buffer.
constexpr size_type null_count() const noexcept
constexpr void set_null_count(size_type count) noexcept
constexpr void swap_null_count(tracking_null_count &other) noexcept
constexpr tracking_null_count() noexcept=default
void recompute_null_count(const BlockType *data, size_type bit_size, size_type block_count, size_type offset=0) noexcept
Recomputes the null count from the buffer.
constexpr void clear_null_count() noexcept
constexpr void update_null_count(bool old_value, bool new_value) noexcept
static constexpr bool track_null_count
Concept that checks if a type is a valid null count policy.
#define SPARROW_API
Definition config.hpp:38
SPARROW_API std::size_t count_non_null(const std::uint8_t *data, std::size_t bit_size, std::size_t byte_size, std::size_t offset=0) noexcept
Counts the number of bits set to true in a buffer.
Extensions to the C++ standard library.