| 321 | }; |
| 322 | |
| 323 | inline auto RleBitPackedToBitmapDecoder::GetBatch(BitmapSpanMut out, |
| 324 | rle_size_t batch_size) -> rle_size_t { |
| 325 | using ControlFlow = RleBitPackedParser::ControlFlow; |
| 326 | |
| 327 | if (ARROW_PREDICT_FALSE(batch_size == 0 || exhausted())) { |
| 328 | return 0; |
| 329 | } |
| 330 | |
| 331 | rle_size_t values_read = 0; |
| 332 | |
| 333 | // Remaining from a previous call that would have left some unread data from a run. |
| 334 | if (ARROW_PREDICT_FALSE(run_remaining() > 0)) { |
| 335 | const auto read = RunGetBatch(out, batch_size); |
| 336 | values_read += read; |
| 337 | |
| 338 | // Either we fulfilled all the batch to be read or we finished remaining run. |
| 339 | if (ARROW_PREDICT_FALSE(values_read == batch_size)) { |
| 340 | return values_read; |
| 341 | } |
| 342 | ARROW_DCHECK(run_remaining() == 0); |
| 343 | } |
| 344 | |
| 345 | parser_.ParseWithCallable([&](auto run) { |
| 346 | using RunDecoder = RleBitPackedToBitmapDecoderGetDecoder<decltype(run)>::type; |
| 347 | |
| 348 | ARROW_DCHECK_LT(values_read, batch_size); |
| 349 | RunDecoder decoder(run); |
| 350 | // The output span carries its own bit offset, so advancing it past the values |
| 351 | // already written keeps successive runs correctly aligned in the bitmap. |
| 352 | const auto read = |
| 353 | decoder.GetBatch(out.NewStartingAt(values_read), batch_size - values_read); |
| 354 | ARROW_DCHECK_LE(read, batch_size - values_read); |
| 355 | values_read += read; |
| 356 | |
| 357 | // Stop reading and store remaining decoder |
| 358 | if (ARROW_PREDICT_FALSE(values_read == batch_size || read == 0)) { |
| 359 | decoder_ = std::move(decoder); |
| 360 | return ControlFlow::Break; |
| 361 | } |
| 362 | |
| 363 | return ControlFlow::Continue; |
| 364 | }); |
| 365 | |
| 366 | return values_read; |
| 367 | } |
| 368 | |
| 369 | } // namespace arrow::util |