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

kelindar / roaring / 15947069014

28 Jun 2025 06:37PM UTC coverage: 85.795% (-0.2%) from 85.945%
15947069014

push

github

kelindar
Implement bitmap container count in WriteTo and ReadFrom methods

- Added functionality to write and read the number of containers in the Bitmap struct, enhancing serialization and deserialization processes.
- Updated WriteTo method to include the count of containers before writing their data.
- Modified ReadFrom method to read the container count first, ensuring proper handling of bitmap data during deserialization.

13 of 19 new or added lines in 1 file covered. (68.42%)

2 existing lines in 1 file now uncovered.

1661 of 1936 relevant lines covered (85.8%)

13240.48 hits per line

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

69.57
/codec.go
1
// Copyright (c) Roman Atachiants and contributors. All rights reserved.
2
// Licensed under the MIT license. See LICENSE file in the project root
3

4
package roaring
5

6
import (
7
        "bytes"
8
        "encoding/binary"
9
        "io"
10
        "math/bits"
11
)
12

13
// ToBytes converts the bitmap to a byte slice
14
func (rb *Bitmap) ToBytes() []byte {
5✔
15
        var buf bytes.Buffer
5✔
16
        if _, err := rb.WriteTo(&buf); err != nil {
5✔
17
                panic(err)
×
18
        }
19

20
        return buf.Bytes()
5✔
21
}
22

23
// WriteTo writes the bitmap to a writer
24
func (rb *Bitmap) WriteTo(w io.Writer) (int64, error) {
7✔
25
        var n int64
7✔
26

7✔
27
        // Write number of containers
7✔
28
        count := uint32(len(rb.containers))
7✔
29
        if err := binary.Write(w, binary.LittleEndian, count); err != nil {
7✔
NEW
30
                return n, err
×
NEW
31
        }
×
32
        n += 4
7✔
33

7✔
34
        for i, c := range rb.containers {
274✔
35
                key := rb.index[i]
267✔
36

267✔
37
                // Write key (uint16)
267✔
38
                if err := binary.Write(w, binary.LittleEndian, key); err != nil {
267✔
39
                        return n, err
×
40
                }
×
41
                n += 2
267✔
42

267✔
43
                // Write type (byte)
267✔
44
                if err := binary.Write(w, binary.LittleEndian, c.Type); err != nil {
267✔
45
                        return n, err
×
46
                }
×
47
                n += 1
267✔
48

267✔
49
                // Prepare payload
267✔
50
                var payload []uint16
267✔
51
                var sizeBytes uint32
267✔
52
                switch c.Type {
267✔
53
                case typeArray:
265✔
54
                        payload = c.Data[:len(c.Data)]
265✔
55
                        sizeBytes = uint32(len(payload)) * 2
265✔
56
                case typeBitmap:
×
NEW
57
                        payload = c.Data[:4096] // Bitmap containers always have a fixed size of 4096 uint16s
×
NEW
58
                        sizeBytes = uint32(len(payload)) * 2
×
59
                case typeRun:
2✔
60
                        payload = c.Data[:len(c.Data)]
2✔
61
                        sizeBytes = uint32(len(payload)) * 2
2✔
62
                default:
×
63
                        return n, io.ErrUnexpectedEOF
×
64
                }
65

66
                // Write size (uint32)
67
                if err := binary.Write(w, binary.LittleEndian, sizeBytes); err != nil {
267✔
68
                        return n, err
×
69
                }
×
70
                n += 4
267✔
71

267✔
72
                // Write payload ([]uint16)
267✔
73
                if err := binary.Write(w, binary.LittleEndian, payload); err != nil {
267✔
74
                        return n, err
×
75
                }
×
76
                n += int64(sizeBytes)
267✔
77
        }
78
        return n, nil
7✔
79
}
80

81
// ReadFrom reads the bitmap from a reader
82
func (rb *Bitmap) ReadFrom(r io.Reader) (int64, error) {
7✔
83
        rb.Clear()
7✔
84
        var n int64
7✔
85

7✔
86
        // Read number of containers
7✔
87
        var count uint32
7✔
88
        if err := binary.Read(r, binary.LittleEndian, &count); err != nil {
7✔
NEW
89
                return n, err
×
NEW
90
        }
×
91
        n += 4
7✔
92

7✔
93
        for i := uint32(0); i < count; i++ {
274✔
94
                var key uint16
267✔
95
                if err := binary.Read(r, binary.LittleEndian, &key); err != nil {
267✔
UNCOV
96
                        return n, err
×
UNCOV
97
                }
×
98
                n += 2
267✔
99

267✔
100
                var typ ctype
267✔
101
                if err := binary.Read(r, binary.LittleEndian, &typ); err != nil {
267✔
102
                        return n, err
×
103
                }
×
104
                n += 1
267✔
105

267✔
106
                var sizeBytes uint32
267✔
107
                if err := binary.Read(r, binary.LittleEndian, &sizeBytes); err != nil {
267✔
108
                        return n, err
×
109
                }
×
110
                n += 4
267✔
111

267✔
112
                count := sizeBytes / 2
267✔
113
                payload := make([]uint16, count)
267✔
114
                if err := binary.Read(r, binary.LittleEndian, payload); err != nil {
267✔
115
                        return n, err
×
116
                }
×
117
                n += int64(sizeBytes)
267✔
118

267✔
119
                switch typ {
267✔
120
                case typeArray:
265✔
121
                        rb.ctrAdd(key, len(rb.containers), &container{
265✔
122
                                Type: typ,
265✔
123
                                Size: uint32(len(payload)),
265✔
124
                                Data: payload,
265✔
125
                        })
265✔
126
                case typeBitmap:
×
127
                        // Count bits set for Size
×
128
                        sz := uint32(0)
×
129
                        for _, v := range payload {
×
130
                                sz += uint32(bits.OnesCount16(v))
×
131
                        }
×
132
                        rb.ctrAdd(key, len(rb.containers), &container{
×
133
                                Type: typ,
×
134
                                Size: sz,
×
135
                                Data: payload,
×
136
                        })
×
137
                case typeRun:
2✔
138
                        // Calculate run cardinality
2✔
139
                        sz := uint32(0)
2✔
140
                        for i := 0; i+1 < len(payload); i += 2 {
4✔
141
                                sz += uint32(payload[i+1]-payload[i]) + 1
2✔
142
                        }
2✔
143
                        rb.ctrAdd(key, len(rb.containers), &container{
2✔
144
                                Type: typ,
2✔
145
                                Size: sz,
2✔
146
                                Data: payload,
2✔
147
                        })
2✔
148
                default:
×
149
                        return n, io.ErrUnexpectedEOF
×
150
                }
151
        }
152
        return n, nil
7✔
153
}
154

155
// FromBytes creates a roaring bitmap from a byte buffer
156
func FromBytes(buffer []byte) *Bitmap {
5✔
157
        rb := New()
5✔
158
        _, err := rb.ReadFrom(bytes.NewReader(buffer))
5✔
159
        if err != nil && err != io.EOF {
5✔
160
                panic(err)
×
161
        }
162
        return rb
5✔
163
}
164

165
// ReadFrom reads a roaring bitmap from an io.Reader
166
func ReadFrom(r io.Reader) (*Bitmap, error) {
1✔
167
        rb := New()
1✔
168
        _, err := rb.ReadFrom(r)
1✔
169
        if err != nil && err != io.EOF {
1✔
170
                return nil, err
×
171
        }
×
172
        return rb, nil
1✔
173
}
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