| 604 | template <typename T> |
| 605 | template <typename OutType> |
| 606 | inline bool RleBatchDecoder<T>::DecodeLiteralValues(int32_t num_literals_to_consume, |
| 607 | OutType* dict, int64_t dict_len, StrideWriter<OutType>* RESTRICT out) { |
| 608 | DCHECK_GT(num_literals_to_consume, 0); |
| 609 | DCHECK_GE(literal_count_, num_literals_to_consume); |
| 610 | |
| 611 | if (num_literals_to_consume == 0) return false; |
| 612 | |
| 613 | int32_t num_remaining = num_literals_to_consume; |
| 614 | // Decode any buffered literals left over from previous calls. |
| 615 | if (HaveBufferedLiterals()) { |
| 616 | int32_t num_consumed = DecodeBufferedLiterals(num_remaining, dict, dict_len, out); |
| 617 | if (UNLIKELY(num_consumed == 0)) return false; |
| 618 | DCHECK_LE(num_consumed, num_remaining); |
| 619 | num_remaining -= num_consumed; |
| 620 | } |
| 621 | |
| 622 | // Copy literals directly to the output, bypassing 'literal_buffer_' when possible. |
| 623 | // Need to round to a batch of 32 if the caller is consuming only part of the current |
| 624 | // run avoid ending on a non-byte boundery. |
| 625 | int32_t num_to_bypass = |
| 626 | std::min<int32_t>(literal_count_, BitUtil::RoundDownToPowerOf2(num_remaining, 32)); |
| 627 | if (num_to_bypass > 0) { |
| 628 | int num_read = bit_reader_.UnpackAndDecodeBatch( |
| 629 | bit_width_, dict, dict_len, num_to_bypass, out->current, out->stride); |
| 630 | // If we couldn't read the expected number, that means the input was truncated. |
| 631 | if (num_read < num_to_bypass) return false; |
| 632 | DCHECK_EQ(num_read, num_to_bypass); |
| 633 | literal_count_ -= num_to_bypass; |
| 634 | out->SkipNext(num_to_bypass); |
| 635 | num_remaining -= num_to_bypass; |
| 636 | } |
| 637 | |
| 638 | if (num_remaining > 0) { |
| 639 | // We weren't able to copy all the literals requested directly from the input. |
| 640 | // Buffer literals and copy over the requested number. |
| 641 | if (UNLIKELY(!FillLiteralBuffer())) return false; |
| 642 | int32_t num_copied = DecodeBufferedLiterals(num_remaining, dict, dict_len, out); |
| 643 | if (UNLIKELY(num_copied == 0)) return false; |
| 644 | DCHECK_EQ(num_copied, num_remaining) << "Should have buffered enough literals"; |
| 645 | } |
| 646 | return true; |
| 647 | } |
| 648 | |
| 649 | template <typename T> |
| 650 | inline bool RleBatchDecoder<T>::GetSingleValue(T* val) { |
no test coverage detected