-
Notifications
You must be signed in to change notification settings - Fork 1
/
div.map.go
130 lines (104 loc) · 1.95 KB
/
div.map.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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package elio
import (
"fmt"
)
const (
// InvalidDivIndex partition invalid index
InvalidDivIndex uint32 = ^uint32(0)
)
// DivMap division map
type DivMap struct {
division []*UnsafeMap
current uint32
}
// NewDivMap new division map
func NewDivMap(l uint32) *DivMap {
s := new(DivMap)
if nil != s {
s.division = make([]*UnsafeMap, l, l)
for i := uint32(0); i < l; i++ {
s.division[i] = NewUnsafeMap()
}
}
return s
}
// IsValidIndex is valid index
func (d *DivMap) IsValidIndex(i uint32) bool {
if i <= InvalidDivIndex {
return false
}
return true
}
// GetCurrent get current partition
func (d *DivMap) GetCurrent() (c uint32, s *UnsafeMap) {
l := len(d.division)
if l <= 0 {
return InvalidDivIndex, nil
}
defer func() {
if 0 < l {
d.current++
d.current = d.current % uint32(l)
}
}()
c = d.current
return c, d.division[c]
}
// GetLeast get least partition
func (d *DivMap) GetLeast() (i uint32, s *UnsafeMap) {
l := 0
for c, p := range d.division {
count := d.Count()
if 0 == l {
i = uint32(c)
s = p
l = count
} else if count < l {
i = uint32(c)
s = p
l = count
}
}
return i, s
}
// Get get partition
func (d *DivMap) Get(i uint32) (s *UnsafeMap, err error) {
if len(d.division) < int(i) {
err = fmt.Errorf("invalid index %d", i)
} else {
s = d.division[i]
}
return s, err
}
// Count get count
func (d *DivMap) Count() int {
return len(d.division)
}
// GetCounts get partitions count
func (d *DivMap) GetCounts() []int {
var c []int
for _, s := range d.division {
c = append(c, s.Count())
}
return c
}
// Set set to partition
func (d *DivMap) Set(k uint64, v interface{}) (uint32, *UnsafeMap) {
i, m := d.GetCurrent()
if InvalidDivIndex != i {
m.Set(k, v)
}
return i, m
}
// Del del from partition
func (d *DivMap) Del(i uint32, k uint64) (v interface{}, ok bool) {
m, err := d.Get(i)
if nil == err {
ok = true
v, ok = m.Get(k)
if ok {
m.Del(k)
}
}
return v, ok
}