Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 32 additions & 13 deletions be/src/util/rle_encoding.h
Original file line number Diff line number Diff line change
Expand Up @@ -435,17 +435,35 @@ template <typename T>
void RleEncoder<T>::Put(T value, size_t run_length) {
DCHECK(bit_width_ == 64 || value < (1LL << bit_width_));

// TODO(perf): remove the loop and use the repeat_count_
for (; run_length > 0; run_length--) {
// Fast path: if this is a continuation of the current repeated run and
// we've already buffered enough values, just increment repeat_count_
if (current_value_ == value && repeat_count_ >= 8 && run_length > 0) [[likely]] {
repeat_count_ += run_length;
return;
}

// Handle run_length > 1 more efficiently
while (run_length > 0) {
if (current_value_ == value) [[likely]] {
++repeat_count_;
if (repeat_count_ > 8) {
// This is just a continuation of the current run, no need to buffer the
// values.
// Note that this is the fast path for long repeated runs.
continue;
// Need to buffer values until we reach 8
size_t to_buffer = std::min(run_length, size_t(8 - num_buffered_values_));
for (size_t i = 0; i < to_buffer; ++i) {
buffered_values_[num_buffered_values_++] = value;
++repeat_count_;
}
run_length -= to_buffer;
if (num_buffered_values_ == 8) {
DCHECK_EQ(literal_count_ % 8, 0);
FlushBufferedValues(false);
// After flushing, if we still have a repeated run and more values,
// we can add them directly to repeat_count_
if (repeat_count_ >= 8 && run_length > 0) {
repeat_count_ += run_length;
return;
}
}
} else {
// Value changed
if (repeat_count_ >= 8) {
// We had a run that was long enough but it has ended. Flush the
// current repeated run.
Expand All @@ -454,12 +472,13 @@ void RleEncoder<T>::Put(T value, size_t run_length) {
}
repeat_count_ = 1;
current_value_ = value;
}

buffered_values_[num_buffered_values_] = value;
if (++num_buffered_values_ == 8) {
DCHECK_EQ(literal_count_ % 8, 0);
FlushBufferedValues(false);
buffered_values_[num_buffered_values_++] = value;
--run_length;
if (num_buffered_values_ == 8) {
DCHECK_EQ(literal_count_ % 8, 0);
FlushBufferedValues(false);
}
}
}
}
Expand Down
Loading
Loading