| 1072 | template <typename T> |
| 1073 | template <typename Converter> |
| 1074 | auto RleBitPackedDecoder<T>::GetSpaced(Converter converter, |
| 1075 | typename Converter::out_type* out, |
| 1076 | rle_size_t batch_size, |
| 1077 | const uint8_t* validity_bits, |
| 1078 | int64_t validity_bits_offset, |
| 1079 | rle_size_t null_count) -> rle_size_t { |
| 1080 | using ControlFlow = RleBitPackedParser::ControlFlow; |
| 1081 | |
| 1082 | ARROW_DCHECK_GT(batch_size, 0); |
| 1083 | |
| 1084 | auto batch = internal::BatchCounter::FromBatchSizeAndNulls(batch_size, null_count); |
| 1085 | |
| 1086 | if (ARROW_PREDICT_FALSE(batch.is_fully_null())) { |
| 1087 | converter.WriteZero(out, out + batch.null_remaining()); |
| 1088 | return batch.null_remaining(); |
| 1089 | } |
| 1090 | |
| 1091 | arrow::internal::BitRunReader validity_reader(validity_bits, validity_bits_offset, |
| 1092 | /*length=*/batch.total_remaining()); |
| 1093 | arrow::internal::BitRun validity_run = validity_reader.NextRun(); |
| 1094 | |
| 1095 | const auto check_and_handle_fully_null_remaining = [&]() { |
| 1096 | if (batch.is_fully_null()) { |
| 1097 | ARROW_DCHECK(validity_run.length == 0 || !validity_run.set); |
| 1098 | ARROW_DCHECK_GE(validity_run.length, batch.null_remaining()); |
| 1099 | |
| 1100 | converter.WriteZero(out, out + batch.null_remaining()); |
| 1101 | out += batch.null_remaining(); |
| 1102 | batch.AccrueReadNulls(batch.null_remaining()); |
| 1103 | } |
| 1104 | }; |
| 1105 | |
| 1106 | // Remaining from a previous call that would have left some unread data from a run. |
| 1107 | if (ARROW_PREDICT_FALSE(run_remaining() > 0)) { |
| 1108 | const auto read = internal::RunGetSpaced(&converter, out, batch.total_remaining(), |
| 1109 | batch.null_remaining(), value_bit_width_, |
| 1110 | &validity_reader, &validity_run, &decoder_); |
| 1111 | |
| 1112 | batch.AccrueReadNulls(read.null_read); |
| 1113 | batch.AccrueReadValues(read.values_read); |
| 1114 | out += read.values_read + read.null_read; |
| 1115 | |
| 1116 | // Either we fulfilled all the batch values to be read |
| 1117 | if (ARROW_PREDICT_FALSE(batch.values_remaining() == 0)) { |
| 1118 | // There may be remaining null if they are not greedily filled |
| 1119 | check_and_handle_fully_null_remaining(); |
| 1120 | return batch.total_read(); |
| 1121 | } |
| 1122 | |
| 1123 | // We finished the remaining run |
| 1124 | ARROW_DCHECK(run_remaining() == 0); |
| 1125 | } |
| 1126 | |
| 1127 | parser_.ParseWithCallable([&](auto run) { |
| 1128 | using RunDecoder = |
| 1129 | typename RleBitPackedDecoderGetRunDecoder<value_type, decltype(run)>::type; |
| 1130 | |
| 1131 | RunDecoder decoder(run, value_bit_width_); |
nothing calls this directly
no test coverage detected