| ... | ... | @@ -50,19 +50,25 @@ pub fn writeMatch(self: *Self, length: u16, distance: u16) !void { |
| 50 | 50 | } |
| 51 | 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 | 54 | const from_end: usize = from + length; |
| 55 | | var to: usize = self.wp; |
| 55 | var to: usize = self.wp & mask; |
| 56 | 56 | const to_end: usize = to + length; |
| 57 | 57 | |
| 58 | 58 | self.wp += length; |
| 59 | 59 | |
| 60 | 60 | // Fast path using memcpy |
| 61 | | if (length <= distance and // no overlapping buffers |
| 62 | | (from >> 16 == from_end >> 16) and // start and and at the same circle |
| 63 | | (to >> 16 == to_end >> 16)) |
| 61 | if (from_end < buffer_len and to_end < buffer_len) // start and end at the same circle |
| 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 | 72 | return; |
| 67 | 73 | } |
| 68 | 74 | |