forked from segmentio/go-hll
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsparse.go
80 lines (60 loc) · 2.21 KB
/
sparse.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
package hll
import "sort"
type sparseStorage map[int32]byte
func (s sparseStorage) overCapacity(settings *settings) bool {
return len(s) > settings.sparseThreshold
}
func (s sparseStorage) sizeInBytes(settings *settings) int {
return divideBy8RoundUp(int(settings.log2m+settings.regwidth) * len(s))
}
func (s sparseStorage) writeBytes(settings *settings, bytes []byte) {
// per the storage spec, the registers must be in sorted order. i'm not
// sure if other implementations will complain if that's not the case, but
// better safe than sorry.
sortedRegisters := make([]int32, 0, len(s))
for reg := range s {
sortedRegisters = append(sortedRegisters, int32(reg))
}
sort.Slice(sortedRegisters, func(i, j int) bool { return sortedRegisters[i] < sortedRegisters[j] })
addr := 0
bitsPerRegister := int(settings.log2m + settings.regwidth)
for _, reg := range sortedRegisters {
writeBits(bytes, addr, (uint64(reg)<<uint(settings.regwidth))|uint64(s[reg]), bitsPerRegister)
addr += bitsPerRegister
}
}
func (s sparseStorage) fromBytes(settings *settings, bytes []byte) error {
bitsPerRegister := int(settings.regwidth + settings.log2m)
regMask := byte((1 << uint(settings.regwidth)) - 1)
// take the floor of the number of bits divided by the width of the regnum + width
numRegisters := (8 * len(bytes)) / bitsPerRegister
for i := 0; i < numRegisters; i++ {
regAndVal := readBits(bytes, i*bitsPerRegister, bitsPerRegister)
s[int32(regAndVal>>uint(settings.regwidth))] = byte(regAndVal) & regMask
}
return nil
}
func (s sparseStorage) copy() storage {
o := make(sparseStorage)
for k, v := range s {
o[k] = v
}
return o
}
func (s sparseStorage) setIfGreater(settings *settings, regnum int, value byte) {
if existing := s[int32(regnum)]; value > existing {
s[int32(regnum)] = value
}
}
func (s sparseStorage) indicator(settings *settings) (float64, int) {
// compute the "indicator function" -- indicator(2^(-M[j])) where M[j] is the
// 'j'th register value
sum := float64(0)
for _, v := range s {
sum += 1.0 / float64(uint64(1)<<v)
}
// account for all the unset registers in the indicator.
numberOfZeros := (1 << uint(settings.log2m)) - len(s)
sum += float64(numberOfZeros)
return sum, numberOfZeros
}