(dst, src []byte)
| 500 | } |
| 501 | |
| 502 | func encodeBlockSnappyGo(dst, src []byte) (d int) { |
| 503 | // Initialize the hash table. |
| 504 | const ( |
| 505 | tableBits = 14 |
| 506 | maxTableSize = 1 << tableBits |
| 507 | ) |
| 508 | var table [maxTableSize]uint32 |
| 509 | |
| 510 | // sLimit is when to stop looking for offset/length copies. The inputMargin |
| 511 | // lets us use a fast path for emitLiteral in the main loop, while we are |
| 512 | // looking for copies. |
| 513 | sLimit := len(src) - inputMargin |
| 514 | |
| 515 | // Bail if we can't compress to at least this. |
| 516 | dstLimit := len(src) - len(src)>>5 - 5 |
| 517 | |
| 518 | // nextEmit is where in src the next emitLiteral should start from. |
| 519 | nextEmit := 0 |
| 520 | |
| 521 | // The encoded form must start with a literal, as there are no previous |
| 522 | // bytes to copy, so we start looking for hash matches at s == 1. |
| 523 | s := 1 |
| 524 | cv := load64(src, s) |
| 525 | |
| 526 | // We search for a repeat at -1, but don't output repeats when nextEmit == 0 |
| 527 | repeat := 1 |
| 528 | |
| 529 | for { |
| 530 | candidate := 0 |
| 531 | for { |
| 532 | // Next src position to check |
| 533 | nextS := s + (s-nextEmit)>>6 + 4 |
| 534 | if nextS > sLimit { |
| 535 | goto emitRemainder |
| 536 | } |
| 537 | hash0 := hash6(cv, tableBits) |
| 538 | hash1 := hash6(cv>>8, tableBits) |
| 539 | candidate = int(table[hash0]) |
| 540 | candidate2 := int(table[hash1]) |
| 541 | table[hash0] = uint32(s) |
| 542 | table[hash1] = uint32(s + 1) |
| 543 | hash2 := hash6(cv>>16, tableBits) |
| 544 | |
| 545 | // Check repeat at offset checkRep. |
| 546 | const checkRep = 1 |
| 547 | if uint32(cv>>(checkRep*8)) == load32(src, s-repeat+checkRep) { |
| 548 | base := s + checkRep |
| 549 | // Extend back |
| 550 | for i := base - repeat; base > nextEmit && i > 0 && src[i-1] == src[base-1]; { |
| 551 | i-- |
| 552 | base-- |
| 553 | } |
| 554 | // Bail if we exceed the maximum size. |
| 555 | if d+(base-nextEmit) > dstLimit { |
| 556 | return 0 |
| 557 | } |
| 558 | |
| 559 | d += emitLiteral(dst[d:], src[nextEmit:base]) |
searching dependent graphs…