mirror of
https://github.com/v2fly/v2ray-core.git
synced 2024-09-06 03:54:22 -04:00
* Reorganize strmatcher's package structure * Rename types in strmatcher package according to their file names * Stablize strmatcher's Matcher interface * Implement []matcherEntry as SimpleMatcherGroup * Implement mph algorithm extracted from MphIndexMatcher as MphMatcherGroup * Implement AddMatcher/AddFullMatcher/AddDomainMatcher/AddSubstrMatcher for each MatcherGroup * Stablize strmatcher's MatcherGroup interface * Stablize strmatcher's IndexMatcher interface * Update strmatcher's benchmark * Compatibility fix for app/router's DomainMatcher condition * Fix code quality issue * Fix basic matcher issues * Update priority specification for Substr matcher
81 lines
1.7 KiB
Go
81 lines
1.7 KiB
Go
package strmatcher
|
|
|
|
// A MphIndexMatcher is divided into three parts:
|
|
// 1. `full` and `domain` patterns are matched by Rabin-Karp algorithm and minimal perfect hash table;
|
|
// 2. `substr` patterns are matched by ac automaton;
|
|
// 3. `regex` patterns are matched with the regex library.
|
|
type MphIndexMatcher struct {
|
|
count uint32
|
|
mph *MphMatcherGroup
|
|
ac *ACAutomatonMatcherGroup
|
|
regex SimpleMatcherGroup
|
|
}
|
|
|
|
func NewMphIndexMatcher() *MphIndexMatcher {
|
|
return &MphIndexMatcher{
|
|
mph: nil,
|
|
ac: nil,
|
|
regex: SimpleMatcherGroup{},
|
|
}
|
|
}
|
|
|
|
// Add implements IndexMatcher.Add.
|
|
func (g *MphIndexMatcher) Add(matcher Matcher) uint32 {
|
|
g.count++
|
|
index := g.count
|
|
|
|
switch matcher := matcher.(type) {
|
|
case FullMatcher:
|
|
if g.mph == nil {
|
|
g.mph = NewMphMatcherGroup()
|
|
}
|
|
g.mph.AddFullMatcher(matcher, index)
|
|
case DomainMatcher:
|
|
if g.mph == nil {
|
|
g.mph = NewMphMatcherGroup()
|
|
}
|
|
g.mph.AddDomainMatcher(matcher, index)
|
|
case SubstrMatcher:
|
|
if g.ac == nil {
|
|
g.ac = NewACAutomatonMatcherGroup()
|
|
}
|
|
g.ac.AddSubstrMatcher(matcher, index)
|
|
case *RegexMatcher:
|
|
g.regex.AddMatcher(matcher, index)
|
|
}
|
|
|
|
return index
|
|
}
|
|
|
|
// Build implements IndexMatcher.Build.
|
|
func (g *MphIndexMatcher) Build() error {
|
|
if g.mph != nil {
|
|
g.mph.Build()
|
|
}
|
|
if g.ac != nil {
|
|
g.ac.Build()
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Match implements IndexMatcher.Match.
|
|
func (*MphIndexMatcher) Match(string) []uint32 {
|
|
return nil
|
|
}
|
|
|
|
// MatchAny implements IndexMatcher.MatchAny.
|
|
func (g *MphIndexMatcher) MatchAny(input string) bool {
|
|
if g.mph != nil && g.mph.MatchAny(input) {
|
|
return true
|
|
}
|
|
if g.ac != nil && g.ac.MatchAny(input) {
|
|
return true
|
|
}
|
|
return g.regex.MatchAny(input)
|
|
}
|
|
|
|
// Size implements IndexMatcher.Size.
|
|
func (g *MphIndexMatcher) Size() uint32 {
|
|
return g.count
|
|
}
|