| ... | @@ -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); |
| 52 | | 52 | |
| 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; |
| 57 | | 57 | |
| 58 | self.wp += length; | 58 | self.wp += length; |
| 59 | | 59 | |
| 60 | // Fast path using memcpy | 60 | // Fast path using memcpy |
| 61 | if (length <= distance and // no overlapping buffers | 61 | 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 | } |
| 68 | | 74 | |