Files
renovate-sh-app[bot]GitHubrenovate-sh-app[bot] <219655108+renovate-sh-app[bot]@users.noreply.github.com>
41f08f4f5a fix(deps): update module github.com/axiomhq/hyperloglog to v0.2.6 (#6149)
| datasource | package                        | from   | to     |
| ---------- | ------------------------------ | ------ | ------ |
| go         | github.com/axiomhq/hyperloglog | v0.2.5 | v0.2.6 |

Signed-off-by: renovate-sh-app[bot] <219655108+renovate-sh-app[bot]@users.noreply.github.com>
Co-authored-by: renovate-sh-app[bot] <219655108+renovate-sh-app[bot]@users.noreply.github.com>
2026-01-07 17:45:17 +00:00

167 lines
3.2 KiB
Go

package hyperloglog
import (
"encoding/binary"
"slices"
)
// Original author of this file is github.com/clarkduvall/hyperloglog
type iterator struct {
i int
last uint32
v *compressedList
}
func (iter *iterator) Next() uint32 {
n, i := iter.v.decode(iter.i, iter.last)
iter.last = n
iter.i = i
return n
}
func (iter *iterator) Peek() (uint32, int) {
return iter.v.decode(iter.i, iter.last)
}
func (iter *iterator) Advance(last uint32, i int) {
iter.last = last
iter.i = i
}
func (iter iterator) HasNext() bool {
return iter.i < iter.v.Len()
}
type compressedList struct {
count uint32
last uint32
b variableLengthList
}
func (v *compressedList) Clone() *compressedList {
if v == nil {
return nil
}
newV := &compressedList{
count: v.count,
last: v.last,
}
newV.b = make(variableLengthList, len(v.b))
copy(newV.b, v.b)
return newV
}
func (v *compressedList) AppendBinary(data []byte) ([]byte, error) {
// At least 4 bytes for the two fixed sized values
data = slices.Grow(data, 4+4)
// Marshal the count and last values.
data = append(data,
// Number of items in the list.
byte(v.count>>24),
byte(v.count>>16),
byte(v.count>>8),
byte(v.count),
// The last item in the list.
byte(v.last>>24),
byte(v.last>>16),
byte(v.last>>8),
byte(v.last),
)
// Append the variableLengthList
return v.b.AppendBinary(data)
}
func (v *compressedList) UnmarshalBinary(data []byte) error {
if len(data) < 12 {
return ErrorTooShort
}
// Set the count.
v.count, data = binary.BigEndian.Uint32(data[:4]), data[4:]
// Set the last value.
v.last, data = binary.BigEndian.Uint32(data[:4]), data[4:]
// Set the list.
sz, data := binary.BigEndian.Uint32(data[:4]), data[4:]
v.b = make([]uint8, sz)
if uint32(len(data)) < sz {
return ErrorTooShort
}
for i := uint32(0); i < sz; i++ {
v.b[i] = data[i]
}
return nil
}
func newCompressedList(capacity int) *compressedList {
v := &compressedList{}
v.b = make(variableLengthList, 0, capacity)
return v
}
func (v *compressedList) Len() int {
return len(v.b)
}
func (v *compressedList) decode(i int, last uint32) (uint32, int) {
n, i := v.b.decode(i)
return n + last, i
}
func (v *compressedList) Append(x uint32) {
v.count++
v.b = v.b.Append(x - v.last)
v.last = x
}
func (v *compressedList) Iter() iterator {
return iterator{0, 0, v}
}
type variableLengthList []uint8
func (v variableLengthList) AppendBinary(data []byte) ([]byte, error) {
// 4 bytes for the size of the list, and a byte for each element in the
// list.
data = slices.Grow(data, 4+len(v))
// Length of the list. We only need 32 bits because the size of the set
// couldn't exceed that on 32 bit architectures.
sz := len(v)
data = append(data,
byte(sz>>24),
byte(sz>>16),
byte(sz>>8),
byte(sz),
)
// Marshal each element in the list.
data = append(data, v...)
return data, nil
}
func (v variableLengthList) decode(i int) (uint32, int) {
var x uint32
j := i
for ; v[j]&0x80 != 0; j++ {
x |= uint32(v[j]&0x7f) << (uint(j-i) * 7)
}
x |= uint32(v[j]) << (uint(j-i) * 7)
return x, j + 1
}
func (v variableLengthList) Append(x uint32) variableLengthList {
for x&0xffffff80 != 0 {
v = append(v, uint8((x&0x7f)|0x80))
x >>= 7
}
return append(v, uint8(x&0x7f))
}