MPH domian matcher: Support building & using cache directly (instead of building from geosite.dat when Xray starts) (#5505)

Like https://github.com/XTLS/Xray-core/pull/5488#issuecomment-3710995080
This commit is contained in:
Hossin Asaadi
2026-01-31 16:45:39 +03:30
committed by RPRX
parent afcfdbca70
commit 61e1153157
18 changed files with 988 additions and 161 deletions
+44 -11
View File
@@ -41,8 +41,9 @@ func (t Type) New(pattern string) (Matcher, error) {
if err != nil {
return nil, err
}
return &regexMatcher{
pattern: r,
return &RegexMatcher{
Pattern: pattern,
reg: r,
}, nil
default:
return nil, errors.New("unk type")
@@ -53,11 +54,13 @@ func (t Type) New(pattern string) (Matcher, error) {
type IndexMatcher interface {
// Match returns the index of a matcher that matches the input. It returns empty array if no such matcher exists.
Match(input string) []uint32
// Size returns the number of matchers in the group.
Size() uint32
}
type matcherEntry struct {
m Matcher
id uint32
type MatcherEntry struct {
M Matcher
Id uint32
}
// MatcherGroup is an implementation of IndexMatcher.
@@ -66,7 +69,7 @@ type MatcherGroup struct {
count uint32
fullMatcher FullMatcherGroup
domainMatcher DomainMatcherGroup
otherMatchers []matcherEntry
otherMatchers []MatcherEntry
}
// Add adds a new Matcher into the MatcherGroup, and returns its index. The index will never be 0.
@@ -80,9 +83,9 @@ func (g *MatcherGroup) Add(m Matcher) uint32 {
case domainMatcher:
g.domainMatcher.addMatcher(tm, c)
default:
g.otherMatchers = append(g.otherMatchers, matcherEntry{
m: m,
id: c,
g.otherMatchers = append(g.otherMatchers, MatcherEntry{
M: m,
Id: c,
})
}
@@ -95,8 +98,8 @@ func (g *MatcherGroup) Match(pattern string) []uint32 {
result = append(result, g.fullMatcher.Match(pattern)...)
result = append(result, g.domainMatcher.Match(pattern)...)
for _, e := range g.otherMatchers {
if e.m.Match(pattern) {
result = append(result, e.id)
if e.M.Match(pattern) {
result = append(result, e.Id)
}
}
return result
@@ -106,3 +109,33 @@ func (g *MatcherGroup) Match(pattern string) []uint32 {
func (g *MatcherGroup) Size() uint32 {
return g.count
}
type IndexMatcherGroup struct {
Matchers []IndexMatcher
}
func (g *IndexMatcherGroup) Match(input string) []uint32 {
var offset uint32
for _, m := range g.Matchers {
if res := m.Match(input); len(res) > 0 {
if offset == 0 {
return res
}
shifted := make([]uint32, len(res))
for i, id := range res {
shifted[i] = id + offset
}
return shifted
}
offset += m.Size()
}
return nil
}
func (g *IndexMatcherGroup) Size() uint32 {
var count uint32
for _, m := range g.Matchers {
count += m.Size()
}
return count
}