@@ -14,14 +14,16 @@ type (
14
14
echo * Echo
15
15
}
16
16
node struct {
17
- kind kind
18
- label byte
19
- prefix string
20
- parent * node
21
- children children
22
- ppath string
23
- pnames []string
24
- methodHandler * methodHandler
17
+ kind kind
18
+ label byte
19
+ prefix string
20
+ parent * node
21
+ staticChildrens children
22
+ ppath string
23
+ pnames []string
24
+ methodHandler * methodHandler
25
+ paramChildren * node
26
+ anyChildren * node
25
27
}
26
28
kind uint8
27
29
children []* node
@@ -44,6 +46,9 @@ const (
44
46
skind kind = iota
45
47
pkind
46
48
akind
49
+
50
+ paramLabel = byte (':' )
51
+ anyLabel = byte ('*' )
47
52
)
48
53
49
54
// NewRouter returns a new Router instance.
@@ -134,23 +139,32 @@ func (r *Router) insert(method, path string, h HandlerFunc, t kind, ppath string
134
139
}
135
140
} else if l < pl {
136
141
// Split node
137
- n := newNode (cn .kind , cn .prefix [l :], cn , cn .children , cn .methodHandler , cn .ppath , cn .pnames )
142
+ n := newNode (cn .kind , cn .prefix [l :], cn , cn .staticChildrens , cn .methodHandler , cn .ppath , cn .pnames , cn . paramChildren , cn . anyChildren )
138
143
139
144
// Update parent path for all children to new node
140
- for _ , child := range cn .children {
145
+ for _ , child := range cn .staticChildrens {
141
146
child .parent = n
142
147
}
148
+ if cn .paramChildren != nil {
149
+ cn .paramChildren .parent = n
150
+ }
151
+ if cn .anyChildren != nil {
152
+ cn .anyChildren .parent = n
153
+ }
143
154
144
155
// Reset parent node
145
156
cn .kind = skind
146
157
cn .label = cn .prefix [0 ]
147
158
cn .prefix = cn .prefix [:l ]
148
- cn .children = nil
159
+ cn .staticChildrens = nil
149
160
cn .methodHandler = new (methodHandler )
150
161
cn .ppath = ""
151
162
cn .pnames = nil
163
+ cn .paramChildren = nil
164
+ cn .anyChildren = nil
152
165
153
- cn .addChild (n )
166
+ // Only Static children could reach here
167
+ cn .addStaticChild (n )
154
168
155
169
if l == sl {
156
170
// At parent node
@@ -160,9 +174,10 @@ func (r *Router) insert(method, path string, h HandlerFunc, t kind, ppath string
160
174
cn .pnames = pnames
161
175
} else {
162
176
// Create child node
163
- n = newNode (t , search [l :], cn , nil , new (methodHandler ), ppath , pnames )
177
+ n = newNode (t , search [l :], cn , nil , new (methodHandler ), ppath , pnames , nil , nil )
164
178
n .addHandler (method , h )
165
- cn .addChild (n )
179
+ // Only Static children could reach here
180
+ cn .addStaticChild (n )
166
181
}
167
182
} else if l < sl {
168
183
search = search [l :]
@@ -173,9 +188,16 @@ func (r *Router) insert(method, path string, h HandlerFunc, t kind, ppath string
173
188
continue
174
189
}
175
190
// Create child node
176
- n := newNode (t , search , cn , nil , new (methodHandler ), ppath , pnames )
191
+ n := newNode (t , search , cn , nil , new (methodHandler ), ppath , pnames , nil , nil )
177
192
n .addHandler (method , h )
178
- cn .addChild (n )
193
+ switch t {
194
+ case skind :
195
+ cn .addStaticChild (n )
196
+ case pkind :
197
+ cn .paramChildren = n
198
+ case akind :
199
+ cn .anyChildren = n
200
+ }
179
201
} else {
180
202
// Node already exists
181
203
if h != nil {
@@ -190,46 +212,45 @@ func (r *Router) insert(method, path string, h HandlerFunc, t kind, ppath string
190
212
}
191
213
}
192
214
193
- func newNode (t kind , pre string , p * node , c children , mh * methodHandler , ppath string , pnames []string ) * node {
215
+ func newNode (t kind , pre string , p * node , sc children , mh * methodHandler , ppath string , pnames []string , paramChildren , anyChildren * node ) * node {
194
216
return & node {
195
- kind : t ,
196
- label : pre [0 ],
197
- prefix : pre ,
198
- parent : p ,
199
- children : c ,
200
- ppath : ppath ,
201
- pnames : pnames ,
202
- methodHandler : mh ,
217
+ kind : t ,
218
+ label : pre [0 ],
219
+ prefix : pre ,
220
+ parent : p ,
221
+ staticChildrens : sc ,
222
+ ppath : ppath ,
223
+ pnames : pnames ,
224
+ methodHandler : mh ,
225
+ paramChildren : paramChildren ,
226
+ anyChildren : anyChildren ,
203
227
}
204
228
}
205
229
206
- func (n * node ) addChild (c * node ) {
207
- n .children = append (n .children , c )
230
+ func (n * node ) addStaticChild (c * node ) {
231
+ n .staticChildrens = append (n .staticChildrens , c )
208
232
}
209
233
210
- func (n * node ) findChild (l byte , t kind ) * node {
211
- for _ , c := range n .children {
212
- if c .label == l && c . kind == t {
234
+ func (n * node ) findStaticChild (l byte ) * node {
235
+ for _ , c := range n .staticChildrens {
236
+ if c .label == l {
213
237
return c
214
238
}
215
239
}
216
240
return nil
217
241
}
218
242
219
243
func (n * node ) findChildWithLabel (l byte ) * node {
220
- for _ , c := range n .children {
244
+ for _ , c := range n .staticChildrens {
221
245
if c .label == l {
222
246
return c
223
247
}
224
248
}
225
- return nil
226
- }
227
-
228
- func (n * node ) findChildByKind (t kind ) * node {
229
- for _ , c := range n .children {
230
- if c .kind == t {
231
- return c
232
- }
249
+ if l == paramLabel {
250
+ return n .paramChildren
251
+ }
252
+ if l == anyLabel {
253
+ return n .anyChildren
233
254
}
234
255
return nil
235
256
}
@@ -356,7 +377,7 @@ func (r *Router) Find(method, path string, c Context) {
356
377
// Attempt to go back up the tree on no matching prefix or no remaining search
357
378
if l != pl || search == "" {
358
379
// Handle special case of trailing slash route with existing any route (see #1526)
359
- if path [len (path )- 1 ] == '/' && cn .findChildByKind ( akind ) != nil {
380
+ if path [len (path )- 1 ] == '/' && cn .anyChildren != nil {
360
381
goto Any
361
382
}
362
383
if nn == nil { // Issue #1348
@@ -372,7 +393,7 @@ func (r *Router) Find(method, path string, c Context) {
372
393
}
373
394
374
395
// Static node
375
- if child = cn .findChild (search [0 ], skind ); child != nil {
396
+ if child = cn .findStaticChild (search [0 ]); child != nil {
376
397
// Save next
377
398
if cn .prefix [len (cn .prefix )- 1 ] == '/' { // Issue #623
378
399
nk = pkind
@@ -385,7 +406,7 @@ func (r *Router) Find(method, path string, c Context) {
385
406
386
407
Param:
387
408
// Param node
388
- if child = cn .findChildByKind ( pkind ) ; child != nil {
409
+ if child = cn .paramChildren ; child != nil {
389
410
// Issue #378
390
411
if len (pvalues ) == n {
391
412
continue
@@ -410,7 +431,7 @@ func (r *Router) Find(method, path string, c Context) {
410
431
411
432
Any:
412
433
// Any node
413
- if cn = cn .findChildByKind ( akind ) ; cn != nil {
434
+ if cn = cn .anyChildren ; cn != nil {
414
435
// If any node is found, use remaining path for pvalues
415
436
pvalues [len (cn .pnames )- 1 ] = search
416
437
break
@@ -424,7 +445,7 @@ func (r *Router) Find(method, path string, c Context) {
424
445
search = ns
425
446
np := nn .parent
426
447
// Consider param route one level up only
427
- if cn = nn .findChildByKind ( pkind ) ; cn != nil {
448
+ if cn = nn .paramChildren ; cn != nil {
428
449
pos := strings .IndexByte (ns , '/' )
429
450
if pos == - 1 {
430
451
// If no slash is remaining in search string set param value
@@ -443,7 +464,7 @@ func (r *Router) Find(method, path string, c Context) {
443
464
// No param route found, try to resolve nearest any route
444
465
for {
445
466
np = nn .parent
446
- if cn = nn .findChildByKind ( akind ) ; cn != nil {
467
+ if cn = nn .anyChildren ; cn != nil {
447
468
break
448
469
}
449
470
if np == nil {
@@ -474,7 +495,7 @@ func (r *Router) Find(method, path string, c Context) {
474
495
475
496
// Dig further for any, might have an empty value for *, e.g.
476
497
// serving a directory. Issue #207.
477
- if cn = cn .findChildByKind ( akind ) ; cn == nil {
498
+ if cn = cn .anyChildren ; cn == nil {
478
499
return
479
500
}
480
501
if h := cn .findHandler (method ); h != nil {
0 commit comments