-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathalp.go
More file actions
96 lines (84 loc) · 2.38 KB
/
Copy pathalp.go
File metadata and controls
96 lines (84 loc) · 2.38 KB
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
// Package alp implements Adaptive Lossless floating-Point compression.
//
// ALP is a lossless compression scheme for floating-point data from
// SIGMOD 2024. It exploits the fact that most real-world floats are
// human-friendly decimals that can be represented as integers scaled by
// powers of 10.
//
// Reference: https://dl.acm.org/doi/10.1145/3626717
package alp
// VectorSize is the number of values per compression block.
// This matches the paper's recommendation for cache efficiency.
const VectorSize = 1024
// State holds the encoding parameters learned from sampling.
// A single State can encode many vectors of similar data.
type State struct {
Exp uint8 // Exponent: multiply by 10^Exp before rounding
Factor uint8 // Factor: divide by 10^Factor after rounding
}
// Vector is a compressed block of VectorSize float64 values.
type Vector struct {
// Encoded contains the integers after ALP transformation.
Encoded [VectorSize]int64
// FrameOfRef is the minimum encoded value subtracted for bit-packing.
FrameOfRef int64
// BitWidth is the number of bits needed to represent max-min.
BitWidth uint8
// Exp and Factor are the encoding parameters used for this vector.
Exp uint8
Factor uint8
// ExceptionPos and ExceptionBits contain the positions and raw float bits
// for values that do not round-trip through the integer transform. Only the
// first NumExceptions entries are valid.
NumExceptions uint16
ExceptionPos [VectorSize]uint16
ExceptionBits [VectorSize]uint64
}
// Sample analyzes data to find encoding parameters.
func Sample(data []float64) State {
if len(data) == 0 {
return State{}
}
samples := sampleData(data)
exp, factor := findBestParameters(samples)
return State{Exp: exp, Factor: factor}
}
// Encoding limits from the ALP paper.
const (
minEncodable = -9223372036854775807 // -(2^63 - 1)
maxEncodable = 9223372036854775807 // 2^63 - 1
)
// bitWidth returns the number of bits needed to represent v.
func bitWidth(v uint64) uint8 {
if v == 0 {
return 0
}
return uint8(64 - leadingZeros64(v))
}
func leadingZeros64(x uint64) int {
n := 0
if x <= 0x00000000FFFFFFFF {
n += 32
x <<= 32
}
if x <= 0x0000FFFFFFFFFFFF {
n += 16
x <<= 16
}
if x <= 0x00FFFFFFFFFFFFFF {
n += 8
x <<= 8
}
if x <= 0x0FFFFFFFFFFFFFFF {
n += 4
x <<= 4
}
if x <= 0x3FFFFFFFFFFFFFFF {
n += 2
x <<= 2
}
if x <= 0x7FFFFFFFFFFFFFFF {
n++
}
return n
}