| 1052 | template <typename T> |
| 1053 | template <typename Converter> |
| 1054 | auto RleBitPackedDecoder<T>::GetSpaced(Converter converter, |
| 1055 | typename Converter::out_type* out, |
| 1056 | rle_size_t batch_size, |
| 1057 | const uint8_t* validity_bits, |
| 1058 | int64_t validity_bits_offset, |
| 1059 | rle_size_t null_count) -> rle_size_t { |
| 1060 | using ControlFlow = RleBitPackedParser::ControlFlow; |
| 1061 | |
| 1062 | ARROW_DCHECK_GT(batch_size, 0); |
| 1063 | |
| 1064 | auto batch = internal::BatchCounter::FromBatchSizeAndNulls(batch_size, null_count); |
| 1065 | |
| 1066 | if (ARROW_PREDICT_FALSE(batch.is_fully_null())) { |
| 1067 | converter.WriteZero(out, out + batch.null_remaining()); |
| 1068 | return batch.null_remaining(); |
| 1069 | } |
| 1070 | |
| 1071 | arrow::internal::BitRunReader validity_reader(validity_bits, validity_bits_offset, |
| 1072 | /*length=*/batch.total_remaining()); |
| 1073 | arrow::internal::BitRun validity_run = validity_reader.NextRun(); |
| 1074 | |
| 1075 | const auto check_and_handle_fully_null_remaining = [&]() { |
| 1076 | if (batch.is_fully_null()) { |
| 1077 | ARROW_DCHECK(validity_run.length == 0 || !validity_run.set); |
| 1078 | ARROW_DCHECK_GE(validity_run.length, batch.null_remaining()); |
| 1079 | |
| 1080 | converter.WriteZero(out, out + batch.null_remaining()); |
| 1081 | out += batch.null_remaining(); |
| 1082 | batch.AccrueReadNulls(batch.null_remaining()); |
| 1083 | } |
| 1084 | }; |
| 1085 | |
| 1086 | // Remaining from a previous call that would have left some unread data from a run. |
| 1087 | if (ARROW_PREDICT_FALSE(run_remaining() > 0)) { |
| 1088 | const auto read = internal::RunGetSpaced(&converter, out, batch.total_remaining(), |
| 1089 | batch.null_remaining(), value_bit_width_, |
| 1090 | &validity_reader, &validity_run, &decoder_); |
| 1091 | |
| 1092 | batch.AccrueReadNulls(read.null_read); |
| 1093 | batch.AccrueReadValues(read.values_read); |
| 1094 | out += read.values_read + read.null_read; |
| 1095 | |
| 1096 | // Either we fulfilled all the batch values to be read |
| 1097 | if (ARROW_PREDICT_FALSE(batch.values_remaining() == 0)) { |
| 1098 | // There may be remaining null if they are not greedily filled |
| 1099 | check_and_handle_fully_null_remaining(); |
| 1100 | return batch.total_read(); |
| 1101 | } |
| 1102 | |
| 1103 | // We finished the remaining run |
| 1104 | ARROW_DCHECK(run_remaining() == 0); |
| 1105 | } |
| 1106 | |
| 1107 | ParseWithCallable([&](auto run) { |
| 1108 | using RunDecoder = typename decltype(run)::template DecoderType<value_type>; |
| 1109 | |
| 1110 | RunDecoder decoder(run, value_bit_width_); |
| 1111 |
nothing calls this directly
no test coverage detected