mirror of https://github.com/v2ray/v2ray-core
				
				
				
			doc for strmatcher interface
							parent
							
								
									44c759eeab
								
							
						
					
					
						commit
						059dfdbb97
					
				| 
						 | 
				
			
			@ -17,7 +17,7 @@ var typeMap = map[Config_HostMapping_Type]strmatcher.Type{
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
func NewStaticHosts(hosts []*Config_HostMapping, legacy map[string]*net.IPOrDomain) (*StaticHosts, error) {
 | 
			
		||||
	g := strmatcher.NewMatcherGroup()
 | 
			
		||||
	g := new(strmatcher.MatcherGroup)
 | 
			
		||||
	sh := &StaticHosts{
 | 
			
		||||
		ips:      make(map[uint32][]net.IP),
 | 
			
		||||
		matchers: g,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -90,7 +90,7 @@ type DomainMatcher struct {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
func NewDomainMatcher(domains []*Domain) (*DomainMatcher, error) {
 | 
			
		||||
	g := strmatcher.NewMatcherGroup()
 | 
			
		||||
	g := new(strmatcher.MatcherGroup)
 | 
			
		||||
	for _, d := range domains {
 | 
			
		||||
		m, err := domainToMatcher(d)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,7 +35,7 @@ func BenchmarkFullMatcherGroup(b *testing.B) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
func BenchmarkMarchGroup(b *testing.B) {
 | 
			
		||||
	g := NewMatcherGroup()
 | 
			
		||||
	g := new(MatcherGroup)
 | 
			
		||||
	for i := 1; i <= 1024; i++ {
 | 
			
		||||
		m, err := Domain.New(strconv.Itoa(i) + ".v2ray.com")
 | 
			
		||||
		common.Must(err)
 | 
			
		||||
| 
						 | 
				
			
			@ -49,7 +49,7 @@ func BenchmarkMarchGroup(b *testing.B) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
func BenchmarkCachedMarchGroup(b *testing.B) {
 | 
			
		||||
	g := NewMatcherGroup()
 | 
			
		||||
	g := new(MatcherGroup)
 | 
			
		||||
	for i := 1; i <= 1024; i++ {
 | 
			
		||||
		m, err := Domain.New(strconv.Itoa(i) + ".v2ray.com")
 | 
			
		||||
		common.Must(err)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,6 +11,8 @@ type node struct {
 | 
			
		|||
	sub   map[string]*node
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DomainMatcherGroup is a IndexMatcher for a large set of Domain matchers.
 | 
			
		||||
// Visible for testing only.
 | 
			
		||||
type DomainMatcherGroup struct {
 | 
			
		||||
	root *node
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -59,6 +59,12 @@ func TestMatcher(t *testing.T) {
 | 
			
		|||
			input:   "xv2ray.com",
 | 
			
		||||
			output:  false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			pattern: "v2ray.com",
 | 
			
		||||
			mType:   Regex,
 | 
			
		||||
			input:   "v2rayxcom",
 | 
			
		||||
			output:  true,
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	for _, test := range cases {
 | 
			
		||||
		matcher, err := test.mType.New(test.pattern)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,19 +8,27 @@ import (
 | 
			
		|||
	"v2ray.com/core/common/task"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Matcher is the interface to determine a string matches a pattern.
 | 
			
		||||
type Matcher interface {
 | 
			
		||||
	// Match returns true if the given string matches a predefined pattern.
 | 
			
		||||
	Match(string) bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Type is the type of the matcher.
 | 
			
		||||
type Type byte
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// Full is the type of matcher that the input string must exactly equal to the pattern.
 | 
			
		||||
	Full Type = iota
 | 
			
		||||
	// Substr is the type of matcher that the input string must contain the pattern as a sub-string.
 | 
			
		||||
	Substr
 | 
			
		||||
	// Domain is the type of matcher that the input string must be a sub-domain or itself of the pattern.
 | 
			
		||||
	Domain
 | 
			
		||||
	// Regex is the type of matcher that the input string must matches the regular-expression pattern.
 | 
			
		||||
	Regex
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// New creates a new Matcher based on the given pattern.
 | 
			
		||||
func (t Type) New(pattern string) (Matcher, error) {
 | 
			
		||||
	switch t {
 | 
			
		||||
	case Full:
 | 
			
		||||
| 
						 | 
				
			
			@ -42,8 +50,10 @@ func (t Type) New(pattern string) (Matcher, error) {
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IndexMatcher is the interface for matching with a group of matchers.
 | 
			
		||||
type IndexMatcher interface {
 | 
			
		||||
	Match(pattern string) uint32
 | 
			
		||||
	// Match returns the the index of a matcher that matches the input. It returns 0 if no such matcher exists.
 | 
			
		||||
	Match(input string) uint32
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type matcherEntry struct {
 | 
			
		||||
| 
						 | 
				
			
			@ -51,6 +61,8 @@ type matcherEntry struct {
 | 
			
		|||
	id uint32
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MatcherGroup is an implementation of IndexMatcher.
 | 
			
		||||
// Empty initialization works.
 | 
			
		||||
type MatcherGroup struct {
 | 
			
		||||
	count         uint32
 | 
			
		||||
	fullMatcher   FullMatcherGroup
 | 
			
		||||
| 
						 | 
				
			
			@ -58,10 +70,7 @@ type MatcherGroup struct {
 | 
			
		|||
	otherMatchers []matcherEntry
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewMatcherGroup() *MatcherGroup {
 | 
			
		||||
	return &MatcherGroup{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Add adds a new Matcher into the MatcherGroup, and returns its index. The index will never be 0.
 | 
			
		||||
func (g *MatcherGroup) Add(m Matcher) uint32 {
 | 
			
		||||
	g.count++
 | 
			
		||||
	c := g.count
 | 
			
		||||
| 
						 | 
				
			
			@ -81,6 +90,7 @@ func (g *MatcherGroup) Add(m Matcher) uint32 {
 | 
			
		|||
	return c
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Match implements IndexMatcher.Match.
 | 
			
		||||
func (g *MatcherGroup) Match(pattern string) uint32 {
 | 
			
		||||
	if c := g.fullMatcher.Match(pattern); c > 0 {
 | 
			
		||||
		return c
 | 
			
		||||
| 
						 | 
				
			
			@ -99,6 +109,7 @@ func (g *MatcherGroup) Match(pattern string) uint32 {
 | 
			
		|||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Size returns the number of matchers in the MatcherGroup.
 | 
			
		||||
func (g *MatcherGroup) Size() uint32 {
 | 
			
		||||
	return g.count
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -108,6 +119,7 @@ type cacheEntry struct {
 | 
			
		|||
	result    uint32
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CachedMatcherGroup is a IndexMatcher with cachable results.
 | 
			
		||||
type CachedMatcherGroup struct {
 | 
			
		||||
	sync.RWMutex
 | 
			
		||||
	group   *MatcherGroup
 | 
			
		||||
| 
						 | 
				
			
			@ -115,6 +127,7 @@ type CachedMatcherGroup struct {
 | 
			
		|||
	cleanup *task.Periodic
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewCachedMatcherGroup creats a new CachedMatcherGroup.
 | 
			
		||||
func NewCachedMatcherGroup(g *MatcherGroup) *CachedMatcherGroup {
 | 
			
		||||
	r := &CachedMatcherGroup{
 | 
			
		||||
		group: g,
 | 
			
		||||
| 
						 | 
				
			
			@ -139,6 +152,7 @@ func NewCachedMatcherGroup(g *MatcherGroup) *CachedMatcherGroup {
 | 
			
		|||
	return r
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Match implements IndexMatcher.Match.
 | 
			
		||||
func (g *CachedMatcherGroup) Match(pattern string) uint32 {
 | 
			
		||||
	g.RLock()
 | 
			
		||||
	r, f := g.cache[pattern]
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue