// hashPrev[hashHead[hashValue] & windowMask] contains the previous index
// with the same hash value.
chainHead int
- hashHead []uint32
- hashPrev []uint32
+ hashHead [hashSize]uint32
+ hashPrev [windowSize]uint32
hashOffset int
// input window: unprocessed data is window[index:windowEnd]
var newH uint32
for i, val := range dst {
di := i + index
- newH = val & hashMask
+ newH = val
+ hh := &d.hashHead[newH&hashMask]
// Get previous value with the same hash.
// Our chain should point to the previous value.
- d.hashPrev[di&windowMask] = d.hashHead[newH]
+ d.hashPrev[di&windowMask] = *hh
// Set the head of the hash chain to us.
- d.hashHead[newH] = uint32(di + d.hashOffset)
+ *hh = uint32(di + d.hashOffset)
}
d.hash = newH
}
// bytes in size.
func matchLen(a, b []byte, max int) int {
a = a[:max]
+ b = b[:len(a)]
for i, av := range a {
if b[i] != av {
return i
}
func (d *compressor) initDeflate() {
- d.hashHead = make([]uint32, hashSize)
- d.hashPrev = make([]uint32, windowSize)
d.window = make([]byte, 2*windowSize)
d.hashOffset = 1
d.tokens = make([]token, 0, maxFlateBlockTokens+1)
if d.index < d.maxInsertIndex {
// Update the hash
d.hash = hash4(d.window[d.index : d.index+minMatchLength])
- d.chainHead = int(d.hashHead[d.hash])
+ hh := &d.hashHead[d.hash&hashMask]
+ d.chainHead = int(*hh)
d.hashPrev[d.index&windowMask] = uint32(d.chainHead)
- d.hashHead[d.hash] = uint32(d.index + d.hashOffset)
+ *hh = uint32(d.index + d.hashOffset)
}
prevLength := d.length
prevOffset := d.offset
d.hash = hash4(d.window[d.index : d.index+minMatchLength])
// Get previous value with the same hash.
// Our chain should point to the previous value.
- d.hashPrev[d.index&windowMask] = d.hashHead[d.hash]
+ hh := &d.hashHead[d.hash&hashMask]
+ d.hashPrev[d.index&windowMask] = *hh
// Set the head of the hash chain to us.
- d.hashHead[d.hash] = uint32(d.index + d.hashOffset)
+ *hh = uint32(d.index + d.hashOffset)
}
}
if d.fastSkipHashing == skipNever {
return nil
}
-// hzeroes is used for zeroing the hash slice.
-var hzeroes [256]uint32
-
func (d *compressor) reset(w io.Writer) {
d.w.reset(w)
d.sync = false
d.windowEnd = 0
default:
d.chainHead = -1
- for s := d.hashHead; len(s) > 0; {
- n := copy(s, hzeroes[:])
- s = s[n:]
+ for i := range d.hashHead {
+ d.hashHead[i] = 0
}
- for s := d.hashPrev; len(s) > 0; s = s[len(hzeroes):] {
- copy(s, hzeroes[:])
+ for i := range d.hashPrev {
+ d.hashPrev[i] = 0
}
d.hashOffset = 1
-
d.index, d.windowEnd = 0, 0
d.blockStart, d.byteAvailable = 0, false
d.tokens = d.tokens[:0]
bits uint64
nbits uint
bytes [bufferSize]byte
+ codegenFreq [codegenCodeCount]int32
nbytes int
literalFreq []int32
offsetFreq []int32
codegen []uint8
- codegenFreq []int32
literalEncoding *huffmanEncoder
offsetEncoding *huffmanEncoder
codegenEncoding *huffmanEncoder
literalFreq: make([]int32, maxNumLit),
offsetFreq: make([]int32, offsetCodeCount),
codegen: make([]uint8, maxNumLit+offsetCodeCount+1),
- codegenFreq: make([]int32, codegenCodeCount),
literalEncoding: newHuffmanEncoder(maxNumLit),
codegenEncoding: newHuffmanEncoder(codegenCodeCount),
offsetEncoding: newHuffmanEncoder(offsetCodeCount),
w.bits >>= 48
w.nbits -= 48
n := w.nbytes
- w.bytes[n+0] = byte(bits)
- w.bytes[n+1] = byte(bits >> 8)
- w.bytes[n+2] = byte(bits >> 16)
- w.bytes[n+3] = byte(bits >> 24)
- w.bytes[n+4] = byte(bits >> 32)
- w.bytes[n+5] = byte(bits >> 40)
+ bytes := w.bytes[n : n+6]
+ bytes[0] = byte(bits)
+ bytes[1] = byte(bits >> 8)
+ bytes[2] = byte(bits >> 16)
+ bytes[3] = byte(bits >> 24)
+ bytes[4] = byte(bits >> 32)
+ bytes[5] = byte(bits >> 40)
n += 6
if n >= bufferFlushSize {
_, w.err = w.w.Write(w.bytes[:n])
w.bits >>= 48
w.nbits -= 48
n := w.nbytes
- w.bytes[n+0] = byte(bits)
- w.bytes[n+1] = byte(bits >> 8)
- w.bytes[n+2] = byte(bits >> 16)
- w.bytes[n+3] = byte(bits >> 24)
- w.bytes[n+4] = byte(bits >> 32)
- w.bytes[n+5] = byte(bits >> 40)
+ bytes := w.bytes[n : n+6]
+ bytes[0] = byte(bits)
+ bytes[1] = byte(bits >> 8)
+ bytes[2] = byte(bits >> 16)
+ bytes[3] = byte(bits >> 24)
+ bytes[4] = byte(bits >> 32)
+ bytes[5] = byte(bits >> 40)
n += 6
if n >= bufferFlushSize {
_, w.err = w.w.Write(w.bytes[:n])
// Generate codegen and codegenFrequencies, which indicates how to encode
// the literalEncoding and the offsetEncoding.
w.generateCodegen(numLiterals, numOffsets, w.literalEncoding, w.offsetEncoding)
- w.codegenEncoding.generate(w.codegenFreq, 7)
+ w.codegenEncoding.generate(w.codegenFreq[:], 7)
numCodegens = len(w.codegenFreq)
for numCodegens > 4 && w.codegenFreq[codegenOrder[numCodegens-1]] == 0 {
numCodegens--
}
dynamicHeader := int64(3+5+5+4+(3*numCodegens)) +
- w.codegenEncoding.bitLength(w.codegenFreq) +
+ w.codegenEncoding.bitLength(w.codegenFreq[:]) +
int64(extraBits) +
int64(w.codegenFreq[16]*2) +
int64(w.codegenFreq[17]*3) +
// Generate codegen and codegenFrequencies, which indicates how to encode
// the literalEncoding and the offsetEncoding.
w.generateCodegen(numLiterals, numOffsets, w.literalEncoding, w.offsetEncoding)
- w.codegenEncoding.generate(w.codegenFreq, 7)
+ w.codegenEncoding.generate(w.codegenFreq[:], 7)
numCodegens := len(w.codegenFreq)
for numCodegens > 4 && w.codegenFreq[codegenOrder[numCodegens-1]] == 0 {
numCodegens--
// Generate codegen and codegenFrequencies, which indicates how to encode
// the literalEncoding and the offsetEncoding.
w.generateCodegen(numLiterals, numOffsets, w.literalEncoding, huffOffset)
- w.codegenEncoding.generate(w.codegenFreq, 7)
+ w.codegenEncoding.generate(w.codegenFreq[:], 7)
numCodegens = len(w.codegenFreq)
for numCodegens > 4 && w.codegenFreq[codegenOrder[numCodegens-1]] == 0 {
numCodegens--
}
headerSize := int64(3+5+5+4+(3*numCodegens)) +
- w.codegenEncoding.bitLength(w.codegenFreq) +
+ w.codegenEncoding.bitLength(w.codegenFreq[:]) +
int64(w.codegenFreq[16]*2) +
int64(w.codegenFreq[17]*3) +
int64(w.codegenFreq[18]*7)
// Huffman.
w.writeDynamicHeader(numLiterals, numOffsets, numCodegens, eof)
- encoding := w.literalEncoding.codes
+ encoding := w.literalEncoding.codes[:257]
n := w.nbytes
for _, t := range input {
// Bitwriting inlined, ~30% speedup
bits := w.bits
w.bits >>= 48
w.nbits -= 48
- w.bytes[n+0] = byte(bits)
- w.bytes[n+1] = byte(bits >> 8)
- w.bytes[n+2] = byte(bits >> 16)
- w.bytes[n+3] = byte(bits >> 24)
- w.bytes[n+4] = byte(bits >> 32)
- w.bytes[n+5] = byte(bits >> 40)
+ bytes := w.bytes[n : n+6]
+ bytes[0] = byte(bits)
+ bytes[1] = byte(bits >> 8)
+ bytes[2] = byte(bits >> 16)
+ bytes[3] = byte(bits >> 24)
+ bytes[4] = byte(bits >> 32)
+ bytes[5] = byte(bits >> 40)
n += 6
if n < bufferFlushSize {
continue
//
// len(h) must be >= 256, and h's elements must be all zeroes.
func histogram(b []byte, h []int32) {
+ h = h[:256]
for _, t := range b {
h[t]++
}