input must be > inputMargin
(src []byte, _ *[32768]byte)
| 329 | |
| 330 | // input must be > inputMargin |
| 331 | func calcBlockSize(src []byte, _ *[32768]byte) (d int) { |
| 332 | // Initialize the hash table. |
| 333 | const ( |
| 334 | tableBits = 13 |
| 335 | maxTableSize = 1 << tableBits |
| 336 | ) |
| 337 | |
| 338 | var table [maxTableSize]uint32 |
| 339 | |
| 340 | // sLimit is when to stop looking for offset/length copies. The inputMargin |
| 341 | // lets us use a fast path for emitLiteral in the main loop, while we are |
| 342 | // looking for copies. |
| 343 | sLimit := len(src) - inputMargin |
| 344 | |
| 345 | // Bail if we can't compress to at least this. |
| 346 | dstLimit := len(src) - len(src)>>5 - 5 |
| 347 | |
| 348 | // nextEmit is where in src the next emitLiteral should start from. |
| 349 | nextEmit := 0 |
| 350 | |
| 351 | // The encoded form must start with a literal, as there are no previous |
| 352 | // bytes to copy, so we start looking for hash matches at s == 1. |
| 353 | s := 1 |
| 354 | cv := load64(src, s) |
| 355 | |
| 356 | // We search for a repeat at -1, but don't output repeats when nextEmit == 0 |
| 357 | repeat := 1 |
| 358 | |
| 359 | for { |
| 360 | candidate := 0 |
| 361 | for { |
| 362 | // Next src position to check |
| 363 | nextS := s + (s-nextEmit)>>6 + 4 |
| 364 | if nextS > sLimit { |
| 365 | goto emitRemainder |
| 366 | } |
| 367 | hash0 := hash6(cv, tableBits) |
| 368 | hash1 := hash6(cv>>8, tableBits) |
| 369 | candidate = int(table[hash0]) |
| 370 | candidate2 := int(table[hash1]) |
| 371 | table[hash0] = uint32(s) |
| 372 | table[hash1] = uint32(s + 1) |
| 373 | hash2 := hash6(cv>>16, tableBits) |
| 374 | |
| 375 | // Check repeat at offset checkRep. |
| 376 | const checkRep = 1 |
| 377 | if uint32(cv>>(checkRep*8)) == load32(src, s-repeat+checkRep) { |
| 378 | base := s + checkRep |
| 379 | // Extend back |
| 380 | for i := base - repeat; base > nextEmit && i > 0 && src[i-1] == src[base-1]; { |
| 381 | i-- |
| 382 | base-- |
| 383 | } |
| 384 | d += emitLiteralSize(src[nextEmit:base]) |
| 385 | |
| 386 | // Extend forward |
| 387 | candidate := s - repeat + 4 + checkRep |
| 388 | s += 4 + checkRep |
no test coverage detected
searching dependent graphs…