-
Notifications
You must be signed in to change notification settings - Fork 1
/
trie.v
140 lines (127 loc) · 2.72 KB
/
trie.v
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
139
140
module very
pub struct Trier {
mut:
root &Node
size int
}
const nul = ''
pub fn new_trie() &Trier {
return &Trier{
root: &Node{
depth: 0
children: map[string]&Node{}
}
size: 0
}
}
pub fn (mut t Trier) root() &Node {
return t.root
}
pub fn (mut t Trier) add(key string, handler Handler, mws []Handler) &Node {
unsafe {
t.size++
segments := key.split('/')
mut node := t.root // 根节点
for _, segment in segments {
if segment in node.children {
node = node.children[segment]
} else {
chr := if segment.len > 0 { segment[0..1].str() } else { '' }
mut se := segment
is_pattern := match chr {
'*', ':' { true }
else { false }
}
mut param_name := ''
if is_pattern {
if chr == ':' {
param_name = segment[1..]
se = '(?P<${param_name}>.+)'
} else if chr == '*' {
if segment.len > 1 {
param_name = segment[1..]
se = '(?P<${param_name}>.*)'
} else {
se = '(.*)'
}
}
}
node = node.new_child(se, '', nil, false, false)
node.set_pattern(is_pattern, se, param_name)
}
}
return node.new_child(very.nul, key, handler, true, false)
}
}
pub fn (mut t Trier) find(key string) (&Node, map[string]string, bool) {
unsafe {
mut params := map[string]string{}
segments := key.split('/')
node := find_node(t.root(), mut segments, mut ¶ms)
if node == nil {
return nil, map[string]string{}, false
}
children := node.children()
if very.nul !in children { // 还没有初始化过
return nil, map[string]string{}, false
}
child := children[very.nul]
if !child.term {
return nil, map[string]string{}, false
}
return child, params, true
}
}
// find_node
fn find_node(node &Node, mut segments []string, mut params map[string]string) &Node {
unsafe {
if node == nil {
return nil
}
}
if segments.len == 0 {
unsafe {
return node
}
}
mut children := node.children()
mut n := &Node{}
if segments[0] !in children {
mut flag := false
for m, _ in children {
if !unsafe { children[m].is_pattern } {
continue
}
mut child := children[m] or { continue }
if child.re.query.contains('*') {
segments = [segments.join('/')]
}
if child.re.matches_string(segments[0]) {
res := child.re.find_all_str(segments[0])
flag = true
if child.param_name.len > 0 {
params[child.param_name] = ''
if res.len > 0 {
params[child.param_name] = res[0]
}
}
unsafe {
n = child
}
break
}
}
if !flag {
return unsafe { nil }
}
} else {
unsafe {
n = children[segments[0]]
}
}
mut nsegments := []string{}
if segments.len > 1 {
nsegments = unsafe { segments[1..] }
}
return find_node(n, mut nsegments, mut params)
}