From 0590eeec211761ceb3e164c0728332d3e19647fa Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Mon, 24 Nov 2025 13:06:45 +0100 Subject: [PATCH 1/2] EXP: [C++][Parquet] Simplify GetVlqInt --- .../arrow/util/bit_stream_utils_internal.h | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/cpp/src/arrow/util/bit_stream_utils_internal.h b/cpp/src/arrow/util/bit_stream_utils_internal.h index d8c7317fe8a3..06ebf78f3367 100644 --- a/cpp/src/arrow/util/bit_stream_utils_internal.h +++ b/cpp/src/arrow/util/bit_stream_utils_internal.h @@ -160,6 +160,10 @@ class BitReader { /// are not enough bits left. bool Advance(int64_t num_bits); + /// Advance the stream by a number of bytes, ignoring remaning bits. + /// Returns true if succeed or false if there are not enough bits left. + bool AdvanceBytes(int64_t num_bytes); + /// Reads a vlq encoded int from the stream. The encoded int must start at /// the beginning of a byte. Return false if there were not enough bytes in /// the buffer. @@ -328,6 +332,17 @@ inline bool BitReader::Advance(int64_t num_bits) { return true; } +inline bool BitReader::AdvanceBytes(int64_t num_bytes) { + if (ARROW_PREDICT_FALSE(num_bytes > max_bytes_ - byte_offset_)) { + return false; + } + byte_offset_ += num_bytes; + bit_offset_ = 0; + buffered_values_ = + detail::ReadLittleEndianWord(buffer_ + byte_offset_, max_bytes_ - byte_offset_); + return true; +} + template inline bool BitWriter::PutVlqInt(Int v) { static_assert(std::is_integral_v); @@ -362,25 +377,10 @@ inline bool BitReader::GetVlqInt(Int* v) { static_assert(std::is_integral_v); // The data that we will pass to the LEB128 parser - // In all case, we read a byte-aligned value, skipping remaining bits - const uint8_t* data = NULLPTR; - int max_size = 0; - - // Number of bytes left in the buffered values, not including the current - // byte (i.e., there may be an additional fraction of a byte). - const int bytes_left_in_cache = - sizeof(buffered_values_) - static_cast(bit_util::BytesForBits(bit_offset_)); - - // If there are clearly enough bytes left we can try to parse from the cache - if (bytes_left_in_cache >= kMaxLEB128ByteLenFor) { - max_size = bytes_left_in_cache; - data = reinterpret_cast(&buffered_values_) + - bit_util::BytesForBits(bit_offset_); - // Otherwise, we try straight from buffer (ignoring few bytes that may be cached) - } else { - max_size = bytes_left(); - data = buffer_ + (max_bytes_ - max_size); - } + // We read a byte-aligned value, skipping remaining bits. + // Also, we don't bother with the cache since the decoding would be the same. + int max_size = bytes_left(); + const uint8_t* data = buffer_ + (max_bytes_ - max_size); const auto bytes_read = bit_util::ParseLeadingLEB128(data, max_size, v); if (ARROW_PREDICT_FALSE(bytes_read == 0)) { @@ -388,8 +388,8 @@ inline bool BitReader::GetVlqInt(Int* v) { return false; } - // Advance for the bytes we have read + the bits we skipped - return Advance((8 * bytes_read) + (bit_offset_ % 8)); + // Advance for the bytes we have read + return AdvanceBytes(bytes_read); } template From f7c9b01ca8fd10980ddaaec2f4d5a2c69a2a9b0a Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Tue, 25 Nov 2025 10:13:41 +0100 Subject: [PATCH 2/2] Fix compilation error --- cpp/src/arrow/util/bit_stream_utils_internal.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cpp/src/arrow/util/bit_stream_utils_internal.h b/cpp/src/arrow/util/bit_stream_utils_internal.h index 06ebf78f3367..376de56a9afc 100644 --- a/cpp/src/arrow/util/bit_stream_utils_internal.h +++ b/cpp/src/arrow/util/bit_stream_utils_internal.h @@ -162,7 +162,7 @@ class BitReader { /// Advance the stream by a number of bytes, ignoring remaning bits. /// Returns true if succeed or false if there are not enough bits left. - bool AdvanceBytes(int64_t num_bytes); + bool AdvanceBytes(int num_bytes); /// Reads a vlq encoded int from the stream. The encoded int must start at /// the beginning of a byte. Return false if there were not enough bytes in @@ -332,7 +332,7 @@ inline bool BitReader::Advance(int64_t num_bits) { return true; } -inline bool BitReader::AdvanceBytes(int64_t num_bytes) { +inline bool BitReader::AdvanceBytes(int num_bytes) { if (ARROW_PREDICT_FALSE(num_bytes > max_bytes_ - byte_offset_)) { return false; }