@@ -12,7 +12,7 @@ import (
12
12
)
13
13
14
14
const (
15
- bestLongTableBits = 22 // Bits used in the long match table
15
+ bestLongTableBits = 23 // Bits used in the long match table
16
16
bestLongTableSize = 1 << bestLongTableBits // Size of the table
17
17
bestLongLen = 8 // Bytes used for table hash
18
18
@@ -188,7 +188,7 @@ encodeLoop:
188
188
panic ("offset0 was 0" )
189
189
}
190
190
191
- const goodEnough = 100
191
+ const goodEnough = 250
192
192
193
193
nextHashL := hashLen (cv , bestLongTableBits , bestLongLen )
194
194
nextHashS := hashLen (cv , bestShortTableBits , bestShortLen )
@@ -234,17 +234,29 @@ encodeLoop:
234
234
improve (& best , candidateS .prev - e .cur , s , uint32 (cv ), - 1 )
235
235
236
236
if canRepeat && best .length < goodEnough {
237
- cv32 := uint32 (cv >> 8 )
238
- spp := s + 1
239
- improve (& best , spp - offset1 , spp , cv32 , 1 )
240
- improve (& best , spp - offset2 , spp , cv32 , 2 )
241
- improve (& best , spp - offset3 , spp , cv32 , 3 )
242
- if best .length > 0 {
243
- cv32 = uint32 (cv >> 24 )
244
- spp += 2
237
+ if s == nextEmit {
238
+ // Check repeats straight after a match.
239
+ improve (& best , s - offset2 , s , uint32 (cv ), 1 | 4 )
240
+ improve (& best , s - offset3 , s , uint32 (cv ), 2 | 4 )
241
+ if offset1 > 1 {
242
+ improve (& best , s - (offset1 - 1 ), s , uint32 (cv ), 3 | 4 )
243
+ }
244
+ }
245
+
246
+ // If either no match or a non-repeat match, check at + 1
247
+ if best .rep <= 0 {
248
+ cv32 := uint32 (cv >> 8 )
249
+ spp := s + 1
245
250
improve (& best , spp - offset1 , spp , cv32 , 1 )
246
251
improve (& best , spp - offset2 , spp , cv32 , 2 )
247
252
improve (& best , spp - offset3 , spp , cv32 , 3 )
253
+ if best .rep < 0 {
254
+ cv32 = uint32 (cv >> 24 )
255
+ spp += 2
256
+ improve (& best , spp - offset1 , spp , cv32 , 1 )
257
+ improve (& best , spp - offset2 , spp , cv32 , 2 )
258
+ improve (& best , spp - offset3 , spp , cv32 , 3 )
259
+ }
248
260
}
249
261
}
250
262
// Load next and check...
@@ -263,7 +275,7 @@ encodeLoop:
263
275
continue
264
276
}
265
277
266
- s ++
278
+ s := s + 1
267
279
candidateS = e .table [hashLen (cv >> 8 , bestShortTableBits , bestShortLen )]
268
280
cv = load6432 (src , s )
269
281
cv2 := load6432 (src , s + 1 )
@@ -307,23 +319,22 @@ encodeLoop:
307
319
308
320
// We have a match, we can store the forward value
309
321
if best .rep > 0 {
310
- s = best .s
311
322
var seq seq
312
323
seq .matchLen = uint32 (best .length - zstdMinMatch )
313
324
if debugAsserts && s <= nextEmit {
314
325
panic ("s <= nextEmit" )
315
326
}
316
- addLiterals (& seq , s )
327
+ addLiterals (& seq , best . s )
317
328
318
- // rep 0
319
- seq .offset = uint32 (best .rep )
329
+ // Repeat. If bit 4 is set, this is a non-lit repeat.
330
+ seq .offset = uint32 (best .rep & 3 )
320
331
if debugSequences {
321
332
println ("repeat sequence" , seq , "next s:" , s )
322
333
}
323
334
blk .sequences = append (blk .sequences , seq )
324
335
325
- // Index match start+1 (long) -> s - 1
326
- index0 := s
336
+ // Index old s + 1 -> s - 1
337
+ index0 := s + 1
327
338
s = best .s + best .length
328
339
329
340
nextEmit = s
@@ -336,7 +347,7 @@ encodeLoop:
336
347
}
337
348
// Index skipped...
338
349
off := index0 + e .cur
339
- for index0 < s - 1 {
350
+ for index0 < s {
340
351
cv0 := load6432 (src , index0 )
341
352
h0 := hashLen (cv0 , bestLongTableBits , bestLongLen )
342
353
h1 := hashLen (cv0 , bestShortTableBits , bestShortLen )
@@ -346,17 +357,20 @@ encodeLoop:
346
357
index0 ++
347
358
}
348
359
switch best .rep {
349
- case 2 :
360
+ case 2 , 4 | 1 :
350
361
offset1 , offset2 = offset2 , offset1
351
- case 3 :
362
+ case 3 , 4 | 2 :
352
363
offset1 , offset2 , offset3 = offset3 , offset1 , offset2
364
+ case 4 | 3 :
365
+ offset1 , offset2 , offset3 = offset1 - 1 , offset1 , offset2
353
366
}
354
367
cv = load6432 (src , s )
355
368
continue
356
369
}
357
370
358
371
// A 4-byte match has been found. Update recent offsets.
359
372
// We'll later see if more than 4 bytes.
373
+ index0 := s + 1
360
374
s = best .s
361
375
t := best .offset
362
376
offset1 , offset2 , offset3 = s - t , offset1 , offset2
@@ -388,10 +402,8 @@ encodeLoop:
388
402
break encodeLoop
389
403
}
390
404
391
- // Index match start+1 (long) -> s - 1
392
- index0 := s - l + 1
393
- // every entry
394
- for index0 < s - 1 {
405
+ // Index old s + 1 -> s - 1
406
+ for index0 < s {
395
407
cv0 := load6432 (src , index0 )
396
408
h0 := hashLen (cv0 , bestLongTableBits , bestLongLen )
397
409
h1 := hashLen (cv0 , bestShortTableBits , bestShortLen )
@@ -400,50 +412,7 @@ encodeLoop:
400
412
e .table [h1 ] = prevEntry {offset : off , prev : e .table [h1 ].offset }
401
413
index0 ++
402
414
}
403
-
404
415
cv = load6432 (src , s )
405
- if ! canRepeat {
406
- continue
407
- }
408
-
409
- // Check offset 2
410
- for {
411
- o2 := s - offset2
412
- if load3232 (src , o2 ) != uint32 (cv ) {
413
- // Do regular search
414
- break
415
- }
416
-
417
- // Store this, since we have it.
418
- nextHashS := hashLen (cv , bestShortTableBits , bestShortLen )
419
- nextHashL := hashLen (cv , bestLongTableBits , bestLongLen )
420
-
421
- // We have at least 4 byte match.
422
- // No need to check backwards. We come straight from a match
423
- l := 4 + e .matchlen (s + 4 , o2 + 4 , src )
424
-
425
- e .longTable [nextHashL ] = prevEntry {offset : s + e .cur , prev : e .longTable [nextHashL ].offset }
426
- e .table [nextHashS ] = prevEntry {offset : s + e .cur , prev : e .table [nextHashS ].offset }
427
- seq .matchLen = uint32 (l ) - zstdMinMatch
428
- seq .litLen = 0
429
-
430
- // Since litlen is always 0, this is offset 1.
431
- seq .offset = 1
432
- s += l
433
- nextEmit = s
434
- if debugSequences {
435
- println ("sequence" , seq , "next s:" , s )
436
- }
437
- blk .sequences = append (blk .sequences , seq )
438
-
439
- // Swap offset 1 and 2.
440
- offset1 , offset2 = offset2 , offset1
441
- if s >= sLimit {
442
- // Finished
443
- break encodeLoop
444
- }
445
- cv = load6432 (src , s )
446
- }
447
416
}
448
417
449
418
if int (nextEmit ) < len (src ) {
0 commit comments