package flate
import (
"fmt"
"github.com/klauspost/compress/internal/le"
)
type fastEncL1 struct {
fastGen
table [tableSize ]tableEntry
}
func (e *fastEncL1 ) Encode (dst *tokens , src []byte ) {
const (
inputMargin = 12 - 1
minNonLiteralBlockSize = 1 + 1 + inputMargin
hashBytes = 5
)
if debugDeflate && e .cur < 0 {
panic (fmt .Sprint ("e.cur < 0: " , e .cur ))
}
for e .cur >= bufferReset {
if len (e .hist ) == 0 {
for i := range e .table [:] {
e .table [i ] = tableEntry {}
}
e .cur = maxMatchOffset
break
}
minOff := e .cur + int32 (len (e .hist )) - maxMatchOffset
for i := range e .table [:] {
v := e .table [i ].offset
if v <= minOff {
v = 0
} else {
v = v - e .cur + maxMatchOffset
}
e .table [i ].offset = v
}
e .cur = maxMatchOffset
}
s := e .addBlock (src )
if len (src ) < minNonLiteralBlockSize {
dst .n = uint16 (len (src ))
return
}
src = e .hist
nextEmit := s
sLimit := int32 (len (src ) - inputMargin )
cv := load6432 (src , s )
for {
const skipLog = 5
const doEvery = 2
nextS := s
var candidate tableEntry
var t int32
for {
nextHash := hashLen (cv , tableBits , hashBytes )
candidate = e .table [nextHash ]
nextS = s + doEvery + (s -nextEmit )>>skipLog
if nextS > sLimit {
goto emitRemainder
}
now := load6432 (src , nextS )
e .table [nextHash ] = tableEntry {offset : s + e .cur }
nextHash = hashLen (now , tableBits , hashBytes )
t = candidate .offset - e .cur
if s -t < maxMatchOffset && uint32 (cv ) == load3232 (src , t ) {
e .table [nextHash ] = tableEntry {offset : nextS + e .cur }
break
}
cv = now
s = nextS
nextS ++
candidate = e .table [nextHash ]
now >>= 8
e .table [nextHash ] = tableEntry {offset : s + e .cur }
t = candidate .offset - e .cur
if s -t < maxMatchOffset && uint32 (cv ) == load3232 (src , t ) {
e .table [nextHash ] = tableEntry {offset : nextS + e .cur }
break
}
cv = now
s = nextS
}
for {
l := e .matchlenLong (int (s +4 ), int (t +4 ), src ) + 4
for t > 0 && s > nextEmit && le .Load8 (src , t -1 ) == le .Load8 (src , s -1 ) {
s --
t --
l ++
}
if nextEmit < s {
if false {
emitLiteral (dst , src [nextEmit :s ])
} else {
for _ , v := range src [nextEmit :s ] {
dst .tokens [dst .n ] = token (v )
dst .litHist [v ]++
dst .n ++
}
}
}
if false {
dst .AddMatchLong (l , uint32 (s -t -baseMatchOffset ))
} else {
xoffset := uint32 (s - t - baseMatchOffset )
xlength := l
oc := offsetCode (xoffset )
xoffset |= oc << 16
for xlength > 0 {
xl := xlength
if xl > 258 {
if xl > 258 +baseMatchLength {
xl = 258
} else {
xl = 258 - baseMatchLength
}
}
xlength -= xl
xl -= baseMatchLength
dst .extraHist [lengthCodes1 [uint8 (xl )]]++
dst .offHist [oc ]++
dst .tokens [dst .n ] = token (matchType | uint32 (xl )<<lengthShift | xoffset )
dst .n ++
}
}
s += l
nextEmit = s
if nextS >= s {
s = nextS + 1
}
if s >= sLimit {
if int (s +l +8 ) < len (src ) {
cv := load6432 (src , s )
e .table [hashLen (cv , tableBits , hashBytes )] = tableEntry {offset : s + e .cur }
}
goto emitRemainder
}
x := load6432 (src , s -2 )
o := e .cur + s - 2
prevHash := hashLen (x , tableBits , hashBytes )
e .table [prevHash ] = tableEntry {offset : o }
x >>= 16
currHash := hashLen (x , tableBits , hashBytes )
candidate = e .table [currHash ]
e .table [currHash ] = tableEntry {offset : o + 2 }
t = candidate .offset - e .cur
if s -t > maxMatchOffset || uint32 (x ) != load3232 (src , t ) {
cv = x >> 8
s ++
break
}
}
}
emitRemainder :
if int (nextEmit ) < len (src ) {
if dst .n == 0 {
return
}
emitLiteral (dst , src [nextEmit :])
}
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .