@@ -4,9 +4,9 @@ import "net/http"
4
4
5
5
type (
6
6
Router struct {
7
- trees map [ string ]* node
8
- routes []Route
9
- echo * Echo
7
+ trees [ 21 ]* node
8
+ routes []Route
9
+ echo * Echo
10
10
}
11
11
node struct {
12
12
typ ntype
@@ -30,12 +30,12 @@ const (
30
30
31
31
func NewRouter (e * Echo ) (r * Router ) {
32
32
r = & Router {
33
- trees : make (map [string ]* node ),
33
+ // trees: make(map[string]*node),
34
34
routes : []Route {},
35
35
echo : e ,
36
36
}
37
37
for _ , m := range methods {
38
- r .trees [m ] = & node {
38
+ r .trees [r . treeIndex ( m ) ] = & node {
39
39
prefix : "" ,
40
40
children : children {},
41
41
}
@@ -81,13 +81,21 @@ func (r *Router) insert(method, path string, h HandlerFunc, t ntype, pnames []st
81
81
* e .maxParam = l
82
82
}
83
83
84
- cn := r .trees [method ] // Current node as root
84
+ cn := r .trees [r . treeIndex ( method ) ] // Current node as root
85
85
search := path
86
86
87
87
for {
88
88
sl := len (search )
89
89
pl := len (cn .prefix )
90
- l := lcp (search , cn .prefix )
90
+ l := 0
91
+
92
+ // LCP
93
+ max := pl
94
+ if sl < max {
95
+ max = sl
96
+ }
97
+ for ; l < max && search [l ] == cn .prefix [l ]; l ++ {
98
+ }
91
99
92
100
if l == 0 {
93
101
// At root node
@@ -102,16 +110,18 @@ func (r *Router) insert(method, path string, h HandlerFunc, t ntype, pnames []st
102
110
} else if l < pl {
103
111
// Split node
104
112
n := newNode (cn .typ , cn .prefix [l :], cn , cn .children , cn .handler , cn .pnames , cn .echo )
105
- cn .children = children {n } // Add to parent
106
113
107
114
// Reset parent node
108
115
cn .typ = stype
109
116
cn .label = cn .prefix [0 ]
110
117
cn .prefix = cn .prefix [:l ]
118
+ cn .children = nil
111
119
cn .handler = nil
112
120
cn .pnames = nil
113
121
cn .echo = nil
114
122
123
+ cn .addChild (n )
124
+
115
125
if l == sl {
116
126
// At parent node
117
127
cn .typ = t
@@ -121,19 +131,19 @@ func (r *Router) insert(method, path string, h HandlerFunc, t ntype, pnames []st
121
131
} else {
122
132
// Create child node
123
133
n = newNode (t , search [l :], cn , nil , h , pnames , e )
124
- cn .children = append ( cn . children , n )
134
+ cn .addChild ( n )
125
135
}
126
136
} else if l < sl {
127
137
search = search [l :]
128
- c := cn .findChild (search [0 ])
138
+ c := cn .findChildWithLabel (search [0 ])
129
139
if c != nil {
130
140
// Go deeper
131
141
cn = c
132
142
continue
133
143
}
134
144
// Create child node
135
145
n := newNode (t , search , cn , nil , h , pnames , e )
136
- cn .children = append ( cn . children , n )
146
+ cn .addChild ( n )
137
147
} else {
138
148
// Node already exists
139
149
if h != nil {
@@ -159,56 +169,47 @@ func newNode(t ntype, pre string, p *node, c children, h HandlerFunc, pnames []s
159
169
}
160
170
}
161
171
162
- func (n * node ) findChild (l byte ) * node {
163
- for _ , c := range n .children {
164
- if c .label == l {
165
- return c
166
- }
167
- }
168
- return nil
172
+ func (n * node ) addChild (c * node ) {
173
+ n .children = append (n .children , c )
169
174
}
170
175
171
- func (n * node ) findSchild (l byte ) * node {
176
+ func (n * node ) findChild (l byte , t ntype ) * node {
172
177
for _ , c := range n .children {
173
- if c .label == l && c .typ == stype {
178
+ if c .label == l && c .typ == t {
174
179
return c
175
180
}
176
181
}
177
182
return nil
178
183
}
179
184
180
- func (n * node ) findPchild ( ) * node {
185
+ func (n * node ) findChildWithLabel ( l byte ) * node {
181
186
for _ , c := range n .children {
182
- if c .typ == ptype {
187
+ if c .label == l {
183
188
return c
184
189
}
185
190
}
186
191
return nil
187
192
}
188
193
189
- func (n * node ) findMchild ( ) * node {
194
+ func (n * node ) findChildWithType ( t ntype ) * node {
190
195
for _ , c := range n .children {
191
- if c .typ == mtype {
196
+ if c .typ == t {
192
197
return c
193
198
}
194
199
}
195
200
return nil
196
201
}
197
202
198
- // Length of longest common prefix
199
- func lcp (a , b string ) (i int ) {
200
- max := len (a )
201
- l := len (b )
202
- if l < max {
203
- max = l
204
- }
205
- for ; i < max && a [i ] == b [i ]; i ++ {
203
+ func (r * Router ) treeIndex (method string ) uint8 {
204
+ if method [0 ] == 'P' {
205
+ return method [0 ]% 10 + method [1 ] - 65
206
+ } else {
207
+ return method [0 ] % 10
206
208
}
207
- return
208
209
}
209
210
210
211
func (r * Router ) Find (method , path string , ctx * Context ) (h HandlerFunc , e * Echo ) {
211
- cn := r .trees [method ] // Current node as root
212
+ cn := r .trees [r . treeIndex ( method ) ] // Current node as root
212
213
search := path
213
214
214
215
var (
@@ -235,8 +236,16 @@ func (r *Router) Find(method, path string, ctx *Context) (h HandlerFunc, e *Echo
235
236
l := 0 // LCP length
236
237
237
238
if cn .label != ':' {
239
+ sl := len (search )
238
240
pl = len (cn .prefix )
239
- l = lcp (search , cn .prefix )
241
+
242
+ // LCP
243
+ max := pl
244
+ if sl < max {
245
+ max = sl
246
+ }
247
+ for ; l < max && search [l ] == cn .prefix [l ]; l ++ {
248
+ }
240
249
}
241
250
242
251
if l == pl {
@@ -257,15 +266,15 @@ func (r *Router) Find(method, path string, ctx *Context) (h HandlerFunc, e *Echo
257
266
258
267
if search == "" {
259
268
// TODO: Needs improvement
260
- if cn .findMchild ( ) == nil {
269
+ if cn .findChildWithType ( mtype ) == nil {
261
270
continue
262
271
}
263
272
// Empty value
264
273
goto MatchAny
265
274
}
266
275
267
276
// Static node
268
- c = cn .findSchild (search [0 ])
277
+ c = cn .findChild (search [0 ], stype )
269
278
if c != nil {
270
279
// Save next
271
280
if cn .label == '/' {
@@ -279,7 +288,7 @@ func (r *Router) Find(method, path string, ctx *Context) (h HandlerFunc, e *Echo
279
288
280
289
// Param node
281
290
Param:
282
- c = cn .findPchild ( )
291
+ c = cn .findChildWithType ( ptype )
283
292
if c != nil {
284
293
// Save next
285
294
if cn .label == '/' {
@@ -299,13 +308,15 @@ func (r *Router) Find(method, path string, ctx *Context) (h HandlerFunc, e *Echo
299
308
300
309
// Match-any node
301
310
MatchAny:
302
- c = cn .findMchild ()
311
+ // c = cn.getChild()
312
+ c = cn .findChildWithType (mtype )
303
313
if c != nil {
304
314
cn = c
305
315
ctx .pvalues [0 ] = search
306
316
search = "" // End search
307
317
continue
308
318
}
319
+
309
320
// Not found
310
321
return
311
322
}
0 commit comments