forked from signalsciences/ipv4
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathset.go
79 lines (71 loc) · 1.53 KB
/
set.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
package ipv4
import (
"sort"
)
// Set defines a unique set of IPv4 addresses using a simple []uint32
type Set struct {
Raw []uint32
}
// Len returns a length, part of the Sort.Interface
func (m Set) Len() int {
return len(m.Raw)
}
// Swap is part of the Sort.Interface
func (m Set) Swap(i, j int) {
m.Raw[i], m.Raw[j] = m.Raw[j], m.Raw[i]
}
// Less is part of the Sort.Interface
func (m Set) Less(i, j int) bool {
return m.Raw[i] < m.Raw[j]
}
// Contains matches a dotted IPv4 address with an internal list
func (m Set) Contains(ipv4dots string) bool {
if len(m.Raw) == 0 {
return false
}
x, err := FromDots(ipv4dots)
if err != nil {
return false
}
i := sort.Search(len(m.Raw), func(i int) bool { return m.Raw[i] >= x })
return (i < len(m.Raw) && m.Raw[i] == x)
}
// Add an element to the set
func (m *Set) Add(ipv4dots string) bool {
x, err := FromDots(ipv4dots)
if err != nil {
return false
}
i := sort.Search(len(m.Raw), func(i int) bool { return m.Raw[i] >= x })
if i == len(m.Raw) {
// goes at end
m.Raw = append(m.Raw, x)
return true
}
if m.Raw[i] == x {
// already exists
return false
}
// splice
// add one extra elemnt
m.Raw = append(m.Raw, 0)
// shift right
copy(m.Raw[i+1:], m.Raw[i:])
// insert new element in hole
m.Raw[i] = x
return true
}
// Valid return true if the internal storage is in sorted form and unique
func (m Set) Valid() bool {
if len(m.Raw) == 0 {
return true
}
last := m.Raw[0]
for _, val := range m.Raw[1:] {
if val <= last {
return false
}
last = val
}
return true
}