authorgravatar for jahe788@gmail.comIntegratedQuantum <jahe788@gmail.com> 2024-02-27 21:55:24+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-02-27 21:26:26-08:00
log6e078883eebd0532928dba0c70e86a2eee0f246b
tree96a588165f10a249e31edde090d5130e7f62035a
parent62ce753814cf6e2f78773c85bf4bad2ba1a3fc0b

Expand the memcpy fast path in flate.CircularBuffer.writeMatch to allow for overlapping regions.


1 files changed, 12 insertions(+), 6 deletions(-)

lib/std/compress/flate/CircularBuffer.zig+12-6
...@@ -50,19 +50,25 @@ pub fn writeMatch(self: *Self, length: u16, distance: u16) !void {...@@ -50,19 +50,25 @@ pub fn writeMatch(self: *Self, length: u16, distance: u16) !void {
50 }50 }
51 assert(self.wp - self.rp < mask);51 assert(self.wp - self.rp < mask);
5252
53 var from: usize = self.wp - distance;53 var from: usize = self.wp - distance & mask;
54 const from_end: usize = from + length;54 const from_end: usize = from + length;
55 var to: usize = self.wp;55 var to: usize = self.wp & mask;
56 const to_end: usize = to + length;56 const to_end: usize = to + length;
5757
58 self.wp += length;58 self.wp += length;
5959
60 // Fast path using memcpy60 // Fast path using memcpy
61 if (length <= distance and // no overlapping buffers61 if (from_end < buffer_len and to_end < buffer_len) // start and end at the same circle
62 (from >> 16 == from_end >> 16) and // start and and at the same circle
63 (to >> 16 == to_end >> 16))
64 {62 {
65 @memcpy(self.buffer[to & mask .. to_end & mask], self.buffer[from & mask .. from_end & mask]);63 var cur_len = distance;
64 var remaining_len = length;
65 while (cur_len < remaining_len) {
66 @memcpy(self.buffer[to..][0..cur_len], self.buffer[from..][0..cur_len]);
67 to += cur_len;
68 remaining_len -= cur_len;
69 cur_len = cur_len * 2;
70 }
71 @memcpy(self.buffer[to..][0..remaining_len], self.buffer[from..][0..remaining_len]);
66 return;72 return;
67 }73 }
6874