|
39 | 39 |
|
40 | 40 | // Node is a tree node.
|
41 | 41 | Node struct {
|
42 |
| - // id is the id of each node. It separates every node from each other. |
| 42 | + // id of each node. It separates nodes from each other. |
43 | 43 | id uint32
|
44 | 44 |
|
45 | 45 | // label of the node.
|
@@ -213,54 +213,56 @@ func isStar(label string) bool {
|
213 | 213 | }
|
214 | 214 |
|
215 | 215 | // searchDFS searches the tree with the DFS search algorithm.
|
216 |
| -func searchDFS( |
217 |
| - stack []*Node, |
218 |
| - visitedMap map[uint32]bool, |
219 |
| - params Params, |
220 |
| - path []string, |
221 |
| - pos int, |
222 |
| -) (map[string]handlerMiddleware, Params, bool) { |
223 |
| - if len(stack) == 0 { |
224 |
| - return nil, params, false |
225 |
| - } |
| 216 | +func (t Tree) searchDFS(path []string) (map[string]handlerMiddleware, Params, bool) { |
| 217 | + stack := []*Node{t.root} |
| 218 | + visitedMap := map[uint32]bool{} |
| 219 | + params := make(Params) |
| 220 | + var pos int |
226 | 221 |
|
227 |
| - node := stack[len(stack)-1] // accessing last element |
| 222 | + // Search while stack is not empty. |
| 223 | +SearchLoop: |
| 224 | + for len(stack) != 0 { |
| 225 | + // Accessing last element. |
| 226 | + node := stack[len(stack)-1] |
228 | 227 |
|
229 |
| - if !visitedMap[node.id] { |
230 |
| - visitedMap[node.id] = true |
| 228 | + if !visitedMap[node.id] { |
| 229 | + visitedMap[node.id] = true |
231 | 230 |
|
232 |
| - if node.isParam { |
233 |
| - params[node.label] = node.getPathParam(path, pos) |
| 231 | + if node.isParam { |
| 232 | + params[node.label] = node.getPathParam(path, pos) |
| 233 | + } |
| 234 | + |
| 235 | + if node.searchFinished(path, pos) { |
| 236 | + return node.handlerMap, params, true |
| 237 | + } |
234 | 238 | }
|
235 | 239 |
|
236 |
| - if node.searchFinished(path, pos) { |
237 |
| - return node.handlerMap, params, true |
| 240 | + for _, child := range node.children { |
| 241 | + if !visitedMap[child.id] && child.doesMatch(path, pos+1) { |
| 242 | + // Push child to the stack. |
| 243 | + stack = append(stack, child) |
| 244 | + pos++ |
| 245 | + continue SearchLoop |
| 246 | + } |
238 | 247 | }
|
239 |
| - } |
240 | 248 |
|
241 |
| - for _, child := range node.children { |
242 |
| - if !visitedMap[child.id] && child.doesMatch(path, pos+1) { |
243 |
| - stack = append(stack, child) |
244 |
| - return searchDFS(stack, visitedMap, params, path, pos+1) |
| 249 | + if node.isParam { |
| 250 | + delete(params, node.label) |
245 | 251 | }
|
246 |
| - } |
247 | 252 |
|
248 |
| - if node.isParam { |
249 |
| - delete(params, node.label) |
| 253 | + // Pop from stack. |
| 254 | + stack = stack[:len(stack)-1] |
| 255 | + pos-- |
250 | 256 | }
|
251 | 257 |
|
252 |
| - stack = stack[:len(stack)-1] |
253 |
| - return searchDFS(stack, visitedMap, params, path, pos-1) |
| 258 | + return nil, params, false |
254 | 259 | }
|
255 | 260 |
|
256 | 261 | // search searches the Tree and tries to match the path to a handler if possible.
|
257 | 262 | func (t Tree) search(path, method string) (handlerMiddleware, Params, error) {
|
258 | 263 | segments := strings.Split(path, "/")
|
259 |
| - stack := []*Node{t.root} |
260 |
| - visitedMap := map[uint32]bool{} |
261 |
| - params := make(Params) |
262 | 264 |
|
263 |
| - hmMap, params, found := searchDFS(stack, visitedMap, params, segments, 0) |
| 265 | + hmMap, params, found := t.searchDFS(segments) |
264 | 266 |
|
265 | 267 | if !found {
|
266 | 268 | return handlerMiddleware{}, params, errNotFound
|
|
0 commit comments