コード例 #1
0
ファイル: distcodec.go プロジェクト: pmezard/xz
// Encode encodes the distance using the parameter l. Dist can have values from
// the full range of uint32 values. To get the distance offset the actual match
// distance has to be decreased by 1. A distance offset of 0xffffffff (eos)
// indicates the end of the stream.
func (dc *distCodec) Encode(e *rangeEncoder, dist uint32, l uint32) (err error) {
	// Compute the posSlot using nlz32
	var posSlot uint32
	var bits uint32
	if dist < startPosModel {
		posSlot = dist
	} else {
		bits = uint32(30 - u32.NLZ(dist))
		posSlot = startPosModel - 2 + (bits << 1)
		posSlot += (dist >> uint(bits)) & 1
	}

	if err = dc.posSlotCodecs[lenState(l)].Encode(e, posSlot); err != nil {
		return
	}

	switch {
	case posSlot < startPosModel:
		return nil
	case posSlot < endPosModel:
		tc := &dc.posModel[posSlot-startPosModel]
		return tc.Encode(dist, e)
	}
	dic := directCodec(bits - alignBits)
	if err = dic.Encode(e, dist>>alignBits); err != nil {
		return
	}
	return dc.alignCodec.Encode(dist, e)
}
コード例 #2
0
ファイル: hashtable.go プロジェクト: pmezard/xz
// hashTableExponent derives the hash table exponent from the history length.
func hashTableExponent(n uint32) int {
	e := 30 - u32.NLZ(n)
	switch {
	case e < minTableExponent:
		e = minTableExponent
	case e > maxTableExponent:
		e = maxTableExponent
	}
	return e
}
コード例 #3
0
ファイル: distcodec.go プロジェクト: pmezard/xz
// distBits returns the number of bits required to encode dist.
func distBits(dist uint32) int {
	if dist < startPosModel {
		return 6
	}
	// slot s > 3, dist d
	// s = 2(bits(d)-1) + bit(d, bits(d)-2)
	// s>>1 = bits(d)-1
	// bits(d) = 32-nlz32(d)
	// s>>1=31-nlz32(d)
	// n = 5 + (s>>1) = 36 - nlz32(d)
	return 36 - u32.NLZ(dist)
}