mirror of
https://github.com/go-gitea/gitea
synced 2025-07-06 02:27:20 +00:00
update: macaron cores,gzip,session (#10522)
Co-authored-by: zeripath <art27@cantab.net>
This commit is contained in:
78
vendor/github.com/klauspost/compress/flate/huffman_bit_writer.go
generated
vendored
78
vendor/github.com/klauspost/compress/flate/huffman_bit_writer.go
generated
vendored
@ -93,12 +93,12 @@ type huffmanBitWriter struct {
|
||||
err error
|
||||
lastHeader int
|
||||
// Set between 0 (reused block can be up to 2x the size)
|
||||
logReusePenalty uint
|
||||
lastHuffMan bool
|
||||
bytes [256]byte
|
||||
literalFreq [lengthCodesStart + 32]uint16
|
||||
offsetFreq [32]uint16
|
||||
codegenFreq [codegenCodeCount]uint16
|
||||
logNewTablePenalty uint
|
||||
lastHuffMan bool
|
||||
bytes [256]byte
|
||||
literalFreq [lengthCodesStart + 32]uint16
|
||||
offsetFreq [32]uint16
|
||||
codegenFreq [codegenCodeCount]uint16
|
||||
|
||||
// codegen must have an extra space for the final symbol.
|
||||
codegen [literalCount + offsetCodeCount + 1]uint8
|
||||
@ -119,7 +119,7 @@ type huffmanBitWriter struct {
|
||||
// If lastHuffMan is set, a table for outputting literals has been generated and offsets are invalid.
|
||||
//
|
||||
// An incoming block estimates the output size of a new table using a 'fresh' by calculating the
|
||||
// optimal size and adding a penalty in 'logReusePenalty'.
|
||||
// optimal size and adding a penalty in 'logNewTablePenalty'.
|
||||
// A Huffman table is not optimal, which is why we add a penalty, and generating a new table
|
||||
// is slower both for compression and decompression.
|
||||
|
||||
@ -135,7 +135,6 @@ func newHuffmanBitWriter(w io.Writer) *huffmanBitWriter {
|
||||
func (w *huffmanBitWriter) reset(writer io.Writer) {
|
||||
w.writer = writer
|
||||
w.bits, w.nbits, w.nbytes, w.err = 0, 0, 0, nil
|
||||
w.bytes = [256]byte{}
|
||||
w.lastHeader = 0
|
||||
w.lastHuffMan = false
|
||||
}
|
||||
@ -178,6 +177,11 @@ func (w *huffmanBitWriter) flush() {
|
||||
w.nbits = 0
|
||||
return
|
||||
}
|
||||
if w.lastHeader > 0 {
|
||||
// We owe an EOB
|
||||
w.writeCode(w.literalEncoding.codes[endBlockMarker])
|
||||
w.lastHeader = 0
|
||||
}
|
||||
n := w.nbytes
|
||||
for w.nbits != 0 {
|
||||
w.bytes[n] = byte(w.bits)
|
||||
@ -350,6 +354,13 @@ func (w *huffmanBitWriter) headerSize() (size, numCodegens int) {
|
||||
int(w.codegenFreq[18])*7, numCodegens
|
||||
}
|
||||
|
||||
// dynamicSize returns the size of dynamically encoded data in bits.
|
||||
func (w *huffmanBitWriter) dynamicReuseSize(litEnc, offEnc *huffmanEncoder) (size int) {
|
||||
size = litEnc.bitLength(w.literalFreq[:]) +
|
||||
offEnc.bitLength(w.offsetFreq[:])
|
||||
return size
|
||||
}
|
||||
|
||||
// dynamicSize returns the size of dynamically encoded data in bits.
|
||||
func (w *huffmanBitWriter) dynamicSize(litEnc, offEnc *huffmanEncoder, extraBits int) (size, numCodegens int) {
|
||||
header, numCodegens := w.headerSize()
|
||||
@ -452,30 +463,30 @@ func (w *huffmanBitWriter) writeDynamicHeader(numLiterals int, numOffsets int, n
|
||||
|
||||
i := 0
|
||||
for {
|
||||
var codeWord int = int(w.codegen[i])
|
||||
var codeWord = uint32(w.codegen[i])
|
||||
i++
|
||||
if codeWord == badCode {
|
||||
break
|
||||
}
|
||||
w.writeCode(w.codegenEncoding.codes[uint32(codeWord)])
|
||||
w.writeCode(w.codegenEncoding.codes[codeWord])
|
||||
|
||||
switch codeWord {
|
||||
case 16:
|
||||
w.writeBits(int32(w.codegen[i]), 2)
|
||||
i++
|
||||
break
|
||||
case 17:
|
||||
w.writeBits(int32(w.codegen[i]), 3)
|
||||
i++
|
||||
break
|
||||
case 18:
|
||||
w.writeBits(int32(w.codegen[i]), 7)
|
||||
i++
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// writeStoredHeader will write a stored header.
|
||||
// If the stored block is only used for EOF,
|
||||
// it is replaced with a fixed huffman block.
|
||||
func (w *huffmanBitWriter) writeStoredHeader(length int, isEof bool) {
|
||||
if w.err != nil {
|
||||
return
|
||||
@ -485,6 +496,16 @@ func (w *huffmanBitWriter) writeStoredHeader(length int, isEof bool) {
|
||||
w.writeCode(w.literalEncoding.codes[endBlockMarker])
|
||||
w.lastHeader = 0
|
||||
}
|
||||
|
||||
// To write EOF, use a fixed encoding block. 10 bits instead of 5 bytes.
|
||||
if length == 0 && isEof {
|
||||
w.writeFixedHeader(isEof)
|
||||
// EOB: 7 bits, value: 0
|
||||
w.writeBits(0, 7)
|
||||
w.flush()
|
||||
return
|
||||
}
|
||||
|
||||
var flag int32
|
||||
if isEof {
|
||||
flag = 1
|
||||
@ -591,8 +612,8 @@ func (w *huffmanBitWriter) writeBlockDynamic(tokens *tokens, eof bool, input []b
|
||||
tokens.AddEOB()
|
||||
}
|
||||
|
||||
// We cannot reuse pure huffman table.
|
||||
if w.lastHuffMan && w.lastHeader > 0 {
|
||||
// We cannot reuse pure huffman table, and must mark as EOF.
|
||||
if (w.lastHuffMan || eof) && w.lastHeader > 0 {
|
||||
// We will not try to reuse.
|
||||
w.writeCode(w.literalEncoding.codes[endBlockMarker])
|
||||
w.lastHeader = 0
|
||||
@ -606,14 +627,14 @@ func (w *huffmanBitWriter) writeBlockDynamic(tokens *tokens, eof bool, input []b
|
||||
var size int
|
||||
// Check if we should reuse.
|
||||
if w.lastHeader > 0 {
|
||||
// Estimate size for using a new table
|
||||
// Estimate size for using a new table.
|
||||
// Use the previous header size as the best estimate.
|
||||
newSize := w.lastHeader + tokens.EstimatedBits()
|
||||
newSize += newSize >> w.logNewTablePenalty
|
||||
|
||||
// The estimated size is calculated as an optimal table.
|
||||
// We add a penalty to make it more realistic and re-use a bit more.
|
||||
newSize += newSize >> (w.logReusePenalty & 31)
|
||||
extra := w.extraBitSize()
|
||||
reuseSize, _ := w.dynamicSize(w.literalEncoding, w.offsetEncoding, extra)
|
||||
reuseSize := w.dynamicReuseSize(w.literalEncoding, w.offsetEncoding) + w.extraBitSize()
|
||||
|
||||
// Check if a new table is better.
|
||||
if newSize < reuseSize {
|
||||
@ -805,21 +826,30 @@ func (w *huffmanBitWriter) writeBlockHuff(eof bool, input []byte, sync bool) {
|
||||
}
|
||||
|
||||
// Add everything as literals
|
||||
estBits := histogramSize(input, w.literalFreq[:], !eof && !sync) + 15
|
||||
// We have to estimate the header size.
|
||||
// Assume header is around 70 bytes:
|
||||
// https://stackoverflow.com/a/25454430
|
||||
const guessHeaderSizeBits = 70 * 8
|
||||
estBits, estExtra := histogramSize(input, w.literalFreq[:], !eof && !sync)
|
||||
estBits += w.lastHeader + 15
|
||||
if w.lastHeader == 0 {
|
||||
estBits += guessHeaderSizeBits
|
||||
}
|
||||
estBits += estBits >> w.logNewTablePenalty
|
||||
|
||||
// Store bytes, if we don't get a reasonable improvement.
|
||||
ssize, storable := w.storedSize(input)
|
||||
if storable && ssize < (estBits+estBits>>4) {
|
||||
if storable && ssize < estBits {
|
||||
w.writeStoredHeader(len(input), eof)
|
||||
w.writeBytes(input)
|
||||
return
|
||||
}
|
||||
|
||||
if w.lastHeader > 0 {
|
||||
size, _ := w.dynamicSize(w.literalEncoding, huffOffset, w.lastHeader)
|
||||
estBits += estBits >> (w.logReusePenalty)
|
||||
reuseSize := w.literalEncoding.bitLength(w.literalFreq[:256])
|
||||
estBits += estExtra
|
||||
|
||||
if estBits < size {
|
||||
if estBits < reuseSize {
|
||||
// We owe an EOB
|
||||
w.writeCode(w.literalEncoding.codes[endBlockMarker])
|
||||
w.lastHeader = 0
|
||||
|
Reference in New Issue
Block a user