sparrow 2.0.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{
33 [[nodiscard]] SPARROW_API std::size_t
34 count_non_null(const std::uint8_t* data, std::size_t bit_size, std::size_t byte_size) noexcept;
35
50 template <typename SizeType = std::size_t>
52 {
53 public:
54
55 static constexpr bool track_null_count = true;
56 using size_type = SizeType;
57
58 constexpr tracking_null_count() noexcept = default;
59
60 constexpr explicit tracking_null_count(size_type count) noexcept
61 : m_null_count(count)
62 {
63 }
64
72 template <std::integral BlockType>
73 void initialize_null_count(const BlockType* data, size_type bit_size, size_type block_count) noexcept
74 {
75 recompute_null_count(data, bit_size, block_count);
76 }
77
78 [[nodiscard]] constexpr size_type null_count() const noexcept
79 {
80 return m_null_count;
81 }
82
83 constexpr void set_null_count(size_type count) noexcept
84 {
85 m_null_count = count;
86 }
87
95 template <std::integral BlockType>
96 void recompute_null_count(const BlockType* data, size_type bit_size, size_type block_count) noexcept
97 {
98 const auto* byte_data = reinterpret_cast<const std::uint8_t*>(data);
99 const std::size_t byte_size = block_count * sizeof(BlockType);
100 m_null_count = static_cast<size_type>(bit_size)
101 - static_cast<size_type>(
102 count_non_null(byte_data, static_cast<std::size_t>(bit_size), byte_size)
103 );
104 }
105
106 constexpr void update_null_count(bool old_value, bool new_value) noexcept
107 {
108 if (new_value && !old_value)
109 {
110 --m_null_count;
111 }
112 else if (!new_value && old_value)
113 {
114 ++m_null_count;
115 }
116 }
117
118 constexpr void swap_null_count(tracking_null_count& other) noexcept
119 {
120 std::swap(m_null_count, other.m_null_count);
121 }
122
123 constexpr void clear_null_count() noexcept
124 {
125 m_null_count = 0;
126 }
127
128 private:
129
130 size_type m_null_count = 0;
131 };
132
147 template <typename SizeType = std::size_t>
149 {
150 public:
151
152 static constexpr bool track_null_count = false;
153 using size_type = SizeType;
154
155 constexpr non_tracking_null_count() noexcept = default;
156
157 // Accepts and ignores a count for interface compatibility
158 constexpr explicit non_tracking_null_count(size_type /*count*/) noexcept
159 {
160 }
161
162 // null_count() is intentionally not provided
163
164 // No-op: non-tracking policy doesn't need to count bits
165 template <std::integral BlockType>
166 constexpr void
167 initialize_null_count(const BlockType* /*data*/, size_type /*bit_size*/, size_type /*block_count*/) noexcept
168 {
169 }
170
171 constexpr void set_null_count(size_type /*count*/) noexcept
172 {
173 // No-op
174 }
175
176 // No-op: non-tracking policy doesn't need to recompute
177 template <std::integral BlockType>
178 constexpr void
179 recompute_null_count(const BlockType* /*data*/, size_type /*bit_size*/, size_type /*block_count*/) noexcept
180 {
181 }
182
183 constexpr void update_null_count(bool /*old_value*/, bool /*new_value*/) noexcept
184 {
185 // No-op
186 }
187
188 constexpr void swap_null_count(non_tracking_null_count& /*other*/) noexcept
189 {
190 // No-op
191 }
192
193 constexpr void clear_null_count() noexcept
194 {
195 // No-op
196 }
197 };
198
208 template <typename P>
209 concept null_count_policy = requires(P p, P other, bool b, typename P::size_type s, const std::uint8_t* data) {
210 { P::track_null_count } -> std::convertible_to<bool>;
211 { p.update_null_count(b, b) } -> std::same_as<void>;
212 { p.swap_null_count(other) } -> std::same_as<void>;
213 { p.clear_null_count() } -> std::same_as<void>;
214 { p.set_null_count(s) } -> std::same_as<void>;
215 { p.initialize_null_count(data, s, s) } -> std::same_as<void>;
216 { p.recompute_null_count(data, s, s) } -> std::same_as<void>;
217 };
218
219} // namespace sparrow
constexpr void recompute_null_count(const BlockType *, size_type, size_type) noexcept
constexpr void set_null_count(size_type) noexcept
constexpr void clear_null_count() noexcept
constexpr void initialize_null_count(const BlockType *, size_type, size_type) 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
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) noexcept
Recomputes the null count from the buffer.
constexpr void clear_null_count() noexcept
void initialize_null_count(const BlockType *data, size_type bit_size, size_type block_count) noexcept
Initializes the null count by counting bits in the buffer.
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) noexcept
Counts the number of bits set to true in a buffer.