@@ -42,30 +42,51 @@ module internal Bytes =
4242 let inline initNext p =
4343 let m = Array.length p
4444 let next = Array.create m 0
45- let i = ref 1
46- let j = ref 0
47- while ! i < m - 1 do
48- if p.[! i] = p.[! j] then begin incr i; incr j; next.[! i] <- ! j end else
49- if ! j = 0 then begin incr i; next.[! i] <- 0 end else j := next.[! j]
45+ let mutable i = 1
46+ let mutable j = 0
47+ while i < m - 1 do
48+ if p.[ i] = p.[ j] then
49+ i <- i + 1
50+ j <- j + 1
51+ next.[ i] <- j
52+ else
53+ if j = 0 then
54+ i <- i + 1
55+ next.[ i] <- 0
56+ else
57+ j <- next.[ j]
5058 next
5159
5260 let inline _kmpW ( p : byte []) ( next : int []) m ( xs : ReadOnlySequence < byte >) =
53- let n = xs.Length
5461 let mutable i = 0 L
55- let mutable j = 0 L
56- let a ( x ) =
57- xs.Slice( xs.GetPosition( x)) .First.Span[ 0 ]
58- while j < m && i < n do
59- if a( i) = p.[ int j] then
62+ let mutable j = 0
63+ let mutable found = false
64+ let mutable result = ValueNone
65+ // Iterate through segments
66+ let mutable enumerator = xs.GetEnumerator()
67+ while not found && enumerator.MoveNext() do
68+ let span = enumerator.Current.Span
69+ let mutable byteIdx = 0
70+ while not found && byteIdx < span.Length do
71+ // Current byte in the sequence
72+ let b = span.[ byteIdx]
73+
74+ // KMP failure function: back up j until we have a match or j is 0
75+ while j > 0 && b <> p.[ j] do
76+ j <- next.[ j]
77+
78+ // Check if current byte matches pattern[j]
79+ if b = p.[ j] then j <- j + 1
80+
81+ // Found complete match - exit early
82+ if j = m then
83+ result <- ValueSome( i - int64( m - 1 ))
84+ found <- true
85+
6086 i <- i + 1 L
61- j <- j + 1 L
62- else
63- if j = 0 then
64- i <- i + 1 L
65- else
66- j <- next.[ int j]
67- done ;
68- if j >= m then ValueSome( i - m) else ValueNone
87+ byteIdx <- byteIdx + 1
88+
89+ result
6990
7091 let inline kmpW p ( xs : ReadOnlySequence < byte >) =
7192 let next = initNext p
0 commit comments