|  | @@ -8,19 +8,27 @@ import (
 | 
											
												
													
														|  |  	"v2ray.com/core/common/task"
 |  |  	"v2ray.com/core/common/task"
 | 
											
												
													
														|  |  )
 |  |  )
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +// Matcher is the interface to determine a string matches a pattern.
 | 
											
												
													
														|  |  type Matcher interface {
 |  |  type Matcher interface {
 | 
											
												
													
														|  | 
 |  | +	// Match returns true if the given string matches a predefined pattern.
 | 
											
												
													
														|  |  	Match(string) bool
 |  |  	Match(string) bool
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +// Type is the type of the matcher.
 | 
											
												
													
														|  |  type Type byte
 |  |  type Type byte
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  const (
 |  |  const (
 | 
											
												
													
														|  | 
 |  | +	// Full is the type of matcher that the input string must exactly equal to the pattern.
 | 
											
												
													
														|  |  	Full Type = iota
 |  |  	Full Type = iota
 | 
											
												
													
														|  | 
 |  | +	// Substr is the type of matcher that the input string must contain the pattern as a sub-string.
 | 
											
												
													
														|  |  	Substr
 |  |  	Substr
 | 
											
												
													
														|  | 
 |  | +	// Domain is the type of matcher that the input string must be a sub-domain or itself of the pattern.
 | 
											
												
													
														|  |  	Domain
 |  |  	Domain
 | 
											
												
													
														|  | 
 |  | +	// Regex is the type of matcher that the input string must matches the regular-expression pattern.
 | 
											
												
													
														|  |  	Regex
 |  |  	Regex
 | 
											
												
													
														|  |  )
 |  |  )
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +// New creates a new Matcher based on the given pattern.
 | 
											
												
													
														|  |  func (t Type) New(pattern string) (Matcher, error) {
 |  |  func (t Type) New(pattern string) (Matcher, error) {
 | 
											
												
													
														|  |  	switch t {
 |  |  	switch t {
 | 
											
												
													
														|  |  	case Full:
 |  |  	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 {
 |  |  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 {
 |  |  type matcherEntry struct {
 | 
											
										
											
												
													
														|  | @@ -51,6 +61,8 @@ type matcherEntry struct {
 | 
											
												
													
														|  |  	id uint32
 |  |  	id uint32
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +// MatcherGroup is an implementation of IndexMatcher.
 | 
											
												
													
														|  | 
 |  | +// Empty initialization works.
 | 
											
												
													
														|  |  type MatcherGroup struct {
 |  |  type MatcherGroup struct {
 | 
											
												
													
														|  |  	count         uint32
 |  |  	count         uint32
 | 
											
												
													
														|  |  	fullMatcher   FullMatcherGroup
 |  |  	fullMatcher   FullMatcherGroup
 | 
											
										
											
												
													
														|  | @@ -58,10 +70,7 @@ type MatcherGroup struct {
 | 
											
												
													
														|  |  	otherMatchers []matcherEntry
 |  |  	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 {
 |  |  func (g *MatcherGroup) Add(m Matcher) uint32 {
 | 
											
												
													
														|  |  	g.count++
 |  |  	g.count++
 | 
											
												
													
														|  |  	c := g.count
 |  |  	c := g.count
 | 
											
										
											
												
													
														|  | @@ -81,6 +90,7 @@ func (g *MatcherGroup) Add(m Matcher) uint32 {
 | 
											
												
													
														|  |  	return c
 |  |  	return c
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +// Match implements IndexMatcher.Match.
 | 
											
												
													
														|  |  func (g *MatcherGroup) Match(pattern string) uint32 {
 |  |  func (g *MatcherGroup) Match(pattern string) uint32 {
 | 
											
												
													
														|  |  	if c := g.fullMatcher.Match(pattern); c > 0 {
 |  |  	if c := g.fullMatcher.Match(pattern); c > 0 {
 | 
											
												
													
														|  |  		return c
 |  |  		return c
 | 
											
										
											
												
													
														|  | @@ -99,6 +109,7 @@ func (g *MatcherGroup) Match(pattern string) uint32 {
 | 
											
												
													
														|  |  	return 0
 |  |  	return 0
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +// Size returns the number of matchers in the MatcherGroup.
 | 
											
												
													
														|  |  func (g *MatcherGroup) Size() uint32 {
 |  |  func (g *MatcherGroup) Size() uint32 {
 | 
											
												
													
														|  |  	return g.count
 |  |  	return g.count
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
										
											
												
													
														|  | @@ -108,6 +119,7 @@ type cacheEntry struct {
 | 
											
												
													
														|  |  	result    uint32
 |  |  	result    uint32
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +// CachedMatcherGroup is a IndexMatcher with cachable results.
 | 
											
												
													
														|  |  type CachedMatcherGroup struct {
 |  |  type CachedMatcherGroup struct {
 | 
											
												
													
														|  |  	sync.RWMutex
 |  |  	sync.RWMutex
 | 
											
												
													
														|  |  	group   *MatcherGroup
 |  |  	group   *MatcherGroup
 | 
											
										
											
												
													
														|  | @@ -115,6 +127,7 @@ type CachedMatcherGroup struct {
 | 
											
												
													
														|  |  	cleanup *task.Periodic
 |  |  	cleanup *task.Periodic
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +// NewCachedMatcherGroup creats a new CachedMatcherGroup.
 | 
											
												
													
														|  |  func NewCachedMatcherGroup(g *MatcherGroup) *CachedMatcherGroup {
 |  |  func NewCachedMatcherGroup(g *MatcherGroup) *CachedMatcherGroup {
 | 
											
												
													
														|  |  	r := &CachedMatcherGroup{
 |  |  	r := &CachedMatcherGroup{
 | 
											
												
													
														|  |  		group: g,
 |  |  		group: g,
 | 
											
										
											
												
													
														|  | @@ -139,6 +152,7 @@ func NewCachedMatcherGroup(g *MatcherGroup) *CachedMatcherGroup {
 | 
											
												
													
														|  |  	return r
 |  |  	return r
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +// Match implements IndexMatcher.Match.
 | 
											
												
													
														|  |  func (g *CachedMatcherGroup) Match(pattern string) uint32 {
 |  |  func (g *CachedMatcherGroup) Match(pattern string) uint32 {
 | 
											
												
													
														|  |  	g.RLock()
 |  |  	g.RLock()
 | 
											
												
													
														|  |  	r, f := g.cache[pattern]
 |  |  	r, f := g.cache[pattern]
 |