-
Notifications
You must be signed in to change notification settings - Fork 3
/
tag.go
83 lines (75 loc) · 2.15 KB
/
tag.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
package alog
// tag is a bit-formatFlag used to show only necessary part of process to show
// in the log. For instance, if there'Vstr an web service, there can be different
// tag such as UI, HTTP request, HTTP response, etc. By alConf a tag
// for each log using `Print` or `Printf`, a user can only print certain
// tag of log messages for better debugging.
type Tag uint64
func (t Tag) Has(tag Tag) bool {
if t & tag == tag {
return true
}
return false
}
func (t Tag) Sub(tag Tag) Tag {
return t & ^tag
}
// TagBucket can issue a tag and also holds the total number
// of tags issued AND also names given to each tag.
// Not that TagBucket is not using any mutex as it is designed
// to be set at the very beginning of the process.
// Also, the maximum number of tag can be issue is limited to 63.
type TagBucket struct {
count int // count stores number of tag issued.
names [64]string // names stores tag names.
}
// GetTag returns a tag if found
func (t TagBucket) GetTag(name string) (tag Tag, ok bool) {
for i := 0; i < t.count; i++ {
if t.names[i] == name {
return 1 << i, true
}
}
return 0, false
}
// MustGetTag returns a tag if found. If not, create a new tag.
func (t *TagBucket) MustGetTag(name string) Tag {
// If a tag is found, return it.
if tag, ok := t.GetTag(name); ok {
return tag
}
// If the tag is not found, issue a tag using most recently created.
// When the maximum capacity of tag has met, return 0.
if t.count >= 64 {
return 0
}
// Create a new tag and return the tag.
t.names[t.count] = name
tag := t.count // this is the value to be printed.
t.count += 1
return 1 << tag
}
func (t *TagBucket) AppendTag(dst []byte, tag Tag) []byte {
origLen := len(dst)
for i := 0; i < t.count; i++ {
if tag&(1<<i) != 0 {
dst = append(append(dst, t.names[i]...), ',')
}
}
if len(dst) > origLen {
return dst[0 : len(dst)-1]
}
return dst
}
func (t *TagBucket) AppendTagForJSON(dst []byte, tag Tag) []byte {
origLen := len(dst)
for i := 0; i < t.count; i++ {
if tag&(1<<i) != 0 {
dst = append(append(append(dst, '"'), t.names[i]...), '"', ',')
}
}
if len(dst) > origLen {
return dst[0 : len(dst)-1]
}
return dst
}