Optimize tree structure with hash map for static children

This commit is contained in:
2025-10-26 12:59:45 +01:00
parent 152460aed6
commit db42316b49
3 changed files with 32 additions and 29 deletions

30
sux.go
View File

@@ -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)
},