Optimize tree structure with hash map for static children
This commit is contained in:
30
sux.go
30
sux.go
@@ -7,8 +7,7 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
noMatch nodeType = iota
|
||||
static
|
||||
static nodeType = iota
|
||||
param
|
||||
wildcard
|
||||
)
|
||||
@@ -26,10 +25,10 @@ type (
|
||||
path string
|
||||
nodeType nodeType
|
||||
handler http.HandlerFunc
|
||||
children []*node
|
||||
paramChild *node // For :param routes
|
||||
wildcardChild *node // For *param routes
|
||||
paramName string // Name of the parameter
|
||||
children map[string]*node // Hash map for O(1) static child lookup
|
||||
paramChild *node // For :param routes
|
||||
wildcardChild *node // For *param routes
|
||||
paramName string // Name of the parameter
|
||||
middleware []MiddlewareFunc
|
||||
}
|
||||
|
||||
@@ -38,8 +37,8 @@ type (
|
||||
middleware []MiddlewareFunc
|
||||
notFoundHandler http.HandlerFunc
|
||||
methodNotAllowedHandler http.HandlerFunc
|
||||
paramsPool sync.Pool
|
||||
prefix string // For route groups
|
||||
paramsPool *sync.Pool // Use pointer to avoid copying
|
||||
prefix string // For route groups
|
||||
}
|
||||
)
|
||||
|
||||
@@ -60,7 +59,7 @@ func ParamsFromContext(r *http.Request) Params {
|
||||
func makeNode(path string) *node {
|
||||
return &node{
|
||||
path: path,
|
||||
children: make([]*node, 0),
|
||||
children: make(map[string]*node),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,7 +67,7 @@ func makeNode(path string) *node {
|
||||
func (n *node) addChild(path string) *node {
|
||||
if child := n.findChild(path); child == nil {
|
||||
newNode := makeNode(path)
|
||||
n.children = append(n.children, newNode)
|
||||
n.children[path] = newNode
|
||||
return newNode
|
||||
} else {
|
||||
return child
|
||||
@@ -97,12 +96,7 @@ func (n *node) addWildcardChild(paramName string) *node {
|
||||
|
||||
// findChild finds a static child node by path
|
||||
func (n *node) findChild(path string) *node {
|
||||
for _, child := range n.children {
|
||||
if child.path == path {
|
||||
return child
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return n.children[path]
|
||||
}
|
||||
|
||||
// parsePath splits a path into segments and identifies parameters
|
||||
@@ -338,7 +332,7 @@ func (r *Router) Group(prefix string, middleware ...MiddlewareFunc) *Router {
|
||||
middleware: append(r.middleware, middleware...),
|
||||
notFoundHandler: r.notFoundHandler,
|
||||
methodNotAllowedHandler: r.methodNotAllowedHandler,
|
||||
paramsPool: r.paramsPool,
|
||||
paramsPool: r.paramsPool, // Already a pointer, just copy the reference
|
||||
prefix: r.prefix + prefix,
|
||||
}
|
||||
}
|
||||
@@ -415,7 +409,7 @@ func New() *Router {
|
||||
router := &Router{
|
||||
trees: make(map[string]*node),
|
||||
middleware: make([]MiddlewareFunc, 0),
|
||||
paramsPool: sync.Pool{
|
||||
paramsPool: &sync.Pool{
|
||||
New: func() interface{} {
|
||||
return make(Params)
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user