If the match is shorter, the returned value can be any value <= old.
fn betterMatchLen(old: u16, prev: []const u8, bytes: []const u8) u16
fn betterMatchLen(old: u16, prev: []const u8, bytes: []const u8) u16 {
assert(old < @min(bytes.len, token.max_length));
assert(prev.len >= bytes.len);
assert(bytes.len >= token.min_length);
var i: u16 = 0;
const Block = @Int(.unsigned, @min(math.divCeil(
comptime_int,
math.ceilPowerOfTwoAssert(usize, @bitSizeOf(usize)),
8,
) catch unreachable, 256) * 8);
if (bytes.len < token.max_length) {
@branchHint(.unlikely); // Only end of stream
while (bytes[i..].len >= @sizeOf(Block)) {
const a = mem.readInt(Block, prev[i..][0..@sizeOf(Block)], .little);
const b = mem.readInt(Block, bytes[i..][0..@sizeOf(Block)], .little);
const diff = a ^ b;
if (diff != 0) {
@branchHint(.likely);
i += @ctz(diff) / 8;
return i;
}
i += @sizeOf(Block);
}
while (i != bytes.len and prev[i] == bytes[i]) {
i += 1;
}
assert(i < token.max_length);
return i;
}
if (old >= @sizeOf(Block)) {
// Check that a longer end is present, otherwise the match is always worse
const a = mem.readInt(Block, prev[old + 1 - @sizeOf(Block) ..][0..@sizeOf(Block)], .little);
const b = mem.readInt(Block, bytes[old + 1 - @sizeOf(Block) ..][0..@sizeOf(Block)], .little);
if (a != b) return i;
}
while (true) {
const a = mem.readInt(Block, prev[i..][0..@sizeOf(Block)], .little);
const b = mem.readInt(Block, bytes[i..][0..@sizeOf(Block)], .little);
const diff = a ^ b;
if (diff != 0) {
i += @ctz(diff) / 8;
return i;
}
i += @sizeOf(Block);
if (i == 256) break;
}
const a = mem.readInt(u16, prev[i..][0..2], .little);
const b = mem.readInt(u16, bytes[i..][0..2], .little);
const diff = a ^ b;
i += @ctz(diff) / 8;
assert(i <= token.max_length);
return i;
}