encodeBlockBetterSnappyGo encodes a non-empty src to a guaranteed-large-enough dst. It assumes that the varint-encoded length of the decompressed bytes has already been written. It also assumes that: len(dst) >= MaxEncodedLen(len(src)) && minNonLiteralBlockSize <= len(src) && len(src) <= maxBloc
(dst, src []byte)
| 731 | // len(dst) >= MaxEncodedLen(len(src)) && |
| 732 | // minNonLiteralBlockSize <= len(src) && len(src) <= maxBlockSize |
| 733 | func encodeBlockBetterSnappyGo64K(dst, src []byte) (d int) { |
| 734 | // sLimit is when to stop looking for offset/length copies. The inputMargin |
| 735 | // lets us use a fast path for emitLiteral in the main loop, while we are |
| 736 | // looking for copies. |
| 737 | sLimit := len(src) - inputMargin |
| 738 | if len(src) < minNonLiteralBlockSize { |
| 739 | return 0 |
| 740 | } |
| 741 | |
| 742 | // Initialize the hash tables. |
| 743 | // Use smaller tables for smaller blocks |
| 744 | const ( |
| 745 | // Long hash matches. |
| 746 | lTableBits = 15 |
| 747 | maxLTableSize = 1 << lTableBits |
| 748 | |
| 749 | // Short hash matches. |
| 750 | sTableBits = 13 |
| 751 | maxSTableSize = 1 << sTableBits |
| 752 | ) |
| 753 | |
| 754 | var lTable [maxLTableSize]uint16 |
| 755 | var sTable [maxSTableSize]uint16 |
| 756 | |
| 757 | // Bail if we can't compress to at least this. |
| 758 | dstLimit := len(src) - len(src)>>5 - 6 |
| 759 | |
| 760 | // nextEmit is where in src the next emitLiteral should start from. |
| 761 | nextEmit := 0 |
| 762 | |
| 763 | // The encoded form must start with a literal, as there are no previous |
| 764 | // bytes to copy, so we start looking for hash matches at s == 1. |
| 765 | s := 1 |
| 766 | cv := load64(src, s) |
| 767 | |
| 768 | const maxSkip = 100 |
| 769 | |
| 770 | for { |
| 771 | candidateL := 0 |
| 772 | nextS := 0 |
| 773 | for { |
| 774 | // Next src position to check |
| 775 | nextS = min(s+(s-nextEmit)>>6+1, s+maxSkip) |
| 776 | |
| 777 | if nextS > sLimit { |
| 778 | goto emitRemainder |
| 779 | } |
| 780 | hashL := hash7(cv, lTableBits) |
| 781 | hashS := hash4(cv, sTableBits) |
| 782 | candidateL = int(lTable[hashL]) |
| 783 | candidateS := int(sTable[hashS]) |
| 784 | lTable[hashL] = uint16(s) |
| 785 | sTable[hashS] = uint16(s) |
| 786 | |
| 787 | if uint32(cv) == load32(src, candidateL) { |
| 788 | break |
| 789 | } |
| 790 |
searching dependent graphs…