encodeBlockBestSnappy 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) <= maxBlockSiz
(dst, src []byte)
| 455 | // len(dst) >= MaxEncodedLen(len(src)) && |
| 456 | // minNonLiteralBlockSize <= len(src) && len(src) <= maxBlockSize |
| 457 | func encodeBlockBestSnappy(dst, src []byte) (d int) { |
| 458 | // Initialize the hash tables. |
| 459 | const ( |
| 460 | // Long hash matches. |
| 461 | lTableBits = bestLongTableBits |
| 462 | maxLTableSize = bestLongTableSize |
| 463 | |
| 464 | // Short hash matches. |
| 465 | sTableBits = bestShortTableBits |
| 466 | maxSTableSize = bestShortTableSize |
| 467 | |
| 468 | inputMargin = 8 + 2 |
| 469 | ) |
| 470 | |
| 471 | // sLimit is when to stop looking for offset/length copies. The inputMargin |
| 472 | // lets us use a fast path for emitLiteral in the main loop, while we are |
| 473 | // looking for copies. |
| 474 | sLimit := len(src) - inputMargin |
| 475 | if len(src) < minNonLiteralBlockSize { |
| 476 | return 0 |
| 477 | } |
| 478 | |
| 479 | tbl := getBestTables() |
| 480 | lTable := &tbl.lTable |
| 481 | sTable := &tbl.sTable |
| 482 | defer bestTablePool.Put(tbl) |
| 483 | |
| 484 | // Bail if we can't compress to at least this. |
| 485 | dstLimit := len(src) - 5 |
| 486 | |
| 487 | // nextEmit is where in src the next emitLiteral should start from. |
| 488 | nextEmit := 0 |
| 489 | |
| 490 | // The encoded form must start with a literal, as there are no previous |
| 491 | // bytes to copy, so we start looking for hash matches at s == 1. |
| 492 | s := 1 |
| 493 | cv := load64(src, s) |
| 494 | |
| 495 | // We search for a repeat at -1, but don't output repeats when nextEmit == 0 |
| 496 | repeat := 1 |
| 497 | const lowbitMask = 0xffffffff |
| 498 | getCur := func(x uint64) int { |
| 499 | return int(x & lowbitMask) |
| 500 | } |
| 501 | getPrev := func(x uint64) int { |
| 502 | return int(x >> 32) |
| 503 | } |
| 504 | const maxSkip = 64 |
| 505 | |
| 506 | for { |
| 507 | type match struct { |
| 508 | offset int |
| 509 | s int |
| 510 | length int |
| 511 | score int |
| 512 | } |
| 513 | var best match |
| 514 | for { |
no test coverage detected
searching dependent graphs…