blob: c67cedc4a06419c8735b1b15db0695092dc0e5f1 [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#include "arrow/util/bit_block_counter.h"
#include <algorithm>
#include <cstdint>
#include <type_traits>
#include "arrow/buffer.h"
#include "arrow/util/bitmap_ops.h"
namespace arrow {
namespace internal {
BitBlockCount BitBlockCounter::GetBlockSlow(int64_t block_size) noexcept {
const int16_t run_length = static_cast<int16_t>(std::min(bits_remaining_, block_size));
int16_t popcount = static_cast<int16_t>(CountSetBits(bitmap_, offset_, run_length));
bits_remaining_ -= run_length;
// This code path should trigger _at most_ 2 times. In the "two times"
// case, the first time the run length will be a multiple of 8 by construction
bitmap_ += run_length / 8;
return {run_length, popcount};
}
// Prevent pointer arithmetic on nullptr, which is undefined behavior even if the pointer
// is never dereferenced.
inline const uint8_t* EnsureNotNull(const uint8_t* ptr) {
static const uint8_t byte{};
return ptr == nullptr ? &byte : ptr;
}
OptionalBitBlockCounter::OptionalBitBlockCounter(const uint8_t* validity_bitmap,
int64_t offset, int64_t length)
: has_bitmap_(validity_bitmap != nullptr),
position_(0),
length_(length),
counter_(EnsureNotNull(validity_bitmap), offset, length) {}
OptionalBitBlockCounter::OptionalBitBlockCounter(
const std::shared_ptr<Buffer>& validity_bitmap, int64_t offset, int64_t length)
: OptionalBitBlockCounter(validity_bitmap ? validity_bitmap->data() : nullptr, offset,
length) {}
OptionalBinaryBitBlockCounter::OptionalBinaryBitBlockCounter(const uint8_t* left_bitmap,
int64_t left_offset,
const uint8_t* right_bitmap,
int64_t right_offset,
int64_t length)
: has_bitmap_(HasBitmapFromBitmaps(left_bitmap != nullptr, right_bitmap != nullptr)),
position_(0),
length_(length),
unary_counter_(EnsureNotNull(left_bitmap != nullptr ? left_bitmap : right_bitmap),
left_bitmap != nullptr ? left_offset : right_offset, length),
binary_counter_(EnsureNotNull(left_bitmap), left_offset,
EnsureNotNull(right_bitmap), right_offset, length) {}
OptionalBinaryBitBlockCounter::OptionalBinaryBitBlockCounter(
const std::shared_ptr<Buffer>& left_bitmap, int64_t left_offset,
const std::shared_ptr<Buffer>& right_bitmap, int64_t right_offset, int64_t length)
: OptionalBinaryBitBlockCounter(
left_bitmap ? left_bitmap->data() : nullptr, left_offset,
right_bitmap ? right_bitmap->data() : nullptr, right_offset, length) {}
} // namespace internal
} // namespace arrow