-
Notifications
You must be signed in to change notification settings - Fork 2
/
sparse.go
116 lines (100 loc) · 1.9 KB
/
sparse.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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
//TODO: use sync.Pool?
package bit
import (
"bytes"
"fmt"
"reflect"
)
type SparseSet struct {
root *node // compact radix tree 7 levels deep.
}
func NewSparseSet(els ...uint64) *SparseSet {
s := &SparseSet{}
for _, e := range els {
s.Add(e)
}
return s
}
func (s *SparseSet) Add(n uint64) {
if s.root == nil {
s.root = &node{shift: 64 - 8}
}
s.root.add(n)
}
func (s *SparseSet) Remove(n uint64) {
if s.root == nil {
return
}
if s.root.remove(uint64(n)) {
s.root = nil
}
}
func (s *SparseSet) Contains(n uint64) bool {
if s.root == nil {
return false
}
return s.root.contains(n)
}
func (s *SparseSet) Empty() bool {
return s.root == nil
}
func (s *SparseSet) Clear() {
s.root = nil
}
func (s1 *SparseSet) Equal(s2 *SparseSet) bool {
if s1.root == nil || s2.root == nil {
return s1.root == s2.root
}
return s1.root.equal(s2.root)
}
// TODO: copy
func (s *SparseSet) Size() int {
if s.root == nil {
return 0
}
return s.root.size()
}
func (s *SparseSet) MemSize() uint64 {
sz := memSize(*s)
if s.root != nil {
sz += s.root.memSize()
}
return sz
}
func memSize(x interface{}) uint64 {
return uint64(reflect.TypeOf(x).Size())
}
func (s *SparseSet) Elements(a []uint64, start uint64) int {
if s.root == nil {
return 0
}
return s.root.elements(a, start, 0)
}
// TODO: rethink
// s becomes the intersection of the ss. It must not be
// one of the ss, and it is not part of the intersection.
func (s *SparseSet) Intersect(ss ...*SparseSet) {
s.Clear()
var nodes []*node
for _, t := range ss {
if t.Empty() {
return
}
nodes = append(nodes, t.root)
}
s.root = intersectNodes(nodes)
}
func (s SparseSet) String() string {
if s.Empty() {
return "{}"
}
els := make([]uint64, s.Size())
s.Elements(els, 0)
var buf bytes.Buffer
fmt.Fprintf(&buf, "{%d", els[0])
for _, e := range els[1:] {
fmt.Fprintf(&buf, ", %d", e)
}
fmt.Fprint(&buf, "}")
return buf.String()
}