-
Notifications
You must be signed in to change notification settings - Fork 53
Expand file tree
/
Copy pathserialization_le.go
More file actions
85 lines (81 loc) · 2.6 KB
/
serialization_le.go
File metadata and controls
85 lines (81 loc) · 2.6 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
//go:build amd64 || 386 || arm || arm64 || ppc64le || mipsle || mips64le || mips64p32le || wasm
package xorfilter
import (
"io"
"unsafe"
)
// Save writes the filter to the writer assuming little endian system, using direct byte copy for performance.
func (f *BinaryFuse[T]) Save(w io.Writer) error {
// Write Seed
if _, err := w.Write((*[8]byte)(unsafe.Pointer(&f.Seed))[:]); err != nil {
return err
}
// Write SegmentLength
if _, err := w.Write((*[4]byte)(unsafe.Pointer(&f.SegmentLength))[:]); err != nil {
return err
}
// Write SegmentLengthMask
if _, err := w.Write((*[4]byte)(unsafe.Pointer(&f.SegmentLengthMask))[:]); err != nil {
return err
}
// Write SegmentCount
if _, err := w.Write((*[4]byte)(unsafe.Pointer(&f.SegmentCount))[:]); err != nil {
return err
}
// Write SegmentCountLength
if _, err := w.Write((*[4]byte)(unsafe.Pointer(&f.SegmentCountLength))[:]); err != nil {
return err
}
// Write length of Fingerprints
fpLen := uint32(len(f.Fingerprints))
if _, err := w.Write((*[4]byte)(unsafe.Pointer(&fpLen))[:]); err != nil {
return err
}
// Write Fingerprints
if len(f.Fingerprints) > 0 {
size := int(unsafe.Sizeof(T(0)))
bytes := unsafe.Slice((*byte)(unsafe.Pointer(&f.Fingerprints[0])), len(f.Fingerprints)*size)
if _, err := w.Write(bytes); err != nil {
return err
}
}
return nil
}
// LoadBinaryFuse reads the filter from the reader assuming little endian system, using direct byte copy for performance.
func LoadBinaryFuse[T Unsigned](r io.Reader) (*BinaryFuse[T], error) {
var f BinaryFuse[T]
// Read Seed
if _, err := io.ReadFull(r, (*[8]byte)(unsafe.Pointer(&f.Seed))[:]); err != nil {
return nil, err
}
// Read SegmentLength
if _, err := io.ReadFull(r, (*[4]byte)(unsafe.Pointer(&f.SegmentLength))[:]); err != nil {
return nil, err
}
// Read SegmentLengthMask
if _, err := io.ReadFull(r, (*[4]byte)(unsafe.Pointer(&f.SegmentLengthMask))[:]); err != nil {
return nil, err
}
// Read SegmentCount
if _, err := io.ReadFull(r, (*[4]byte)(unsafe.Pointer(&f.SegmentCount))[:]); err != nil {
return nil, err
}
// Read SegmentCountLength
if _, err := io.ReadFull(r, (*[4]byte)(unsafe.Pointer(&f.SegmentCountLength))[:]); err != nil {
return nil, err
}
// Read length of Fingerprints
var fpLen uint32
if _, err := io.ReadFull(r, (*[4]byte)(unsafe.Pointer(&fpLen))[:]); err != nil {
return nil, err
}
f.Fingerprints = make([]T, fpLen)
if fpLen > 0 {
size := int(unsafe.Sizeof(T(0)))
bytes := unsafe.Slice((*byte)(unsafe.Pointer(&f.Fingerprints[0])), int(fpLen)*size)
if _, err := io.ReadFull(r, bytes); err != nil {
return nil, err
}
}
return &f, nil
}