encodeBlockBest 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) <= maxBlockSize
(dst, src []byte, dict *Dict)
| 20 | // len(dst) >= MaxEncodedLen(len(src)) && |
| 21 | // minNonLiteralBlockSize <= len(src) && len(src) <= maxBlockSize |
| 22 | func encodeBlockBest(dst, src []byte, dict *Dict) (d int) { |
| 23 | // Initialize the hash tables. |
| 24 | const ( |
| 25 | // Long hash matches. |
| 26 | lTableBits = bestLongTableBits |
| 27 | maxLTableSize = bestLongTableSize |
| 28 | |
| 29 | // Short hash matches. |
| 30 | sTableBits = bestShortTableBits |
| 31 | maxSTableSize = bestShortTableSize |
| 32 | |
| 33 | inputMargin = 8 + 2 |
| 34 | |
| 35 | debug = false |
| 36 | ) |
| 37 | |
| 38 | // sLimit is when to stop looking for offset/length copies. The inputMargin |
| 39 | // lets us use a fast path for emitLiteral in the main loop, while we are |
| 40 | // looking for copies. |
| 41 | sLimit := len(src) - inputMargin |
| 42 | if len(src) < minNonLiteralBlockSize { |
| 43 | return 0 |
| 44 | } |
| 45 | sLimitDict := min(len(src)-inputMargin, MaxDictSrcOffset-inputMargin) |
| 46 | |
| 47 | tbl := getBestTables() |
| 48 | lTable := &tbl.lTable |
| 49 | sTable := &tbl.sTable |
| 50 | defer bestTablePool.Put(tbl) |
| 51 | |
| 52 | // Bail if we can't compress to at least this. |
| 53 | dstLimit := len(src) - 5 |
| 54 | |
| 55 | // nextEmit is where in src the next emitLiteral should start from. |
| 56 | nextEmit := 0 |
| 57 | |
| 58 | // The encoded form must start with a literal, as there are no previous |
| 59 | // bytes to copy, so we start looking for hash matches at s == 1. |
| 60 | s := 1 |
| 61 | repeat := 1 |
| 62 | if dict != nil { |
| 63 | dict.initBest() |
| 64 | s = 0 |
| 65 | repeat = len(dict.dict) - dict.repeat |
| 66 | } |
| 67 | cv := load64(src, s) |
| 68 | |
| 69 | // We search for a repeat at -1, but don't output repeats when nextEmit == 0 |
| 70 | const lowbitMask = 0xffffffff |
| 71 | getCur := func(x uint64) int { |
| 72 | return int(x & lowbitMask) |
| 73 | } |
| 74 | getPrev := func(x uint64) int { |
| 75 | return int(x >> 32) |
| 76 | } |
| 77 | const maxSkip = 64 |
| 78 | |
| 79 | for { |
searching dependent graphs…