| 249 | using ArrayType = typename CTypeTraits<T>::ArrayType; |
| 250 | |
| 251 | static void Sum(const ArrayType& array, SumState<T>* state) { |
| 252 | SumState<T> local; |
| 253 | |
| 254 | const auto values = array.raw_values(); |
| 255 | const auto bitmap = array.null_bitmap_data(); |
| 256 | const auto length = array.length(); |
| 257 | const int64_t length_rounded = bit_util::RoundDown(length, 8); |
| 258 | for (int64_t i = 0; i < length_rounded; i += 8) { |
| 259 | const uint8_t valid_byte = bitmap[i / 8]; |
| 260 | |
| 261 | # define SUM_SHIFT(ITEM) (values[i + ITEM] * ((valid_byte >> ITEM) & 1)) |
| 262 | |
| 263 | if (valid_byte < 0xFF) { |
| 264 | // Some nulls |
| 265 | local.total += SUM_SHIFT(0); |
| 266 | local.total += SUM_SHIFT(1); |
| 267 | local.total += SUM_SHIFT(2); |
| 268 | local.total += SUM_SHIFT(3); |
| 269 | local.total += SUM_SHIFT(4); |
| 270 | local.total += SUM_SHIFT(5); |
| 271 | local.total += SUM_SHIFT(6); |
| 272 | local.total += SUM_SHIFT(7); |
| 273 | local.valid_count += std::popcount(valid_byte); |
| 274 | } else { |
| 275 | // No nulls |
| 276 | local.total += values[i + 0] + values[i + 1] + values[i + 2] + values[i + 3] + |
| 277 | values[i + 4] + values[i + 5] + values[i + 6] + values[i + 7]; |
| 278 | local.valid_count += 8; |
| 279 | } |
| 280 | } |
| 281 | |
| 282 | # undef SUM_SHIFT |
| 283 | |
| 284 | for (int64_t i = length_rounded; i < length; ++i) { |
| 285 | if (bit_util::GetBit(bitmap, i)) { |
| 286 | local.total = values[i]; |
| 287 | ++local.valid_count; |
| 288 | } |
| 289 | } |
| 290 | |
| 291 | *state = local; |
| 292 | } |
| 293 | }; |
| 294 | |
| 295 | template <typename Functor> |
nothing calls this directly
no test coverage detected