| 1246 | template <typename T> |
| 1247 | template <typename V> |
| 1248 | auto RleBitPackedDecoder<T>::GetBatchWithDict(const V* dictionary, |
| 1249 | int32_t dictionary_length, V* out, |
| 1250 | rle_size_t batch_size) -> rle_size_t { |
| 1251 | using ControlFlow = RleBitPackedParser::ControlFlow; |
| 1252 | |
| 1253 | if (ARROW_PREDICT_FALSE(batch_size <= 0 || dictionary_length == 0)) { |
| 1254 | // Either empty batch or invalid dictionary |
| 1255 | return 0; |
| 1256 | } |
| 1257 | |
| 1258 | internal::DictionaryConverter<V, value_type> converter{dictionary, dictionary_length}; |
| 1259 | |
| 1260 | // Make lightweight BitRun class to reuse previous methods. |
| 1261 | constexpr internal::UnreachableBitRunReader validity_reader{}; |
| 1262 | internal::AllSetBitRun validity_run = {batch_size}; |
| 1263 | |
| 1264 | rle_size_t values_read = 0; |
| 1265 | auto batch_values_remaining = [&]() { |
| 1266 | ARROW_DCHECK_LE(values_read, batch_size); |
| 1267 | return batch_size - values_read; |
| 1268 | }; |
| 1269 | |
| 1270 | if (ARROW_PREDICT_FALSE(run_remaining() > 0)) { |
| 1271 | const auto read = internal::RunGetSpaced(&converter, out, batch_size, |
| 1272 | /* null_count= */ 0, value_bit_width_, |
| 1273 | &validity_reader, &validity_run, &decoder_); |
| 1274 | |
| 1275 | ARROW_DCHECK_EQ(read.null_read, 0); |
| 1276 | values_read += read.values_read; |
| 1277 | out += read.values_read; |
| 1278 | |
| 1279 | // Either we fulfilled all the batch values to be read |
| 1280 | if (ARROW_PREDICT_FALSE(values_read >= batch_size)) { |
| 1281 | // There may be remaining null if they are not greedily filled |
| 1282 | return values_read; |
| 1283 | } |
| 1284 | |
| 1285 | // We finished the remaining run |
| 1286 | ARROW_DCHECK(run_remaining() == 0); |
| 1287 | } |
| 1288 | |
| 1289 | ParseWithCallable([&](auto run) { |
| 1290 | using RunDecoder = typename decltype(run)::template DecoderType<value_type>; |
| 1291 | |
| 1292 | RunDecoder decoder(run, value_bit_width_); |
| 1293 | |
| 1294 | const auto read = internal::RunGetSpaced(&converter, out, batch_values_remaining(), |
| 1295 | /* null_count= */ 0, value_bit_width_, |
| 1296 | &validity_reader, &validity_run, &decoder); |
| 1297 | |
| 1298 | ARROW_DCHECK_EQ(read.null_read, 0); |
| 1299 | values_read += read.values_read; |
| 1300 | out += read.values_read; |
| 1301 | |
| 1302 | // Stop reading and store remaining decoder |
| 1303 | if (ARROW_PREDICT_FALSE(read.values_read == 0 || values_read == batch_size)) { |
| 1304 | decoder_ = std::move(decoder); |
| 1305 | return ControlFlow::Break; |