MCPcopy Create free account
hub / github.com/apache/arrow / IntegersInRange

Function IntegersInRange

cpp/src/arrow/util/int_util.cc:595–670  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

593
594template <typename InType, typename CType = typename InType::c_type>
595Status IntegersInRange(const ArraySpan& values, CType bound_lower, CType bound_upper) {
596 if (std::numeric_limits<CType>::lowest() >= bound_lower &&
597 std::numeric_limits<CType>::max() <= bound_upper) {
598 return Status::OK();
599 }
600
601 auto IsOutOfBounds = [&](CType val) -> bool {
602 return val < bound_lower || val > bound_upper;
603 };
604 auto IsOutOfBoundsMaybeNull = [&](CType val, bool is_valid) -> bool {
605 return is_valid && (val < bound_lower || val > bound_upper);
606 };
607 auto GetErrorMessage = [&](CType val) {
608 return Status::Invalid("Integer value ", ToChars(val),
609 " not in range: ", ToChars(bound_lower), " to ",
610 ToChars(bound_upper));
611 };
612
613 const CType* values_data = values.GetValues<CType>(1);
614 const uint8_t* bitmap = values.buffers[0].data;
615 OptionalBitBlockCounter values_bit_counter(bitmap, values.offset, values.length);
616 int64_t position = 0;
617 int64_t offset_position = values.offset;
618 while (position < values.length) {
619 BitBlockCount block = values_bit_counter.NextBlock();
620 bool block_out_of_bounds = false;
621 if (block.popcount == block.length) {
622 // Fast path: branchless
623 int64_t i = 0;
624 for (int64_t chunk = 0; chunk < block.length / 8; ++chunk) {
625 // Let the compiler unroll this
626 for (int j = 0; j < 8; ++j) {
627 block_out_of_bounds |= IsOutOfBounds(values_data[i++]);
628 }
629 }
630 for (; i < block.length; ++i) {
631 block_out_of_bounds |= IsOutOfBounds(values_data[i]);
632 }
633 } else if (block.popcount > 0) {
634 // Values have nulls, must only boundscheck non-null values
635 int64_t i = 0;
636 for (int64_t chunk = 0; chunk < block.length / 8; ++chunk) {
637 // Let the compiler unroll this
638 for (int j = 0; j < 8; ++j) {
639 block_out_of_bounds |= IsOutOfBoundsMaybeNull(
640 values_data[i], bit_util::GetBit(bitmap, offset_position + i));
641 ++i;
642 }
643 }
644 for (; i < block.length; ++i) {
645 block_out_of_bounds |= IsOutOfBoundsMaybeNull(
646 values_data[i], bit_util::GetBit(bitmap, offset_position + i));
647 }
648 }
649 if (ARROW_PREDICT_FALSE(block_out_of_bounds)) {
650 if (values.GetNullCount() > 0) {
651 for (int64_t i = 0; i < block.length; ++i) {
652 if (IsOutOfBoundsMaybeNull(values_data[i],

Callers

nothing calls this directly

Calls 6

ToCharsFunction · 0.85
NextBlockMethod · 0.80
GetNullCountMethod · 0.80
GetBitFunction · 0.70
OKFunction · 0.50
InvalidFunction · 0.50

Tested by

no test coverage detected