fix(net/ghttp): refactor the route tree#4712
Open
LanceAdd wants to merge 4 commits intogogf:masterfrom
Open
Conversation
- 引入 routeNode 结构体作为路由前缀树的节点 - 使用 children 字段存储精确匹配路径段,fuzz 字段存储通配符节点,list 字段存储处理器项 - 添加 ensureList、ensureFuzz、ensureChild 等辅助方法来管理节点操作 - 修改路由注册逻辑以适应新的前缀树结构 - 更新路由查找逻辑以遍历前缀树并正确处理模糊匹配和精确匹配 - 替换原有的 map[string]any 嵌套结构为类型安全的 routeNode 指针映射
Contributor
There was a problem hiding this comment.
Pull request overview
This PR refactors ghttp’s core routing structure (Server.serveTree) from a map[string]any-based recursive tree with magic keys into a typed prefix trie (routeNode) to eliminate runtime type assertions on the hot path (searchHandlers).
Changes:
- Introduced
routeNode(children/fuzz/list) and changedserveTreetomap[string]*routeNodekeyed by domain. - Added small helper methods on
routeNode(ensureList/ensureFuzz/ensureChild/appendList) to simplify and speed up route registration and lookup. - Updated route registration (
doSetHandler) and lookup (searchHandlers) to use typed navigation instead ofmap[string]any+ type assertions.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| net/ghttp/ghttp_server_router_serve.go | Switch route lookup to typed trie traversal and typed handler list iteration. |
| net/ghttp/ghttp_server_router.go | Add routeNode helper methods and refactor registration to build the typed trie. |
| net/ghttp/ghttp_server.go | Initialize serveTree as map[string]*routeNode. |
| net/ghttp/ghttp.go | Update Server’s serveTree type and define the routeNode struct. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
背景
Server.serveTree是 ghttp 路由系统的核心数据结构,承载从域名到路由处理器的整棵前缀树。每次 HTTP 请求在缓存未命中时,都必须通过searchHandlers遍历该树来匹配路由,是真正的热路径。原始实现将整棵树递归地表示为
map[string]any,通过硬编码字符串键区分节点语义:"*fuzz"→ 模糊子节点(:param/{param}/*wildcard)"*list"→ 当前节点的处理器列表(*glist.List)这导致
searchHandlers每处理一个 URI 段最多产生 5 次运行时类型断言,以/api/v1/user/123(4 段)为例,单次调用约产生 16 次断言。变更内容
新增
routeNode结构体用具体结构体替换递归的
map[string]any,将三种节点语义直接表达为结构体字段:Server.serveTree字段类型由map[string]any改为map[string]*routeNode。新增 4 个封装方法
ensureList(dst)ensureFuzz()ensureChild(part)appendList(dst)性能收益
searchHandlers每段断言次数fuzz/list字段访问doSetHandler核心循环行数serveCache)