influxdb/pkg/encoding/simple8b/encoding.go

1032 lines
22 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

// Package simple8b implements the 64bit integer encoding algoritm as published
// by Ann and Moffat in "Index compression using 64-bit words", Softw. Pract. Exper. 2010; 40:131147
//
// It is capable of encoding multiple integers with values betweeen 0 and to 1^60 -1, in a single word.
//
// Imported from github.com/jwilder/encoding
package simple8b
// Simple8b is 64bit word-sized encoder that packs multiple integers into a single word using
// a 4 bit selector values and up to 60 bits for the remaining values. Integers are encoded using
// the following table:
//
// ┌──────────────┬─────────────────────────────────────────────────────────────┐
// │ Selector │ 0 1 2 3 4 5 6 7 8 9 0 11 12 13 14 15│
// ├──────────────┼─────────────────────────────────────────────────────────────┤
// │ Bits │ 0 0 1 2 3 4 5 6 7 8 10 12 15 20 30 60│
// ├──────────────┼─────────────────────────────────────────────────────────────┤
// │ N │ 240 120 60 30 20 15 12 10 8 7 6 5 4 3 2 1│
// ├──────────────┼─────────────────────────────────────────────────────────────┤
// │ Wasted Bits│ 60 60 0 0 0 0 12 0 4 4 0 0 0 0 0 0│
// └──────────────┴─────────────────────────────────────────────────────────────┘
//
// For example, when the number of values can be encoded using 4 bits, selected 5 is encoded in the
// 4 most significant bits followed by 15 values encoded used 4 bits each in the remaing 60 bits.
import (
"encoding/binary"
"errors"
"fmt"
"unsafe"
)
const MaxValue = (1 << 60) - 1
// Encoder converts a stream of unsigned 64bit integers to a compressed byte slice.
type Encoder struct {
// most recently written integers that have not been flushed
buf []uint64
// index in buf of the head of the buf
h int
// index in buf of the tail of the buf
t int
// index into bytes of written bytes
bp int
// current bytes written and flushed
bytes []byte
b []byte
}
// NewEncoder returns an Encoder able to convert uint64s to compressed byte slices
func NewEncoder() *Encoder {
return &Encoder{
buf: make([]uint64, 240),
b: make([]byte, 8),
bytes: make([]byte, 128),
}
}
func (e *Encoder) SetValues(v []uint64) {
e.buf = v
e.t = len(v)
e.h = 0
e.bytes = e.bytes[:0]
}
func (e *Encoder) Reset() {
e.t = 0
e.h = 0
e.bp = 0
e.buf = e.buf[:240]
e.b = e.b[:8]
e.bytes = e.bytes[:128]
}
func (e *Encoder) Write(v uint64) error {
if e.t >= len(e.buf) {
if err := e.flush(); err != nil {
return err
}
}
// The buf is full but there is space at the front, just shift
// the values down for now. TODO: use ring buffer
if e.t >= len(e.buf) {
copy(e.buf, e.buf[e.h:])
e.t -= e.h
e.h = 0
}
e.buf[e.t] = v
e.t += 1
return nil
}
func (e *Encoder) flush() error {
if e.t == 0 {
return nil
}
// encode as many values into one as we can
encoded, n, err := Encode(e.buf[e.h:e.t])
if err != nil {
return err
}
binary.BigEndian.PutUint64(e.b, encoded)
if e.bp+8 > len(e.bytes) {
e.bytes = append(e.bytes, e.b...)
e.bp = len(e.bytes)
} else {
copy(e.bytes[e.bp:e.bp+8], e.b)
e.bp += 8
}
// Move the head forward since we encoded those values
e.h += n
// If we encoded them all, reset the head/tail pointers to the beginning
if e.h == e.t {
e.h = 0
e.t = 0
}
return nil
}
func (e *Encoder) Bytes() ([]byte, error) {
for e.t > 0 {
if err := e.flush(); err != nil {
return nil, err
}
}
return e.bytes[:e.bp], nil
}
// Decoder converts a compressed byte slice to a stream of unsigned 64bit integers.
type Decoder struct {
bytes []byte
buf [240]uint64
i int
n int
}
// NewDecoder returns a Decoder from a byte slice
func NewDecoder(b []byte) *Decoder {
return &Decoder{
bytes: b,
}
}
// Next returns true if there are remaining values to be read. Successive
// calls to Next advance the current element pointer.
func (d *Decoder) Next() bool {
d.i += 1
if d.i >= d.n {
d.read()
}
return len(d.bytes) >= 8 || (d.i >= 0 && d.i < d.n)
}
func (d *Decoder) SetBytes(b []byte) {
d.bytes = b
d.i = 0
d.n = 0
}
// Read returns the current value. Successive calls to Read return the same
// value.
func (d *Decoder) Read() uint64 {
v := d.buf[d.i]
return v
}
func (d *Decoder) read() {
if len(d.bytes) < 8 {
return
}
v := binary.BigEndian.Uint64(d.bytes[:8])
d.bytes = d.bytes[8:]
d.n, _ = Decode(&d.buf, v)
d.i = 0
}
type packing struct {
n, bit int
unpack func(uint64, *[240]uint64)
pack func([]uint64) uint64
}
var selector [16]packing = [16]packing{
{240, 0, unpack240, pack240},
{120, 0, unpack120, pack120},
{60, 1, unpack60, pack60},
{30, 2, unpack30, pack30},
{20, 3, unpack20, pack20},
{15, 4, unpack15, pack15},
{12, 5, unpack12, pack12},
{10, 6, unpack10, pack10},
{8, 7, unpack8, pack8},
{7, 8, unpack7, pack7},
{6, 10, unpack6, pack6},
{5, 12, unpack5, pack5},
{4, 15, unpack4, pack4},
{3, 20, unpack3, pack3},
{2, 30, unpack2, pack2},
{1, 60, unpack1, pack1},
}
// Count returns the number of integers encoded in the byte slice
func CountBytes(b []byte) (int, error) {
var count int
for len(b) >= 8 {
v := binary.BigEndian.Uint64(b[:8])
b = b[8:]
sel := v >> 60
if sel >= 16 {
return 0, fmt.Errorf("invalid selector value: %v", sel)
}
count += selector[sel].n
}
if len(b) > 0 {
return 0, fmt.Errorf("invalid slice len remaining: %v", len(b))
}
return count, nil
}
// Count returns the number of integers encoded within an uint64
func Count(v uint64) (int, error) {
sel := v >> 60
if sel >= 16 {
return 0, fmt.Errorf("invalid selector value: %v", sel)
}
return selector[sel].n, nil
}
func ForEach(b []byte, fn func(v uint64) bool) error {
for len(b) >= 8 {
v := binary.BigEndian.Uint64(b[:8])
b = b[8:]
sel := v >> 60
if sel >= 16 {
return fmt.Errorf("invalid selector value: %v", sel)
}
n := selector[sel].n
bits := uint(selector[sel].bit)
mask := uint64(^(int64(^0) << bits))
for i := 0; i < n; i++ {
val := v & mask
if !fn(val) {
return nil
}
v = v >> bits
}
}
return nil
}
func CountBytesBetween(b []byte, min, max uint64) (int, error) {
var count int
for len(b) >= 8 {
v := binary.BigEndian.Uint64(b[:8])
b = b[8:]
sel := v >> 60
if sel >= 16 {
return 0, fmt.Errorf("invalid selector value: %v", sel)
}
// If the max value that could be encoded by the uint64 is less than the min
// skip the whole thing.
maxValue := uint64((1 << uint64(selector[sel].bit)) - 1)
if maxValue < min {
continue
}
mask := uint64(^(int64(^0) << uint(selector[sel].bit)))
for i := 0; i < selector[sel].n; i++ {
val := v & mask
if val >= min && val < max {
count++
} else if val > max {
break
}
v = v >> uint(selector[sel].bit)
}
}
if len(b) > 0 {
return 0, fmt.Errorf("invalid slice len remaining: %v", len(b))
}
return count, nil
}
// Encode packs as many values into a single uint64. It returns the packed
// uint64, how many values from src were packed, or an error if the values exceed
// the maximum value range.
func Encode(src []uint64) (value uint64, n int, err error) {
if canPack(src, 240, 0) {
return uint64(0), 240, nil
} else if canPack(src, 120, 0) {
return 1 << 60, 120, nil
} else if canPack(src, 60, 1) {
return pack60(src[:60]), 60, nil
} else if canPack(src, 30, 2) {
return pack30(src[:30]), 30, nil
} else if canPack(src, 20, 3) {
return pack20(src[:20]), 20, nil
} else if canPack(src, 15, 4) {
return pack15(src[:15]), 15, nil
} else if canPack(src, 12, 5) {
return pack12(src[:12]), 12, nil
} else if canPack(src, 10, 6) {
return pack10(src[:10]), 10, nil
} else if canPack(src, 8, 7) {
return pack8(src[:8]), 8, nil
} else if canPack(src, 7, 8) {
return pack7(src[:7]), 7, nil
} else if canPack(src, 6, 10) {
return pack6(src[:6]), 6, nil
} else if canPack(src, 5, 12) {
return pack5(src[:5]), 5, nil
} else if canPack(src, 4, 15) {
return pack4(src[:4]), 4, nil
} else if canPack(src, 3, 20) {
return pack3(src[:3]), 3, nil
} else if canPack(src, 2, 30) {
return pack2(src[:2]), 2, nil
} else if canPack(src, 1, 60) {
return pack1(src[:1]), 1, nil
} else {
if len(src) > 0 {
return 0, 0, fmt.Errorf("value out of bounds: %v", src)
}
return 0, 0, nil
}
}
const (
S8B_BIT_SIZE = 60
)
var (
numBits = [...][2]byte{
// { number of values, max bits per value }
{60, 1},
{30, 2},
{20, 3},
{15, 4},
{12, 5},
{10, 6},
{8, 7},
{7, 8},
{6, 10},
{5, 12},
{4, 15},
{3, 20},
{2, 30},
{1, 60},
}
ErrValueOutOfBounds = errors.New("value out of bounds")
)
// Encode returns a packed slice of the values from src. If a value is over
// 1 << 60, an error is returned. The input src is modified to avoid extra
// allocations. If you need to re-use, use a copy.
func EncodeAll(src []uint64) ([]uint64, error) {
i := 0
// Re-use the input slice and write encoded values back in place
dst := src
j := 0
NEXTVALUE:
for i < len(src) {
remaining := src[i:]
// try to pack run of 240 or 120 1s
if len(remaining) >= 120 {
// Invariant: len(a) is fixed to 120 or 240 values
var a []uint64
if len(remaining) >= 240 {
a = remaining[:240]
} else {
a = remaining[:120]
}
// search for the longest sequence of 1s in a
// Postcondition: k equals the index of the last 1 or -1
k := 0
for k = range a {
if a[k] != 1 {
k--
break
}
}
v := uint64(0)
switch {
case k == 239:
// 240 1s
i += 240
case k >= 119:
// at least 120 1s
v = 1 << 60
i += 120
default:
goto CODES
}
dst[j] = v
j++
continue
}
CODES:
for code := range numBits {
intN := int(numBits[code][0])
bitN := numBits[code][1]
if intN > len(remaining) {
continue
}
maxVal := uint64(1 << (bitN & 0x3f))
val := uint64(code+2) << S8B_BIT_SIZE
for k, inV := range remaining {
if k < intN {
if inV >= maxVal {
continue CODES
}
val |= inV << ((byte(k) * bitN) & 0x3f)
} else {
break
}
}
dst[j] = val
j += 1
i += intN
continue NEXTVALUE
}
return nil, ErrValueOutOfBounds
}
return dst[:j], nil
}
func Decode(dst *[240]uint64, v uint64) (n int, err error) {
sel := v >> 60
if sel >= 16 {
return 0, fmt.Errorf("invalid selector value: %b", sel)
}
selector[sel].unpack(v, dst)
return selector[sel].n, nil
}
// Decode writes the uncompressed values from src to dst. It returns the number
// of values written or an error.
func DecodeAll(dst, src []uint64) (value int, err error) {
j := 0
for _, v := range src {
sel := (v >> 60) & 0xf
selector[sel].unpack(v, (*[240]uint64)(unsafe.Pointer(&dst[j])))
j += selector[sel].n
}
return j, nil
}
// DecodeBytesBigEndian writes the compressed, big-endian values from src to dst. It returns the number
// of values written or an error.
func DecodeBytesBigEndian(dst []uint64, src []byte) (value int, err error) {
if len(src)&7 != 0 {
return 0, errors.New("src length is not multiple of 8")
}
i := 0
j := 0
for i < len(src) {
v := binary.BigEndian.Uint64(src[i:])
sel := (v >> 60) & 0xf
selector[sel].unpack(v, (*[240]uint64)(unsafe.Pointer(&dst[j])))
j += selector[sel].n
i += 8
}
return j, nil
}
// canPack returs true if n elements from in can be stored using bits per element
func canPack(src []uint64, n, bits int) bool {
if len(src) < n {
return false
}
end := len(src)
if n < end {
end = n
}
// Selector 0,1 are special and use 0 bits to encode runs of 1's
if bits == 0 {
for _, v := range src {
if v != 1 {
return false
}
}
return true
}
max := uint64((1 << uint64(bits)) - 1)
for i := 0; i < end; i++ {
if src[i] > max {
return false
}
}
return true
}
// pack240 packs 240 ones from in using 1 bit each
func pack240(src []uint64) uint64 {
return 0
}
// pack120 packs 120 ones from in using 1 bit each
func pack120(src []uint64) uint64 {
return 0
}
// pack60 packs 60 values from in using 1 bit each
func pack60(src []uint64) uint64 {
return 2<<60 |
src[0] |
src[1]<<1 |
src[2]<<2 |
src[3]<<3 |
src[4]<<4 |
src[5]<<5 |
src[6]<<6 |
src[7]<<7 |
src[8]<<8 |
src[9]<<9 |
src[10]<<10 |
src[11]<<11 |
src[12]<<12 |
src[13]<<13 |
src[14]<<14 |
src[15]<<15 |
src[16]<<16 |
src[17]<<17 |
src[18]<<18 |
src[19]<<19 |
src[20]<<20 |
src[21]<<21 |
src[22]<<22 |
src[23]<<23 |
src[24]<<24 |
src[25]<<25 |
src[26]<<26 |
src[27]<<27 |
src[28]<<28 |
src[29]<<29 |
src[30]<<30 |
src[31]<<31 |
src[32]<<32 |
src[33]<<33 |
src[34]<<34 |
src[35]<<35 |
src[36]<<36 |
src[37]<<37 |
src[38]<<38 |
src[39]<<39 |
src[40]<<40 |
src[41]<<41 |
src[42]<<42 |
src[43]<<43 |
src[44]<<44 |
src[45]<<45 |
src[46]<<46 |
src[47]<<47 |
src[48]<<48 |
src[49]<<49 |
src[50]<<50 |
src[51]<<51 |
src[52]<<52 |
src[53]<<53 |
src[54]<<54 |
src[55]<<55 |
src[56]<<56 |
src[57]<<57 |
src[58]<<58 |
src[59]<<59
}
// pack30 packs 30 values from in using 2 bits each
func pack30(src []uint64) uint64 {
return 3<<60 |
src[0] |
src[1]<<2 |
src[2]<<4 |
src[3]<<6 |
src[4]<<8 |
src[5]<<10 |
src[6]<<12 |
src[7]<<14 |
src[8]<<16 |
src[9]<<18 |
src[10]<<20 |
src[11]<<22 |
src[12]<<24 |
src[13]<<26 |
src[14]<<28 |
src[15]<<30 |
src[16]<<32 |
src[17]<<34 |
src[18]<<36 |
src[19]<<38 |
src[20]<<40 |
src[21]<<42 |
src[22]<<44 |
src[23]<<46 |
src[24]<<48 |
src[25]<<50 |
src[26]<<52 |
src[27]<<54 |
src[28]<<56 |
src[29]<<58
}
// pack20 packs 20 values from in using 3 bits each
func pack20(src []uint64) uint64 {
return 4<<60 |
src[0] |
src[1]<<3 |
src[2]<<6 |
src[3]<<9 |
src[4]<<12 |
src[5]<<15 |
src[6]<<18 |
src[7]<<21 |
src[8]<<24 |
src[9]<<27 |
src[10]<<30 |
src[11]<<33 |
src[12]<<36 |
src[13]<<39 |
src[14]<<42 |
src[15]<<45 |
src[16]<<48 |
src[17]<<51 |
src[18]<<54 |
src[19]<<57
}
// pack15 packs 15 values from in using 3 bits each
func pack15(src []uint64) uint64 {
return 5<<60 |
src[0] |
src[1]<<4 |
src[2]<<8 |
src[3]<<12 |
src[4]<<16 |
src[5]<<20 |
src[6]<<24 |
src[7]<<28 |
src[8]<<32 |
src[9]<<36 |
src[10]<<40 |
src[11]<<44 |
src[12]<<48 |
src[13]<<52 |
src[14]<<56
}
// pack12 packs 12 values from in using 5 bits each
func pack12(src []uint64) uint64 {
return 6<<60 |
src[0] |
src[1]<<5 |
src[2]<<10 |
src[3]<<15 |
src[4]<<20 |
src[5]<<25 |
src[6]<<30 |
src[7]<<35 |
src[8]<<40 |
src[9]<<45 |
src[10]<<50 |
src[11]<<55
}
// pack10 packs 10 values from in using 6 bits each
func pack10(src []uint64) uint64 {
return 7<<60 |
src[0] |
src[1]<<6 |
src[2]<<12 |
src[3]<<18 |
src[4]<<24 |
src[5]<<30 |
src[6]<<36 |
src[7]<<42 |
src[8]<<48 |
src[9]<<54
}
// pack8 packs 8 values from in using 7 bits each
func pack8(src []uint64) uint64 {
return 8<<60 |
src[0] |
src[1]<<7 |
src[2]<<14 |
src[3]<<21 |
src[4]<<28 |
src[5]<<35 |
src[6]<<42 |
src[7]<<49
}
// pack7 packs 7 values from in using 8 bits each
func pack7(src []uint64) uint64 {
return 9<<60 |
src[0] |
src[1]<<8 |
src[2]<<16 |
src[3]<<24 |
src[4]<<32 |
src[5]<<40 |
src[6]<<48
}
// pack6 packs 6 values from in using 10 bits each
func pack6(src []uint64) uint64 {
return 10<<60 |
src[0] |
src[1]<<10 |
src[2]<<20 |
src[3]<<30 |
src[4]<<40 |
src[5]<<50
}
// pack5 packs 5 values from in using 12 bits each
func pack5(src []uint64) uint64 {
return 11<<60 |
src[0] |
src[1]<<12 |
src[2]<<24 |
src[3]<<36 |
src[4]<<48
}
// pack4 packs 4 values from in using 15 bits each
func pack4(src []uint64) uint64 {
return 12<<60 |
src[0] |
src[1]<<15 |
src[2]<<30 |
src[3]<<45
}
// pack3 packs 3 values from in using 20 bits each
func pack3(src []uint64) uint64 {
return 13<<60 |
src[0] |
src[1]<<20 |
src[2]<<40
}
// pack2 packs 2 values from in using 30 bits each
func pack2(src []uint64) uint64 {
return 14<<60 |
src[0] |
src[1]<<30
}
// pack1 packs 1 values from in using 60 bits each
func pack1(src []uint64) uint64 {
return 15<<60 |
src[0]
}
func unpack240(v uint64, dst *[240]uint64) {
for i := range dst {
dst[i] = 1
}
}
func unpack120(v uint64, dst *[240]uint64) {
for i := range dst[:120] {
dst[i] = 1
}
}
func unpack60(v uint64, dst *[240]uint64) {
dst[0] = v & 1
dst[1] = (v >> 1) & 1
dst[2] = (v >> 2) & 1
dst[3] = (v >> 3) & 1
dst[4] = (v >> 4) & 1
dst[5] = (v >> 5) & 1
dst[6] = (v >> 6) & 1
dst[7] = (v >> 7) & 1
dst[8] = (v >> 8) & 1
dst[9] = (v >> 9) & 1
dst[10] = (v >> 10) & 1
dst[11] = (v >> 11) & 1
dst[12] = (v >> 12) & 1
dst[13] = (v >> 13) & 1
dst[14] = (v >> 14) & 1
dst[15] = (v >> 15) & 1
dst[16] = (v >> 16) & 1
dst[17] = (v >> 17) & 1
dst[18] = (v >> 18) & 1
dst[19] = (v >> 19) & 1
dst[20] = (v >> 20) & 1
dst[21] = (v >> 21) & 1
dst[22] = (v >> 22) & 1
dst[23] = (v >> 23) & 1
dst[24] = (v >> 24) & 1
dst[25] = (v >> 25) & 1
dst[26] = (v >> 26) & 1
dst[27] = (v >> 27) & 1
dst[28] = (v >> 28) & 1
dst[29] = (v >> 29) & 1
dst[30] = (v >> 30) & 1
dst[31] = (v >> 31) & 1
dst[32] = (v >> 32) & 1
dst[33] = (v >> 33) & 1
dst[34] = (v >> 34) & 1
dst[35] = (v >> 35) & 1
dst[36] = (v >> 36) & 1
dst[37] = (v >> 37) & 1
dst[38] = (v >> 38) & 1
dst[39] = (v >> 39) & 1
dst[40] = (v >> 40) & 1
dst[41] = (v >> 41) & 1
dst[42] = (v >> 42) & 1
dst[43] = (v >> 43) & 1
dst[44] = (v >> 44) & 1
dst[45] = (v >> 45) & 1
dst[46] = (v >> 46) & 1
dst[47] = (v >> 47) & 1
dst[48] = (v >> 48) & 1
dst[49] = (v >> 49) & 1
dst[50] = (v >> 50) & 1
dst[51] = (v >> 51) & 1
dst[52] = (v >> 52) & 1
dst[53] = (v >> 53) & 1
dst[54] = (v >> 54) & 1
dst[55] = (v >> 55) & 1
dst[56] = (v >> 56) & 1
dst[57] = (v >> 57) & 1
dst[58] = (v >> 58) & 1
dst[59] = (v >> 59) & 1
}
func unpack30(v uint64, dst *[240]uint64) {
dst[0] = v & 3
dst[1] = (v >> 2) & 3
dst[2] = (v >> 4) & 3
dst[3] = (v >> 6) & 3
dst[4] = (v >> 8) & 3
dst[5] = (v >> 10) & 3
dst[6] = (v >> 12) & 3
dst[7] = (v >> 14) & 3
dst[8] = (v >> 16) & 3
dst[9] = (v >> 18) & 3
dst[10] = (v >> 20) & 3
dst[11] = (v >> 22) & 3
dst[12] = (v >> 24) & 3
dst[13] = (v >> 26) & 3
dst[14] = (v >> 28) & 3
dst[15] = (v >> 30) & 3
dst[16] = (v >> 32) & 3
dst[17] = (v >> 34) & 3
dst[18] = (v >> 36) & 3
dst[19] = (v >> 38) & 3
dst[20] = (v >> 40) & 3
dst[21] = (v >> 42) & 3
dst[22] = (v >> 44) & 3
dst[23] = (v >> 46) & 3
dst[24] = (v >> 48) & 3
dst[25] = (v >> 50) & 3
dst[26] = (v >> 52) & 3
dst[27] = (v >> 54) & 3
dst[28] = (v >> 56) & 3
dst[29] = (v >> 58) & 3
}
func unpack20(v uint64, dst *[240]uint64) {
dst[0] = v & 7
dst[1] = (v >> 3) & 7
dst[2] = (v >> 6) & 7
dst[3] = (v >> 9) & 7
dst[4] = (v >> 12) & 7
dst[5] = (v >> 15) & 7
dst[6] = (v >> 18) & 7
dst[7] = (v >> 21) & 7
dst[8] = (v >> 24) & 7
dst[9] = (v >> 27) & 7
dst[10] = (v >> 30) & 7
dst[11] = (v >> 33) & 7
dst[12] = (v >> 36) & 7
dst[13] = (v >> 39) & 7
dst[14] = (v >> 42) & 7
dst[15] = (v >> 45) & 7
dst[16] = (v >> 48) & 7
dst[17] = (v >> 51) & 7
dst[18] = (v >> 54) & 7
dst[19] = (v >> 57) & 7
}
func unpack15(v uint64, dst *[240]uint64) {
dst[0] = v & 15
dst[1] = (v >> 4) & 15
dst[2] = (v >> 8) & 15
dst[3] = (v >> 12) & 15
dst[4] = (v >> 16) & 15
dst[5] = (v >> 20) & 15
dst[6] = (v >> 24) & 15
dst[7] = (v >> 28) & 15
dst[8] = (v >> 32) & 15
dst[9] = (v >> 36) & 15
dst[10] = (v >> 40) & 15
dst[11] = (v >> 44) & 15
dst[12] = (v >> 48) & 15
dst[13] = (v >> 52) & 15
dst[14] = (v >> 56) & 15
}
func unpack12(v uint64, dst *[240]uint64) {
dst[0] = v & 31
dst[1] = (v >> 5) & 31
dst[2] = (v >> 10) & 31
dst[3] = (v >> 15) & 31
dst[4] = (v >> 20) & 31
dst[5] = (v >> 25) & 31
dst[6] = (v >> 30) & 31
dst[7] = (v >> 35) & 31
dst[8] = (v >> 40) & 31
dst[9] = (v >> 45) & 31
dst[10] = (v >> 50) & 31
dst[11] = (v >> 55) & 31
}
func unpack10(v uint64, dst *[240]uint64) {
dst[0] = v & 63
dst[1] = (v >> 6) & 63
dst[2] = (v >> 12) & 63
dst[3] = (v >> 18) & 63
dst[4] = (v >> 24) & 63
dst[5] = (v >> 30) & 63
dst[6] = (v >> 36) & 63
dst[7] = (v >> 42) & 63
dst[8] = (v >> 48) & 63
dst[9] = (v >> 54) & 63
}
func unpack8(v uint64, dst *[240]uint64) {
dst[0] = v & 127
dst[1] = (v >> 7) & 127
dst[2] = (v >> 14) & 127
dst[3] = (v >> 21) & 127
dst[4] = (v >> 28) & 127
dst[5] = (v >> 35) & 127
dst[6] = (v >> 42) & 127
dst[7] = (v >> 49) & 127
}
func unpack7(v uint64, dst *[240]uint64) {
dst[0] = v & 255
dst[1] = (v >> 8) & 255
dst[2] = (v >> 16) & 255
dst[3] = (v >> 24) & 255
dst[4] = (v >> 32) & 255
dst[5] = (v >> 40) & 255
dst[6] = (v >> 48) & 255
}
func unpack6(v uint64, dst *[240]uint64) {
dst[0] = v & 1023
dst[1] = (v >> 10) & 1023
dst[2] = (v >> 20) & 1023
dst[3] = (v >> 30) & 1023
dst[4] = (v >> 40) & 1023
dst[5] = (v >> 50) & 1023
}
func unpack5(v uint64, dst *[240]uint64) {
dst[0] = v & 4095
dst[1] = (v >> 12) & 4095
dst[2] = (v >> 24) & 4095
dst[3] = (v >> 36) & 4095
dst[4] = (v >> 48) & 4095
}
func unpack4(v uint64, dst *[240]uint64) {
dst[0] = v & 32767
dst[1] = (v >> 15) & 32767
dst[2] = (v >> 30) & 32767
dst[3] = (v >> 45) & 32767
}
func unpack3(v uint64, dst *[240]uint64) {
dst[0] = v & 1048575
dst[1] = (v >> 20) & 1048575
dst[2] = (v >> 40) & 1048575
}
func unpack2(v uint64, dst *[240]uint64) {
dst[0] = v & 1073741823
dst[1] = (v >> 30) & 1073741823
}
func unpack1(v uint64, dst *[240]uint64) {
dst[0] = v & 1152921504606846975
}