-
Notifications
You must be signed in to change notification settings - Fork 272
/
wildcard_node.go
138 lines (107 loc) · 2.56 KB
/
wildcard_node.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
131
132
133
134
135
136
137
138
package logger
import (
"strings"
)
type wildcardNode struct {
// Level is the logging level of this subsystem.
level Level
// Name is the latest part of the namespace, after the last colon.
name string
children map[string]*wildcardNode
}
func newWildcardNode(config ConfigMap) Config {
if config == nil {
return nil
}
root := &wildcardNode{}
for k, v := range config {
root.add(k, v)
}
return root
}
var _ Config = &wildcardNode{}
func (n *wildcardNode) add(namespace string, level Level) {
if namespace == "" {
n.level = level
return
}
names := strings.Split(namespace, ":")
parent := n
for _, name := range names {
child, ok := parent.children[name]
if !ok {
child = &wildcardNode{
level: LevelUnknown,
name: name,
}
if parent.children == nil {
parent.children = map[string]*wildcardNode{
name: child,
}
} else {
parent.children[name] = child
}
}
parent = child
}
parent.level = level
}
func (n *wildcardNode) levelForNamespace(names []string) (Level, bool) {
if len(names) == 0 {
node := n
if node.level == LevelUnknown {
// Final check for wildcard on the right side.
if child, ok := n.children["**"]; ok {
node = child
}
}
// fmt.Println("returning")
return node.level, node.level != LevelUnknown
}
parent := n
name := names[0]
if child, ok := parent.children[name]; ok {
if level, ok := child.levelForNamespace(names[1:]); ok {
return level, true
}
}
// Handle special case for double-wildcard. This matches any number of
// namespace sections in between.
if n.name == "**" {
for i := 0; i < len(names); i++ {
if child, ok := parent.children[names[i]]; ok {
if level, ok := child.levelForNamespace(names[i+1:]); ok {
return level, true
}
}
}
// Special case when ** is at the end.
if n.level != LevelUnknown {
return n.level, true
}
}
if child, ok := parent.children["*"]; ok {
if level, ok := child.levelForNamespace(names[1:]); ok {
return level, true
}
}
if child, ok := parent.children["**"]; ok {
// Send all names to take into account for the scenario where there is no prefix matched by **.
if level, ok := child.levelForNamespace(names); ok {
return level, true
}
}
return LevelDisabled, false
}
// LevelForNamespace implements Config.
func (n *wildcardNode) LevelForNamespace(namespace string) Level {
if namespace == "" {
return n.level
}
split := strings.Split(namespace, ":")
if level, ok := n.levelForNamespace(split); ok {
return level
}
// fmt.Println("fallback", c.level)
return n.level
}