Skip to content

Commit

Permalink
Compare 4 bytes when checking if a longer match is possible.
Browse files Browse the repository at this point in the history
Loading and comparing 4 bytes is ~as fast as 1 byte, but allows us to avoid more full match length calculation.

PiperOrigin-RevId: 617556847
  • Loading branch information
Brotli authored and Copybara-Service committed Mar 20, 2024
1 parent 9717649 commit 9351fa7
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 6 deletions.
12 changes: 9 additions & 3 deletions c/enc/hash.h
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,11 @@ static BROTLI_INLINE void FindCompoundDictionaryMatch(
}
}
}
/* we require matches of len >4, so increase best_len to 3, so we can compare
* 4 bytes all the time. */
if (best_len < 3) {
best_len = 3;
}
while (item == 0) {
size_t offset;
size_t distance;
Expand All @@ -586,9 +591,10 @@ static BROTLI_INLINE void FindCompoundDictionaryMatch(
limit = source_size - offset;
limit = (limit > max_length) ? max_length : limit;
if (distance > max_distance) continue;
if (cur_ix_masked + best_len > ring_buffer_mask ||
best_len >= limit ||
data[cur_ix_masked + best_len] != source[offset + best_len]) {
if (cur_ix_masked + best_len > ring_buffer_mask || best_len >= limit ||
/* compare 4 bytes ending at best_len + 1 */
BrotliUnalignedRead32(&data[cur_ix_masked + best_len - 3]) !=
BrotliUnalignedRead32(&source[offset + best_len - 3])) {
continue;
}
{
Expand Down
9 changes: 8 additions & 1 deletion c/enc/hash_forgetful_chain_inc.h
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,11 @@ static BROTLI_INLINE void FN(FindLongestMatch)(
}
}
}
/* we require matches of len >4, so increase best_len to 3, so we can compare
* 4 bytes all the time. */
if (best_len < 3) {
best_len = 3;
}
{
const size_t bank = key & (NUM_BANKS - 1);
size_t backward = 0;
Expand All @@ -257,7 +262,9 @@ static BROTLI_INLINE void FN(FindLongestMatch)(
delta = banks[bank].slots[last].delta;
if (cur_ix_masked + best_len > ring_buffer_mask ||
prev_ix + best_len > ring_buffer_mask ||
data[cur_ix_masked + best_len] != data[prev_ix + best_len]) {
/* compare 4 bytes ending at best_len + 1 */
BrotliUnalignedRead32(&data[cur_ix_masked + best_len - 3]) !=
BrotliUnalignedRead32(&data[prev_ix + best_len - 3])) {
continue;
}
{
Expand Down
9 changes: 8 additions & 1 deletion c/enc/hash_longest_match64_inc.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,11 @@ static BROTLI_INLINE void FN(FindLongestMatch)(
}
}
}
/* we require matches of len >4, so increase best_len to 3, so we can compare
* 4 bytes all the time. */
if (best_len < 3) {
best_len = 3;
}
{
const size_t key = FN(HashBytes)(&data[cur_ix_masked], self->hash_mul_);
uint32_t* BROTLI_RESTRICT bucket = &buckets[key << self->block_bits_];
Expand All @@ -230,7 +235,9 @@ static BROTLI_INLINE void FN(FindLongestMatch)(
prev_ix &= ring_buffer_mask;
if (cur_ix_masked + best_len > ring_buffer_mask ||
prev_ix + best_len > ring_buffer_mask ||
data[cur_ix_masked + best_len] != data[prev_ix + best_len]) {
/* compare 4 bytes ending at best_len + 1 */
BrotliUnalignedRead32(&data[cur_ix_masked + best_len - 3]) !=
BrotliUnalignedRead32(&data[prev_ix + best_len - 3])) {
continue;
}
current4 = BrotliUnalignedRead32(data + prev_ix);
Expand Down
9 changes: 8 additions & 1 deletion c/enc/hash_longest_match_inc.h
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,11 @@ static BROTLI_INLINE void FN(FindLongestMatch)(
}
}
}
/* we require matches of len >4, so increase best_len to 3, so we can compare
* 4 bytes all the time. */
if (best_len < 3) {
best_len = 3;
}
{
const uint32_t key =
FN(HashBytes)(&data[cur_ix_masked], self->hash_shift_);
Expand All @@ -223,7 +228,9 @@ static BROTLI_INLINE void FN(FindLongestMatch)(
prev_ix &= ring_buffer_mask;
if (cur_ix_masked + best_len > ring_buffer_mask ||
prev_ix + best_len > ring_buffer_mask ||
data[cur_ix_masked + best_len] != data[prev_ix + best_len]) {
/* compare 4 bytes ending at best_len + 1 */
BrotliUnalignedRead32(&data[cur_ix_masked + best_len - 3]) !=
BrotliUnalignedRead32(&data[prev_ix + best_len - 3])) {
continue;
}
{
Expand Down
1 change: 1 addition & 0 deletions c/enc/hash_longest_match_quickly_inc.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ static BROTLI_INLINE void FN(FindLongestMatch)(
uint32_t* BROTLI_RESTRICT buckets = self->buckets_;
const size_t best_len_in = out->len;
const size_t cur_ix_masked = cur_ix & ring_buffer_mask;
/* TODO: compare 4 bytes at once (and set the minimum best len to 4) */
int compare_char = data[cur_ix_masked + best_len_in];
size_t key = FN(HashBytes)(&data[cur_ix_masked]);
size_t key_out;
Expand Down

0 comments on commit 9351fa7

Please sign in to comment.