tree: sync part httprouter codes and reduce if/else (#2163)

This commit is contained in:
thinkerou 2019-12-01 19:53:03 +08:00 committed by GitHub
parent 3957f6bb4b
commit 3abc96e3cd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 188 additions and 182 deletions

78
tree.go
View File

@ -62,6 +62,15 @@ func min(a, b int) int {
return b
}
func longestCommonPrefix(a, b string) int {
i := 0
max := min(len(a), len(b))
for i < max && a[i] == b[i] {
i++
}
return i
}
func countParams(path string) uint8 {
var n uint
for i := 0; i < len(path); i++ {
@ -127,11 +136,16 @@ func (n *node) addRoute(path string, handlers HandlersChain) {
n.priority++
numParams := countParams(path)
// Empty tree
if len(n.path) == 0 && len(n.children) == 0 {
n.insertChild(numParams, path, fullPath, handlers)
n.nType = root
return
}
parentFullPathIndex := 0
// non-empty tree
if len(n.path) > 0 || len(n.children) > 0 {
walk:
walk:
for {
// Update maxParams of the current node
if numParams > n.maxParams {
@ -141,11 +155,7 @@ func (n *node) addRoute(path string, handlers HandlersChain) {
// Find the longest common prefix.
// This also implies that the common prefix contains no ':' or '*'
// since the existing key can't contain those chars.
i := 0
max := min(len(path), len(n.path))
for i < max && path[i] == n.path[i] {
i++
}
i := longestCommonPrefix(path, n.path)
// Split edge
if i < len(n.path) {
@ -253,10 +263,6 @@ func (n *node) addRoute(path string, handlers HandlersChain) {
}
return
}
} else { // Empty tree
n.insertChild(numParams, path, fullPath, handlers)
n.nType = root
}
}
func (n *node) insertChild(numParams uint8, path string, fullPath string, handlers HandlersChain) {
@ -542,7 +548,30 @@ func (n *node) findCaseInsensitivePath(path string, fixTrailingSlash bool) (ciPa
path = path[len(n.path):]
ciPath = append(ciPath, n.path...)
if len(path) > 0 {
if len(path) == 0 {
// We should have reached the node containing the handle.
// Check if this node has a handle registered.
if n.handlers != nil {
return ciPath, true
}
// No handle found.
// Try to fix the path by adding a trailing slash
if fixTrailingSlash {
for i := 0; i < len(n.indices); i++ {
if n.indices[i] == '/' {
n = n.children[i]
if (len(n.path) == 1 && n.handlers != nil) ||
(n.nType == catchAll && n.children[0].handlers != nil) {
return append(ciPath, '/'), true
}
return
}
}
}
return
}
// If this node does not have a wildcard (param or catchAll) child,
// we can just look up the next child node and continue to walk down
// the tree
@ -610,29 +639,6 @@ func (n *node) findCaseInsensitivePath(path string, fixTrailingSlash bool) (ciPa
default:
panic("invalid node type")
}
} else {
// We should have reached the node containing the handle.
// Check if this node has a handle registered.
if n.handlers != nil {
return ciPath, true
}
// No handle found.
// Try to fix the path by adding a trailing slash
if fixTrailingSlash {
for i := 0; i < len(n.indices); i++ {
if n.indices[i] == '/' {
n = n.children[i]
if (len(n.path) == 1 && n.handlers != nil) ||
(n.nType == catchAll && n.children[0].handlers != nil) {
return append(ciPath, '/'), true
}
return
}
}
}
return
}
}
// Nothing found.