mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-29 10:57:44 +09: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