| 172 | }; |
| 173 | |
| 174 | Status Consume(const ExecSpan& batch) override { |
| 175 | auto* counts = counts_.mutable_data_as<int64_t>(); |
| 176 | auto* g_begin = batch[1].array.GetValues<uint32_t>(1); |
| 177 | |
| 178 | if (options_.mode == CountOptions::ALL) { |
| 179 | for (int64_t i = 0; i < batch.length; ++i, ++g_begin) { |
| 180 | counts[*g_begin] += 1; |
| 181 | } |
| 182 | } else if (batch[0].is_array()) { |
| 183 | const ArraySpan& input = batch[0].array; |
| 184 | if (options_.mode == CountOptions::ONLY_VALID) { // ONLY_VALID |
| 185 | if (input.type->id() != arrow::Type::NA) { |
| 186 | const uint8_t* bitmap = input.buffers[0].data; |
| 187 | if (bitmap) { |
| 188 | arrow::internal::VisitSetBitRunsVoid( |
| 189 | bitmap, input.offset, input.length, [&](int64_t offset, int64_t length) { |
| 190 | auto g = g_begin + offset; |
| 191 | for (int64_t i = 0; i < length; ++i, ++g) { |
| 192 | counts[*g] += 1; |
| 193 | } |
| 194 | }); |
| 195 | } else { |
| 196 | // Array without validity bitmaps require special handling of nulls. |
| 197 | const bool all_valid = !input.MayHaveLogicalNulls(); |
| 198 | if (all_valid) { |
| 199 | for (int64_t i = 0; i < input.length; ++i, ++g_begin) { |
| 200 | counts[*g_begin] += 1; |
| 201 | } |
| 202 | } else { |
| 203 | switch (input.type->id()) { |
| 204 | case Type::RUN_END_ENCODED: |
| 205 | RunEndEncodedCountImpl<true>{}(input, counts, g_begin); |
| 206 | break; |
| 207 | default: // Generic and forward-compatible version. |
| 208 | for (int64_t i = 0; i < input.length; ++i, ++g_begin) { |
| 209 | counts[*g_begin] += input.IsValid(i); |
| 210 | } |
| 211 | break; |
| 212 | } |
| 213 | } |
| 214 | } |
| 215 | } |
| 216 | } else { // ONLY_NULL |
| 217 | if (input.type->id() == arrow::Type::NA) { |
| 218 | for (int64_t i = 0; i < batch.length; ++i, ++g_begin) { |
| 219 | counts[*g_begin] += 1; |
| 220 | } |
| 221 | } else if (input.MayHaveLogicalNulls()) { |
| 222 | if (input.HasValidityBitmap()) { |
| 223 | auto end = input.offset + input.length; |
| 224 | for (int64_t i = input.offset; i < end; ++i, ++g_begin) { |
| 225 | counts[*g_begin] += !bit_util::GetBit(input.buffers[0].data, i); |
| 226 | } |
| 227 | } else { |
| 228 | // Arrays without validity bitmaps require special handling of nulls. |
| 229 | switch (input.type->id()) { |
| 230 | case Type::RUN_END_ENCODED: |
| 231 | RunEndEncodedCountImpl<false>{}(input, counts, g_begin); |