• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

apache / datasketches-go / 23520345713

25 Mar 2026 01:23AM UTC coverage: 86.404% (-0.1%) from 86.509%
23520345713

push

github

web-flow
Merge pull request #140 from proost/ci-upload-coverage-directly

ci: upload coverage directly

20743 of 24007 relevant lines covered (86.4%)

0.94 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

77.53
/tuple/decoder.go
1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
3
 * contributor license agreements.  See the NOTICE file distributed with
4
 * this work for additional information regarding copyright ownership.
5
 * The ASF licenses this file to You under the Apache License, Version 2.0
6
 * (the "License"); you may not use this file except in compliance with
7
 * the License.  You may obtain a copy of the License at
8
 *
9
 *     http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 */
17

18
package tuple
19

20
import (
21
        "bytes"
22
        "encoding/binary"
23
        "fmt"
24
        "io"
25

26
        "github.com/apache/datasketches-go/internal"
27
        "github.com/apache/datasketches-go/theta"
28
)
29

30
// SummaryReader reads and returns a summary from the reader.
31
// Implementations should read the format written by a corresponding SummaryWriter.
32
//
33
// If the summary contains string values and the caller cares about
34
// cross-language compatibility, it is the caller's responsibility to ensure
35
// that the serialized string data is encoded as valid UTF-8.
36
type SummaryReader[S Summary] func(r io.Reader) (S, error)
37

38
// Decoder decodes a compact sketch from the given reader.
39
type Decoder[S Summary] struct {
40
        seed uint64
41
        read SummaryReader[S]
42
}
43

44
// NewDecoder creates a new decoder.
45
func NewDecoder[S Summary](seed uint64, read SummaryReader[S]) Decoder[S] {
1✔
46
        return Decoder[S]{
1✔
47
                seed: seed,
1✔
48
                read: read,
1✔
49
        }
1✔
50
}
1✔
51

52
// Decode decodes a compact sketch from the given reader.
53
func (dec *Decoder[S]) Decode(r io.Reader) (*CompactSketch[S], error) {
1✔
54
        var preambleLongs uint8
1✔
55
        if err := binary.Read(r, binary.LittleEndian, &preambleLongs); err != nil {
2✔
56
                return nil, err
1✔
57
        }
1✔
58

59
        var serialVersion uint8
1✔
60
        if err := binary.Read(r, binary.LittleEndian, &serialVersion); err != nil {
2✔
61
                return nil, err
1✔
62
        }
1✔
63

64
        var family uint8
1✔
65
        if err := binary.Read(r, binary.LittleEndian, &family); err != nil {
1✔
66
                return nil, err
×
67
        }
×
68

69
        var sketchType uint8
1✔
70
        if err := binary.Read(r, binary.LittleEndian, &sketchType); err != nil {
2✔
71
                return nil, err
1✔
72
        }
1✔
73

74
        var unused uint8
1✔
75
        if err := binary.Read(r, binary.LittleEndian, &unused); err != nil {
1✔
76
                return nil, err
×
77
        }
×
78

79
        var flags uint8
1✔
80
        if err := binary.Read(r, binary.LittleEndian, &flags); err != nil {
1✔
81
                return nil, err
×
82
        }
×
83

84
        var seedHash uint16
1✔
85
        if err := binary.Read(r, binary.LittleEndian, &seedHash); err != nil {
1✔
86
                return nil, err
×
87
        }
×
88

89
        if serialVersion != SerialVersion && serialVersion != SerialVersionLegacy {
2✔
90
                return nil, fmt.Errorf("serial version mismatch: expected %d, actual %d", SerialVersion, serialVersion)
1✔
91
        }
1✔
92

93
        if err := theta.CheckSketchFamilyEqual(family, uint8(internal.FamilyEnum.Tuple.Id)); err != nil {
2✔
94
                return nil, err
1✔
95
        }
1✔
96

97
        if sketchType != uint8(SketchTypeCompactTuple) && sketchType != uint8(SketchTypeCompactTupleLegacy) {
2✔
98
                return nil, fmt.Errorf("sketch type mismatch: expected %d, actual %d", SketchTypeCompactTuple, sketchType)
1✔
99
        }
1✔
100

101
        isEmpty := (flags & (1 << flagIsEmpty)) != 0
1✔
102
        if !isEmpty {
2✔
103
                expectedSeedHash, err := internal.ComputeSeedHash(int64(dec.seed))
1✔
104
                if err != nil {
1✔
105
                        return nil, err
×
106
                }
×
107
                if err := theta.CheckSeedHashEqual(seedHash, uint16(expectedSeedHash)); err != nil {
2✔
108
                        return nil, err
1✔
109
                }
1✔
110
        }
111

112
        thetaVal := theta.MaxTheta
1✔
113
        numEntries := uint32(0)
1✔
114
        if !isEmpty {
2✔
115
                if preambleLongs == 1 {
2✔
116
                        numEntries = 1
1✔
117
                } else {
2✔
118
                        if err := binary.Read(r, binary.LittleEndian, &numEntries); err != nil {
1✔
119
                                return nil, err
×
120
                        }
×
121

122
                        unused := uint32(0)
1✔
123
                        if err := binary.Read(r, binary.LittleEndian, &unused); err != nil {
1✔
124
                                return nil, err
×
125
                        }
×
126

127
                        if preambleLongs > 2 {
2✔
128
                                if err := binary.Read(r, binary.LittleEndian, &thetaVal); err != nil {
1✔
129
                                        return nil, err
×
130
                                }
×
131
                        }
132
                }
133
        }
134

135
        entries := make([]entry[S], numEntries)
1✔
136
        for i := uint32(0); i < numEntries; i++ {
2✔
137
                var hash uint64
1✔
138
                if err := binary.Read(r, binary.LittleEndian, &hash); err != nil {
1✔
139
                        return nil, err
×
140
                }
×
141

142
                summary, err := dec.read(r)
1✔
143
                if err != nil {
1✔
144
                        return nil, err
×
145
                }
×
146

147
                entries[i] = entry[S]{Hash: hash, Summary: summary}
1✔
148
        }
149

150
        isOrdered := (flags & (1 << flagIsOrdered)) != 0
1✔
151
        return newCompactSketch[S](
1✔
152
                isEmpty, isOrdered, seedHash, thetaVal, entries,
1✔
153
        ), nil
1✔
154
}
155

156
// Decode reconstructs a CompactSketch from a byte slice using a specified seed and read function.
157
func Decode[S Summary](b []byte, seed uint64, read SummaryReader[S]) (*CompactSketch[S], error) {
1✔
158
        decoder := NewDecoder[S](seed, read)
1✔
159
        return decoder.Decode(bytes.NewReader(b))
1✔
160
}
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc