@@ -215,6 +215,7 @@ func (q *Pathfinder) FindMatches(dst []Match, src []byte) []Match {
215
215
216
216
slices .SortFunc (foundMatches , func (a , b absoluteMatch ) int { return a .Start - b .Start })
217
217
matchIndex := 0
218
+ var pending absoluteMatch
218
219
219
220
for i := historyLen ; i < len (src ); i ++ {
220
221
var arrivedHere arrival
@@ -234,6 +235,9 @@ func (q *Pathfinder) FindMatches(dst []Match, src []byte) []Match {
234
235
for matchIndex < len (foundMatches ) && foundMatches [matchIndex ].Start == i {
235
236
m := foundMatches [matchIndex ]
236
237
matchIndex ++
238
+ if m .End > pending .End {
239
+ pending = m
240
+ }
237
241
matchCost := baseMatchCost + float32 (bits .Len (uint (m .Start - m .Match )))
238
242
if i > historyLen && arrivedHere .length == 0 && arrivedHere .distance == uint32 (m .Start - m .Match ) {
239
243
matchCost = repeatMatchCost
@@ -250,6 +254,23 @@ func (q *Pathfinder) FindMatches(dst []Match, src []byte) []Match {
250
254
}
251
255
}
252
256
257
+ // If a match from an earlier position extends far enough past the current
258
+ // position, try using the tail of it, starting from here.
259
+ if pending .Start != i && pending .End >= i + q .MinLength &&
260
+ ! (arrivedHere .length != 0 && arrivedHere .distance == uint32 (pending .Start - pending .Match )) {
261
+ matchCost := baseMatchCost + float32 (bits .Len (uint (pending .Start - pending .Match )))
262
+ for j := i + q .MinLength ; j <= pending .End ; j ++ {
263
+ a := & arrivals [j - historyLen - 1 ]
264
+ if a .cost == 0 || arrivedHere .cost + matchCost < a .cost {
265
+ * a = arrival {
266
+ length : uint32 (j - i ),
267
+ distance : uint32 (pending .Start - pending .Match ),
268
+ cost : arrivedHere .cost + matchCost ,
269
+ }
270
+ }
271
+ }
272
+ }
273
+
253
274
delta := q .chain [i ]
254
275
if delta == 0 {
255
276
continue
0 commit comments