encodeBlockSnappyGo64K is a special version of encodeBlockSnappyGo for sizes <64KB
(dst, src []byte)
| 690 | |
| 691 | // encodeBlockSnappyGo64K is a special version of encodeBlockSnappyGo for sizes <64KB |
| 692 | func encodeBlockSnappyGo64K(dst, src []byte) (d int) { |
| 693 | // Initialize the hash table. |
| 694 | const ( |
| 695 | tableBits = 14 |
| 696 | maxTableSize = 1 << tableBits |
| 697 | ) |
| 698 | |
| 699 | var table [maxTableSize]uint16 |
| 700 | |
| 701 | // sLimit is when to stop looking for offset/length copies. The inputMargin |
| 702 | // lets us use a fast path for emitLiteral in the main loop, while we are |
| 703 | // looking for copies. |
| 704 | sLimit := len(src) - inputMargin |
| 705 | |
| 706 | // Bail if we can't compress to at least this. |
| 707 | dstLimit := len(src) - len(src)>>5 - 5 |
| 708 | |
| 709 | // nextEmit is where in src the next emitLiteral should start from. |
| 710 | nextEmit := 0 |
| 711 | |
| 712 | // The encoded form must start with a literal, as there are no previous |
| 713 | // bytes to copy, so we start looking for hash matches at s == 1. |
| 714 | s := 1 |
| 715 | cv := load64(src, s) |
| 716 | |
| 717 | // We search for a repeat at -1, but don't output repeats when nextEmit == 0 |
| 718 | repeat := 1 |
| 719 | |
| 720 | for { |
| 721 | candidate := 0 |
| 722 | for { |
| 723 | // Next src position to check |
| 724 | nextS := s + (s-nextEmit)>>5 + 4 |
| 725 | if nextS > sLimit { |
| 726 | goto emitRemainder |
| 727 | } |
| 728 | hash0 := hash6(cv, tableBits) |
| 729 | hash1 := hash6(cv>>8, tableBits) |
| 730 | candidate = int(table[hash0]) |
| 731 | candidate2 := int(table[hash1]) |
| 732 | table[hash0] = uint16(s) |
| 733 | table[hash1] = uint16(s + 1) |
| 734 | hash2 := hash6(cv>>16, tableBits) |
| 735 | |
| 736 | // Check repeat at offset checkRep. |
| 737 | const checkRep = 1 |
| 738 | if uint32(cv>>(checkRep*8)) == load32(src, s-repeat+checkRep) { |
| 739 | base := s + checkRep |
| 740 | // Extend back |
| 741 | for i := base - repeat; base > nextEmit && i > 0 && src[i-1] == src[base-1]; { |
| 742 | i-- |
| 743 | base-- |
| 744 | } |
| 745 | // Bail if we exceed the maximum size. |
| 746 | if d+(base-nextEmit) > dstLimit { |
| 747 | return 0 |
| 748 | } |
| 749 |
searching dependent graphs…