-
Notifications
You must be signed in to change notification settings - Fork 279
/
multi_ver.go
81 lines (72 loc) · 2.23 KB
/
multi_ver.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
81
package series
import "github.com/RoaringBitmap/roaring"
// MultiVerSeriesIDSet represents a multi version series ids set, can do and/or/and not operator,
// NOTICE: stores the result in the current bitmap, not safe for goroutine concurrent.
// version-> a bitmap of series ids.
type MultiVerSeriesIDSet struct {
versions map[int64]*roaring.Bitmap
}
// NewMultiVerSeriesIDSet creates a multi-version series id set
func NewMultiVerSeriesIDSet() *MultiVerSeriesIDSet {
return &MultiVerSeriesIDSet{
versions: make(map[int64]*roaring.Bitmap),
}
}
// Add adds a series id set version to map, if version exist ignore new ids
func (mv *MultiVerSeriesIDSet) Add(version int64, ids *roaring.Bitmap) {
_, ok := mv.versions[version]
if !ok {
mv.versions[version] = ids
}
}
// IsEmpty returns true if the multi-versions is empty or all bitmap is empty under versions
func (mv *MultiVerSeriesIDSet) IsEmpty() bool {
if len(mv.versions) == 0 {
return true
}
for _, ids := range mv.versions {
// if one bitmap is not empty, return false
if !ids.IsEmpty() {
return false
}
}
return true
}
// And computes the intersection between two set and stores the result in the current set
func (mv *MultiVerSeriesIDSet) And(other *MultiVerSeriesIDSet) {
// 1. computes the intersection between two version
var notExist []int64
for version := range mv.versions {
_, ok := other.versions[version]
if !ok {
notExist = append(notExist, version)
}
}
for _, version := range notExist {
delete(mv.versions, version)
}
// 2. computes the intersection between tow bitmap with same version
for version, ids := range mv.versions {
ids.And(other.versions[version])
}
}
// Or computes the union between two set and stores the result in the current set
func (mv *MultiVerSeriesIDSet) Or(other *MultiVerSeriesIDSet) {
for version, ids := range other.versions {
existIDs, ok := mv.versions[version]
if ok {
existIDs.Or(ids)
} else {
mv.versions[version] = ids
}
}
}
// AndNot computes the difference between two set and stores the result in the current set
func (mv *MultiVerSeriesIDSet) AndNot(other *MultiVerSeriesIDSet) {
for version, ids := range other.versions {
existIDs, ok := mv.versions[version]
if ok {
existIDs.AndNot(ids)
}
}
}