package  flate 
 
import  "fmt"  
 
type  fastEncL4 struct  { 
	fastGen  
	table  [tableSize ]tableEntry  
	bTable [tableSize ]tableEntry  
} 
 
func  (e  *fastEncL4 ) Encode (dst  *tokens , src  []byte ) { 
	const  ( 
		inputMargin             = 12  - 1  
		minNonLiteralBlockSize  = 1  + 1  + inputMargin  
		hashShortBytes          = 4  
	) 
	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 {} 
			} 
			for  i  := range  e .bTable [:] { 
				e .bTable [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  
		} 
		for  i  := range  e .bTable [:] { 
			v  := e .bTable [i ].offset  
			if  v  <= minOff  { 
				v  = 0  
			} else  { 
				v  = v  - e .cur  + maxMatchOffset  
			} 
			e .bTable [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  = 6  
		const  doEvery  = 1  
 
		nextS  := s  
		var  t  int32  
		for  { 
			nextHashS  := hashLen (cv , tableBits , hashShortBytes ) 
			nextHashL  := hash7 (cv , tableBits ) 
 
			s  = nextS  
			nextS  = s  + doEvery  + (s -nextEmit )>>skipLog  
			if  nextS  > sLimit  { 
				goto  emitRemainder  
			} 
			 
			sCandidate  := e .table [nextHashS ] 
			lCandidate  := e .bTable [nextHashL ] 
			next  := load6432 (src , nextS ) 
			entry  := tableEntry {offset : s  + e .cur } 
			e .table [nextHashS ] = entry  
			e .bTable [nextHashL ] = entry  
 
			t  = lCandidate .offset  - e .cur  
			if  s -t  < maxMatchOffset  && uint32 (cv ) == load3232 (src , lCandidate .offset -e .cur ) { 
				 
				break  
			} 
 
			t  = sCandidate .offset  - e .cur  
			if  s -t  < maxMatchOffset  && uint32 (cv ) == load3232 (src , sCandidate .offset -e .cur ) { 
				 
				lCandidate  = e .bTable [hash7 (next , tableBits )] 
 
				 
				lOff  := nextS  - (lCandidate .offset  - e .cur ) 
				if  lOff  < maxMatchOffset  && load3232 (src , lCandidate .offset -e .cur ) == uint32 (next ) { 
					l1 , l2  := matchLen (src [s +4 :], src [t +4 :]), matchLen (src [nextS +4 :], src [nextS -lOff +4 :]) 
					if  l2  > l1  { 
						s  = nextS  
						t  = lCandidate .offset  - e .cur  
					} 
				} 
				break  
			} 
			cv  = next  
		} 
 
		 
 
 
 
		 
		l  := e .matchlenLong (s +4 , t +4 , src ) + 4  
 
		 
		for  t  > 0  && s  > nextEmit  && src [t -1 ] == 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  debugDeflate  { 
			if  t  >= s  { 
				panic ("s-t" ) 
			} 
			if  (s  - t ) > maxMatchOffset  { 
				panic (fmt .Sprintln ("mmo" , t )) 
			} 
			if  l  < baseMatchLength  { 
				panic ("bml" ) 
			} 
		} 
 
		dst .AddMatchLong (l , uint32 (s -t -baseMatchOffset )) 
		s  += l  
		nextEmit  = s  
		if  nextS  >= s  { 
			s  = nextS  + 1  
		} 
 
		if  s  >= sLimit  { 
			 
			if  int (s +8 ) < len (src ) { 
				cv  := load6432 (src , s ) 
				e .table [hashLen (cv , tableBits , hashShortBytes )] = tableEntry {offset : s  + e .cur } 
				e .bTable [hash7 (cv , tableBits )] = tableEntry {offset : s  + e .cur } 
			} 
			goto  emitRemainder  
		} 
 
		 
		if  true  { 
			i  := nextS  
			if  i  < s -1  { 
				cv  := load6432 (src , i ) 
				t  := tableEntry {offset : i  + e .cur } 
				t2  := tableEntry {offset : t .offset  + 1 } 
				e .bTable [hash7 (cv , tableBits )] = t  
				e .bTable [hash7 (cv >>8 , tableBits )] = t2  
				e .table [hashLen (cv >>8 , tableBits , hashShortBytes )] = t2  
 
				i  += 3  
				for  ; i  < s -1 ; i  += 3  { 
					cv  := load6432 (src , i ) 
					t  := tableEntry {offset : i  + e .cur } 
					t2  := tableEntry {offset : t .offset  + 1 } 
					e .bTable [hash7 (cv , tableBits )] = t  
					e .bTable [hash7 (cv >>8 , tableBits )] = t2  
					e .table [hashLen (cv >>8 , tableBits , hashShortBytes )] = t2  
				} 
			} 
		} 
 
		 
 
		x  := load6432 (src , s -1 ) 
		o  := e .cur  + s  - 1  
		prevHashS  := hashLen (x , tableBits , hashShortBytes ) 
		prevHashL  := hash7 (x , tableBits ) 
		e .table [prevHashS ] = tableEntry {offset : o } 
		e .bTable [prevHashL ] = tableEntry {offset : o } 
		cv  = x  >> 8  
	} 
 
emitRemainder : 
	if  int (nextEmit ) < len (src ) { 
		 
		if  dst .n  == 0  { 
			return  
		} 
 
		emitLiteral (dst , src [nextEmit :]) 
	} 
} 
  
The pages are generated with Golds   v0.6.7 . (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 @Go100and1  (reachable from the left QR code) to get the latest news of Golds .