| 515 | |
| 516 | template <typename T> |
| 517 | ALWAYS_INLINE inline bool DictDecoder<T>::GetNextValues( |
| 518 | T* first_value, int64_t stride, int count) { |
| 519 | DCHECK_GE(count, 0); |
| 520 | StrideWriter<T> out(first_value, stride); |
| 521 | if (num_repeats_ > 0) { |
| 522 | // Consume any already-decoded repeated value. |
| 523 | int num_to_copy = std::min<uint32_t>(num_repeats_, count); |
| 524 | T repeated_val = decoded_values_[0]; |
| 525 | out.SetNext(repeated_val, num_to_copy); |
| 526 | count -= num_to_copy; |
| 527 | num_repeats_ -= num_to_copy; |
| 528 | } else if (next_literal_idx_ < num_literal_values_) { |
| 529 | // Consume any already-decoded literal values. |
| 530 | count -= CopyLiteralsToOutput(count, &out); |
| 531 | } |
| 532 | DCHECK_GE(count, 0); |
| 533 | while (count > 0) { |
| 534 | uint32_t num_repeats = data_decoder_.NextNumRepeats(); |
| 535 | if (num_repeats > 0) { |
| 536 | // Decode repeats directly to the output. |
| 537 | uint32_t num_repeats_to_consume = std::min<uint32_t>(num_repeats, count); |
| 538 | const IndexType idx = data_decoder_.GetRepeatedValue(num_repeats_to_consume); |
| 539 | if (UNLIKELY(idx >= dict_.size())) return false; |
| 540 | T repeated_val = dict_[idx]; |
| 541 | out.SetNext(repeated_val, num_repeats_to_consume); |
| 542 | count -= num_repeats_to_consume; |
| 543 | } else { |
| 544 | // Decode as many literals as possible directly to the output, buffer the rest. |
| 545 | uint32_t num_literals = data_decoder_.NextNumLiterals(); |
| 546 | if (UNLIKELY(num_literals == 0)) return false; |
| 547 | // Case 1: decode the whole literal run directly to the output. |
| 548 | // Case 2: decode none or some of the run to the output, buffer some remaining. |
| 549 | if (count >= num_literals) { // Case 1 |
| 550 | if (UNLIKELY(!data_decoder_.DecodeLiteralValues( |
| 551 | num_literals, dict_.data(), dict_.size(), &out))) { |
| 552 | return false; |
| 553 | } |
| 554 | count -= num_literals; |
| 555 | } else { // Case 2 |
| 556 | uint32_t num_to_decode = BitUtil::RoundDown(count, 32); |
| 557 | if (num_to_decode > 0 && UNLIKELY(!data_decoder_.DecodeLiteralValues( |
| 558 | num_to_decode, dict_.data(), dict_.size(), &out))) { |
| 559 | return false; |
| 560 | } |
| 561 | count -= num_to_decode; |
| 562 | DCHECK_GE(count, 0); |
| 563 | if (count > 0) { |
| 564 | if (UNLIKELY(!DecodeNextValue(out.Advance()))) return false; |
| 565 | --count; |
| 566 | // Consume any already-decoded literal values. |
| 567 | count -= CopyLiteralsToOutput(count, &out); |
| 568 | } |
| 569 | return true; |
| 570 | } |
| 571 | } |
| 572 | } |
| 573 | return true; |
| 574 | } |