| 1267 | template <typename T> |
| 1268 | template <typename V> |
| 1269 | auto RleBitPackedDecoder<T>::GetBatchWithDict(const V* dictionary, |
| 1270 | int32_t dictionary_length, V* out, |
| 1271 | rle_size_t batch_size) -> rle_size_t { |
| 1272 | using ControlFlow = RleBitPackedParser::ControlFlow; |
| 1273 | |
| 1274 | if (ARROW_PREDICT_FALSE(batch_size <= 0 || dictionary_length == 0)) { |
| 1275 | // Either empty batch or invalid dictionary |
| 1276 | return 0; |
| 1277 | } |
| 1278 | |
| 1279 | internal::DictionaryConverter<V, value_type> converter{dictionary, dictionary_length}; |
| 1280 | |
| 1281 | // Make lightweight BitRun class to reuse previous methods. |
| 1282 | constexpr internal::UnreachableBitRunReader validity_reader{}; |
| 1283 | internal::AllSetBitRun validity_run = {batch_size}; |
| 1284 | |
| 1285 | rle_size_t values_read = 0; |
| 1286 | auto batch_values_remaining = [&]() { |
| 1287 | ARROW_DCHECK_LE(values_read, batch_size); |
| 1288 | return batch_size - values_read; |
| 1289 | }; |
| 1290 | |
| 1291 | if (ARROW_PREDICT_FALSE(run_remaining() > 0)) { |
| 1292 | const auto read = internal::RunGetSpaced(&converter, out, batch_size, |
| 1293 | /* null_count= */ 0, value_bit_width_, |
| 1294 | &validity_reader, &validity_run, &decoder_); |
| 1295 | |
| 1296 | ARROW_DCHECK_EQ(read.null_read, 0); |
| 1297 | values_read += read.values_read; |
| 1298 | out += read.values_read; |
| 1299 | |
| 1300 | // Either we fulfilled all the batch values to be read |
| 1301 | if (ARROW_PREDICT_FALSE(values_read >= batch_size)) { |
| 1302 | // There may be remaining null if they are not greedily filled |
| 1303 | return values_read; |
| 1304 | } |
| 1305 | |
| 1306 | // We finished the remaining run |
| 1307 | ARROW_DCHECK(run_remaining() == 0); |
| 1308 | } |
| 1309 | |
| 1310 | parser_.ParseWithCallable([&](auto run) { |
| 1311 | using RunDecoder = |
| 1312 | typename RleBitPackedDecoderGetRunDecoder<value_type, decltype(run)>::type; |
| 1313 | |
| 1314 | RunDecoder decoder(run, value_bit_width_); |
| 1315 | |
| 1316 | const auto read = internal::RunGetSpaced(&converter, out, batch_values_remaining(), |
| 1317 | /* null_count= */ 0, value_bit_width_, |
| 1318 | &validity_reader, &validity_run, &decoder); |
| 1319 | |
| 1320 | ARROW_DCHECK_EQ(read.null_read, 0); |
| 1321 | values_read += read.values_read; |
| 1322 | out += read.values_read; |
| 1323 | |
| 1324 | // Stop reading and store remaining decoder |
| 1325 | if (ARROW_PREDICT_FALSE(read.values_read == 0 || values_read == batch_size)) { |
| 1326 | decoder_ = std::move(decoder); |