Skip to content

Commit 2c5d12a

Browse files
committed
[klauspost/deflate-improve-comp] Remove hash7 and use const for long table bytes.
Change-Id: Ia141c7ec888bf51ceb6351d2a1c3f1501c2c4e12
1 parent 374779b commit 2c5d12a

File tree

5 files changed

+24
-28
lines changed

5 files changed

+24
-28
lines changed

src/compress/flate/deflatefast.go

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ func newFastEnc(level int) fastEnc {
3535
const (
3636
tableBits = 15 // Bits used in the table
3737
tableSize = 1 << tableBits // Size of the table
38+
hashLongBytes = 7 // Bytes used for long table hash
3839
baseMatchOffset = 1 // The smallest match offset
3940
baseMatchLength = 3 // The smallest match length per the RFC section 3.2.5
4041
maxMatchOffset = 1 << 15 // The largest match offset
@@ -93,12 +94,6 @@ type tableEntryPrev struct {
9394
Prev tableEntry
9495
}
9596

96-
// hash7 returns the hash of the lowest 7 bytes of u to fit in a hash table with h bits.
97-
// Preferably h should be a constant and should always be <64.
98-
func hash7(u uint64, h uint8) uint32 {
99-
return uint32(((u << (64 - 56)) * prime7bytes) >> ((64 - h) & reg8SizeMask64))
100-
}
101-
10297
// hashLen returns a hash of the lowest mls bytes of with length output bits.
10398
// mls must be >=3 and <=8. Any other value will return hash for 4 bytes.
10499
// length should always be < 32.

src/compress/flate/huffman_bit_writer.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -412,8 +412,9 @@ func (w *huffmanBitWriter) storedSize(in []byte) (int, bool) {
412412
return 0, false
413413
}
414414

415+
// writeCode writes 'c' to the stream.
416+
// Inline manually when performance is critical.
415417
func (w *huffmanBitWriter) writeCode(c hcode) {
416-
// The function does not get inlined if we "& 63" the shift.
417418
w.bits |= c.code64() << (w.nbits & reg8SizeMask64)
418419
w.nbits += c.len()
419420
if w.nbits >= 48 {

src/compress/flate/level4.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ func (e *fastEncL4) Encode(dst *tokens, src []byte) {
8282
var t int32
8383
for {
8484
nextHashS := hashLen(cv, tableBits, hashShortBytes)
85-
nextHashL := hash7(cv, tableBits)
85+
nextHashL := hashLen(cv, tableBits, hashLongBytes)
8686

8787
s = nextS
8888
nextS = s + doEvery + (s-nextEmit)>>skipLog
@@ -106,7 +106,7 @@ func (e *fastEncL4) Encode(dst *tokens, src []byte) {
106106
t = sCandidate.offset - e.cur
107107
if s-t < maxMatchOffset && uint32(cv) == loadLE32(src, t) {
108108
// Found a 4 match...
109-
lCandidate = e.bTable[hash7(next, tableBits)]
109+
lCandidate = e.bTable[hashLen(next, tableBits, hashLongBytes)]
110110

111111
// If the next long is a candidate, check if we should use that instead...
112112
lOff := lCandidate.offset - e.cur
@@ -155,7 +155,7 @@ func (e *fastEncL4) Encode(dst *tokens, src []byte) {
155155
if int(s+8) < len(src) {
156156
cv := loadLE64(src, s)
157157
e.table[hashLen(cv, tableBits, hashShortBytes)] = tableEntry{offset: s + e.cur}
158-
e.bTable[hash7(cv, tableBits)] = tableEntry{offset: s + e.cur}
158+
e.bTable[hashLen(cv, tableBits, hashLongBytes)] = tableEntry{offset: s + e.cur}
159159
}
160160
goto emitRemainder
161161
}
@@ -166,17 +166,17 @@ func (e *fastEncL4) Encode(dst *tokens, src []byte) {
166166
cv := loadLE64(src, i)
167167
t := tableEntry{offset: i + e.cur}
168168
t2 := tableEntry{offset: t.offset + 1}
169-
e.bTable[hash7(cv, tableBits)] = t
170-
e.bTable[hash7(cv>>8, tableBits)] = t2
169+
e.bTable[hashLen(cv, tableBits, hashLongBytes)] = t
170+
e.bTable[hashLen(cv>>8, tableBits, hashLongBytes)] = t2
171171
e.table[hashLen(cv>>8, tableBits, hashShortBytes)] = t2
172172

173173
i += 3
174174
for ; i < s-1; i += 3 {
175175
cv := loadLE64(src, i)
176176
t := tableEntry{offset: i + e.cur}
177177
t2 := tableEntry{offset: t.offset + 1}
178-
e.bTable[hash7(cv, tableBits)] = t
179-
e.bTable[hash7(cv>>8, tableBits)] = t2
178+
e.bTable[hashLen(cv, tableBits, hashLongBytes)] = t
179+
e.bTable[hashLen(cv>>8, tableBits, hashLongBytes)] = t2
180180
e.table[hashLen(cv>>8, tableBits, hashShortBytes)] = t2
181181
}
182182
}
@@ -186,7 +186,7 @@ func (e *fastEncL4) Encode(dst *tokens, src []byte) {
186186
x := loadLE64(src, s-1)
187187
o := e.cur + s - 1
188188
prevHashS := hashLen(x, tableBits, hashShortBytes)
189-
prevHashL := hash7(x, tableBits)
189+
prevHashL := hashLen(x, tableBits, hashLongBytes)
190190
e.table[prevHashS] = tableEntry{offset: o}
191191
e.bTable[prevHashL] = tableEntry{offset: o}
192192
cv = x >> 8

src/compress/flate/level5.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ func (e *fastEncL5) Encode(dst *tokens, src []byte) {
9292
var t int32
9393
for {
9494
nextHashS := hashLen(cv, tableBits, hashShortBytes)
95-
nextHashL := hash7(cv, tableBits)
95+
nextHashL := hashLen(cv, tableBits, hashLongBytes)
9696

9797
s = nextS
9898
nextS = s + doEvery + (s-nextEmit)>>skipLog
@@ -109,7 +109,7 @@ func (e *fastEncL5) Encode(dst *tokens, src []byte) {
109109
eLong.Cur, eLong.Prev = entry, eLong.Cur
110110

111111
nextHashS = hashLen(next, tableBits, hashShortBytes)
112-
nextHashL = hash7(next, tableBits)
112+
nextHashL = hashLen(next, tableBits, hashLongBytes)
113113

114114
t = lCandidate.Cur.offset - e.cur
115115
if s-t < maxMatchOffset {
@@ -196,7 +196,7 @@ func (e *fastEncL5) Encode(dst *tokens, src []byte) {
196196
// The skipped bytes are tested in Extend backwards,
197197
// and still picked up as part of the match if they do.
198198
const skipBeginning = 2
199-
eLong := e.bTable[hash7(loadLE64(src, sAt), tableBits)].Cur.offset
199+
eLong := e.bTable[hashLen(loadLE64(src, sAt), tableBits, hashLongBytes)].Cur.offset
200200
t2 := eLong - e.cur - l + skipBeginning
201201
s2 := s + skipBeginning
202202
off := s2 - t2
@@ -241,13 +241,13 @@ func (e *fastEncL5) Encode(dst *tokens, src []byte) {
241241
cv := loadLE64(src, i)
242242
t := tableEntry{offset: i + e.cur}
243243
e.table[hashLen(cv, tableBits, hashShortBytes)] = t
244-
eLong := &e.bTable[hash7(cv, tableBits)]
244+
eLong := &e.bTable[hashLen(cv, tableBits, hashLongBytes)]
245245
eLong.Cur, eLong.Prev = t, eLong.Cur
246246

247247
// Do an long at i+1
248248
cv >>= 8
249249
t = tableEntry{offset: t.offset + 1}
250-
eLong = &e.bTable[hash7(cv, tableBits)]
250+
eLong = &e.bTable[hashLen(cv, tableBits, hashLongBytes)]
251251
eLong.Cur, eLong.Prev = t, eLong.Cur
252252

253253
// We only have enough bits for a short entry at i+2
@@ -261,7 +261,7 @@ func (e *fastEncL5) Encode(dst *tokens, src []byte) {
261261
cv := loadLE64(src, i)
262262
t := tableEntry{offset: i + e.cur}
263263
t2 := tableEntry{offset: t.offset + 1}
264-
eLong := &e.bTable[hash7(cv, tableBits)]
264+
eLong := &e.bTable[hashLen(cv, tableBits, hashLongBytes)]
265265
eLong.Cur, eLong.Prev = t, eLong.Cur
266266
e.table[hashLen(cv>>8, tableBits, hashShortBytes)] = t2
267267
}
@@ -272,7 +272,7 @@ func (e *fastEncL5) Encode(dst *tokens, src []byte) {
272272
x := loadLE64(src, s-1)
273273
o := e.cur + s - 1
274274
prevHashS := hashLen(x, tableBits, hashShortBytes)
275-
prevHashL := hash7(x, tableBits)
275+
prevHashL := hashLen(x, tableBits, hashLongBytes)
276276
e.table[prevHashS] = tableEntry{offset: o}
277277
eLong := &e.bTable[prevHashL]
278278
eLong.Cur, eLong.Prev = tableEntry{offset: o}, eLong.Cur

src/compress/flate/level6.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ func (e *fastEncL6) Encode(dst *tokens, src []byte) {
9292
var t int32
9393
for {
9494
nextHashS := hashLen(cv, tableBits, hashShortBytes)
95-
nextHashL := hash7(cv, tableBits)
95+
nextHashL := hashLen(cv, tableBits, hashLongBytes)
9696
s = nextS
9797
nextS = s + doEvery + (s-nextEmit)>>skipLog
9898
if nextS > sLimit {
@@ -109,7 +109,7 @@ func (e *fastEncL6) Encode(dst *tokens, src []byte) {
109109

110110
// Calculate hashes of 'next'
111111
nextHashS = hashLen(next, tableBits, hashShortBytes)
112-
nextHashL = hash7(next, tableBits)
112+
nextHashL = hashLen(next, tableBits, hashLongBytes)
113113

114114
t = lCandidate.Cur.offset - e.cur
115115
if s-t < maxMatchOffset {
@@ -216,7 +216,7 @@ func (e *fastEncL6) Encode(dst *tokens, src []byte) {
216216
// The skipped bytes are tested in extend backwards,
217217
// and still picked up as part of the match if they do.
218218
const skipBeginning = 2
219-
eLong := &e.bTable[hash7(loadLE64(src, sAt), tableBits)]
219+
eLong := &e.bTable[hashLen(loadLE64(src, sAt), tableBits, hashLongBytes)]
220220
// Test current
221221
t2 := eLong.Cur.offset - e.cur - l + skipBeginning
222222
s2 := s + skipBeginning
@@ -269,7 +269,7 @@ func (e *fastEncL6) Encode(dst *tokens, src []byte) {
269269
for i := nextS + 1; i < int32(len(src))-8; i += 2 {
270270
cv := loadLE64(src, i)
271271
e.table[hashLen(cv, tableBits, hashShortBytes)] = tableEntry{offset: i + e.cur}
272-
eLong := &e.bTable[hash7(cv, tableBits)]
272+
eLong := &e.bTable[hashLen(cv, tableBits, hashLongBytes)]
273273
eLong.Cur, eLong.Prev = tableEntry{offset: i + e.cur}, eLong.Cur
274274
}
275275
goto emitRemainder
@@ -280,8 +280,8 @@ func (e *fastEncL6) Encode(dst *tokens, src []byte) {
280280
cv := loadLE64(src, i)
281281
t := tableEntry{offset: i + e.cur}
282282
t2 := tableEntry{offset: t.offset + 1}
283-
eLong := &e.bTable[hash7(cv, tableBits)]
284-
eLong2 := &e.bTable[hash7(cv>>8, tableBits)]
283+
eLong := &e.bTable[hashLen(cv, tableBits, hashLongBytes)]
284+
eLong2 := &e.bTable[hashLen(cv>>8, tableBits, hashLongBytes)]
285285
e.table[hashLen(cv, tableBits, hashShortBytes)] = t
286286
eLong.Cur, eLong.Prev = t, eLong.Cur
287287
eLong2.Cur, eLong2.Prev = t2, eLong2.Cur

0 commit comments

Comments
 (0)