Skip to content

Commit

Permalink
huff0/zstd: Fix tablelog reuse (#203)
Browse files Browse the repository at this point in the history
Fix tablelog reuse.
  • Loading branch information
klauspost authored Jan 5, 2020
1 parent dca0232 commit f61bac3
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 11 deletions.
30 changes: 28 additions & 2 deletions huff0/compress.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,12 @@ func compress(in []byte, s *Scratch, compressor func(src []byte) ([]byte, error)

if s.Reuse == ReusePolicyPrefer && canReuse {
keepTable := s.cTable
keepTL := s.actualTableLog
s.cTable = s.prevTable
s.actualTableLog = s.prevTableLog
s.Out, err = compressor(in)
s.cTable = keepTable
s.actualTableLog = keepTL
if err == nil && len(s.Out) < wantSize {
s.OutData = s.Out
return s.Out, true, nil
Expand All @@ -108,9 +111,15 @@ func compress(in []byte, s *Scratch, compressor func(src []byte) ([]byte, error)
if oldSize <= hSize+newSize || hSize+12 >= wantSize {
// Retain cTable even if we re-use.
keepTable := s.cTable
keepTL := s.actualTableLog

s.cTable = s.prevTable
s.actualTableLog = s.prevTableLog
s.Out, err = compressor(in)

// Restore ctable.
s.cTable = keepTable
s.actualTableLog = keepTL
if err != nil {
return nil, false, err
}
Expand Down Expand Up @@ -141,7 +150,7 @@ func compress(in []byte, s *Scratch, compressor func(src []byte) ([]byte, error)
return nil, false, ErrIncompressible
}
// Move current table into previous.
s.prevTable, s.cTable = s.cTable, s.prevTable[:0]
s.prevTable, s.prevTableLog, s.cTable = s.cTable, s.actualTableLog, s.prevTable[:0]
s.OutData = s.Out[len(s.OutTable):]
return s.Out, false, nil
}
Expand Down Expand Up @@ -316,9 +325,26 @@ func (s *Scratch) canUseTable(c cTable) bool {
return true
}

func (s *Scratch) validateTable(c cTable) bool {
if len(c) < int(s.symbolLen) {
return false
}
for i, v := range s.count[:s.symbolLen] {
if v != 0 {
if c[i].nBits == 0 {
return false
}
if c[i].nBits > s.actualTableLog {
return false
}
}
}
return true
}

// minTableLog provides the minimum logSize to safely represent a distribution.
func (s *Scratch) minTableLog() uint8 {
minBitsSrc := highBit32(uint32(s.br.remain()-1)) + 1
minBitsSrc := highBit32(uint32(s.br.remain())) + 1
minBitsSymbols := highBit32(uint32(s.symbolLen-1)) + 2
if minBitsSrc < minBitsSymbols {
return uint8(minBitsSrc)
Expand Down
1 change: 1 addition & 0 deletions huff0/huff0.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ type Scratch struct {
maxCount int // count of the most probable symbol
clearCount bool // clear count
actualTableLog uint8 // Selected tablelog.
prevTableLog uint8 // Tablelog for previous table
prevTable cTable // Table used for previous compression.
cTable cTable // compression table
dt dTable // decompression table
Expand Down
8 changes: 0 additions & 8 deletions zstd/blockenc.go
Original file line number Diff line number Diff line change
Expand Up @@ -338,18 +338,10 @@ func (b *blockEnc) encodeLits(raw bool) error {
if len(b.literals) >= 1024 {
// Use 4 Streams.
out, reUsed, err = huff0.Compress4X(b.literals, b.litEnc)
if len(out) > len(b.literals)-len(b.literals)>>4 {
// Bail out of compression is too little.
err = huff0.ErrIncompressible
}
} else if len(b.literals) > 32 {
// Use 1 stream
single = true
out, reUsed, err = huff0.Compress1X(b.literals, b.litEnc)
if len(out) > len(b.literals)-len(b.literals)>>4 {
// Bail out of compression is too little.
err = huff0.ErrIncompressible
}
} else {
err = huff0.ErrIncompressible
}
Expand Down
2 changes: 1 addition & 1 deletion zstd/encoder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func TestEncoder_EncodeAllSimple(t *testing.T) {
in = append(in, in...)
for level := EncoderLevel(speedNotSet + 1); level < speedLast; level++ {
t.Run(level.String(), func(t *testing.T) {
e, err := NewWriter(nil, WithEncoderLevel(level))
e, err := NewWriter(nil, WithEncoderLevel(level), WithEncoderConcurrency(2), WithWindowSize(128<<10), WithZeroFrames(true))
if err != nil {
t.Fatal(err)
}
Expand Down
Binary file modified zstd/testdata/comp-crashers.zip
Binary file not shown.

0 comments on commit f61bac3

Please sign in to comment.