forked from andeya/erpc
-
Notifications
You must be signed in to change notification settings - Fork 0
/
count_str.go
64 lines (58 loc) · 1.33 KB
/
count_str.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
package utils
import (
"github.com/henrylee2cn/goutil"
)
var countStringSet = []byte("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")
// CountString self-increasing string counter
type CountString struct {
indexes []int
str string
}
// NewCountString creates a self-increasing string counter.
// NOTE: panic if maxLen<=0
func NewCountString(maxLen int) *CountString {
if maxLen > len(countStringSet) {
maxLen = len(countStringSet)
} else if maxLen <= 0 {
panic("NewCountString: maxLen must be greater than 0!")
}
return &CountString{
indexes: make([]int, 1, maxLen),
}
}
// Incr increases 1.
// NOTE: non-concurrent security.
func (c *CountString) Incr() *CountString {
c.str = ""
var ok bool
for i, j := range c.indexes {
j++
if j < len(countStringSet) {
c.indexes[i] = j
ok = true
break
}
c.indexes[i] = 0
}
if !ok {
if len(c.indexes) < cap(c.indexes) {
c.indexes = append(c.indexes, 0)
} else {
// to zero
c.indexes = make([]int, 1, cap(c.indexes))
}
}
return c
}
// String returns the string.
// NOTE: non-concurrent security
func (c *CountString) String() string {
if c.str == "" {
var b = make([]byte, 0, len(c.indexes))
for i := len(c.indexes) - 1; i >= 0; i-- {
b = append(b, countStringSet[c.indexes[i]])
}
c.str = goutil.BytesToString(b)
}
return c.str
}