perf(matcher): change Match/FindLongestPrefix to accept []byte

Accept []byte directly instead of string, allowing callers to pass
fasthttp's ctx.Path() without string conversion. Internally uses
bytes.HasPrefix instead of strings.HasPrefix in radix tree search.
This commit is contained in:
xfy 2026-06-04 11:05:49 +08:00
parent 0a53622351
commit aef0d8357b
2 changed files with 10 additions and 8 deletions

View File

@ -198,8 +198,8 @@ func (e *LocationEngine) AddNamed(name string, handler fasthttp.RequestHandler)
// //
// 返回值: // 返回值:
// - *MatchResult: 匹配结果,无匹配时返回 nil // - *MatchResult: 匹配结果,无匹配时返回 nil
func (e *LocationEngine) Match(path string) *MatchResult { func (e *LocationEngine) Match(path []byte) *MatchResult {
if m, ok := e.exactMatchers[path]; ok { if m, ok := e.exactMatchers[string(path)]; ok {
return m.Result() return m.Result()
} }
@ -209,10 +209,11 @@ func (e *LocationEngine) Match(path string) *MatchResult {
} }
ReleaseMatchResult(prefixPriorityResult) ReleaseMatchResult(prefixPriorityResult)
pathStr := string(path)
for _, m := range e.regexMatchers { for _, m := range e.regexMatchers {
if m.Match(path) { if m.Match(pathStr) {
result := m.Result() result := m.Result()
result.Captures = m.GetCaptures(path) result.Captures = m.GetCaptures(pathStr)
return result return result
} }
} }

View File

@ -9,6 +9,7 @@
package matcher package matcher
import ( import (
"bytes"
"errors" "errors"
"strings" "strings"
"sync" "sync"
@ -224,7 +225,7 @@ func (t *RadixTree) insertNode(parent *RadixNode, node *RadixNode, path string,
// //
// 返回值: // 返回值:
// - *MatchResult: 最长前缀匹配结果,无匹配时返回 nil // - *MatchResult: 最长前缀匹配结果,无匹配时返回 nil
func (t *RadixTree) FindLongestPrefix(path string) *MatchResult { func (t *RadixTree) FindLongestPrefix(path []byte) *MatchResult {
bestNode := t.searchLongest(t.root, path, nil) bestNode := t.searchLongest(t.root, path, nil)
if bestNode == nil { if bestNode == nil {
return nil return nil
@ -238,12 +239,12 @@ func (t *RadixTree) FindLongestPrefix(path string) *MatchResult {
return result return result
} }
func (t *RadixTree) searchLongest(node *RadixNode, path string, bestNode *RadixNode) *RadixNode { func (t *RadixTree) searchLongest(node *RadixNode, path []byte, bestNode *RadixNode) *RadixNode {
if node == nil || path == "" { if node == nil || len(path) == 0 {
return bestNode return bestNode
} }
if !strings.HasPrefix(path, node.prefix) { if !bytes.HasPrefix(path, []byte(node.prefix)) {
return bestNode return bestNode
} }