Explorar o código

extract full matcher group

Darien Raymond %!s(int64=7) %!d(string=hai) anos
pai
achega
44c759eeab

+ 13 - 0
common/strmatcher/benchmark_test.go

@@ -21,6 +21,19 @@ func BenchmarkDomainMatcherGroup(b *testing.B) {
 	}
 }
 
+func BenchmarkFullMatcherGroup(b *testing.B) {
+	g := new(FullMatcherGroup)
+
+	for i := 1; i <= 1024; i++ {
+		g.Add(strconv.Itoa(i)+".v2ray.com", uint32(i))
+	}
+
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		_ = g.Match("0.v2ray.com")
+	}
+}
+
 func BenchmarkMarchGroup(b *testing.B) {
 	g := NewMatcherGroup()
 	for i := 1; i <= 1024; i++ {

+ 4 - 0
common/strmatcher/domain_matcher.go

@@ -37,6 +37,10 @@ func (g *DomainMatcherGroup) Add(domain string, value uint32) {
 	current.value = value
 }
 
+func (g *DomainMatcherGroup) addMatcher(m domainMatcher, value uint32) {
+	g.Add(string(m), value)
+}
+
 func (g *DomainMatcherGroup) Match(domain string) uint32 {
 	current := g.root
 	if current == nil {

+ 25 - 0
common/strmatcher/full_matcher.go

@@ -0,0 +1,25 @@
+package strmatcher
+
+type FullMatcherGroup struct {
+	matchers map[string]uint32
+}
+
+func (g *FullMatcherGroup) Add(domain string, value uint32) {
+	if g.matchers == nil {
+		g.matchers = make(map[string]uint32)
+	}
+
+	g.matchers[domain] = value
+}
+
+func (g *FullMatcherGroup) addMatcher(m fullMatcher, value uint32) {
+	g.Add(string(m), value)
+}
+
+func (g *FullMatcherGroup) Match(str string) uint32 {
+	if g.matchers == nil {
+		return 0
+	}
+
+	return g.matchers[str]
+}

+ 43 - 0
common/strmatcher/full_matcher_test.go

@@ -0,0 +1,43 @@
+package strmatcher_test
+
+import (
+	"testing"
+
+	. "v2ray.com/core/common/strmatcher"
+)
+
+func TestFullMatcherGroup(t *testing.T) {
+	g := new(FullMatcherGroup)
+	g.Add("v2ray.com", 1)
+	g.Add("google.com", 2)
+	g.Add("x.a.com", 3)
+
+	testCases := []struct {
+		Domain string
+		Result uint32
+	}{
+		{
+			Domain: "v2ray.com",
+			Result: 1,
+		},
+		{
+			Domain: "y.com",
+			Result: 0,
+		},
+	}
+
+	for _, testCase := range testCases {
+		r := g.Match(testCase.Domain)
+		if r != testCase.Result {
+			t.Error("Failed to match domain: ", testCase.Domain, ", expect ", testCase.Result, ", but got ", r)
+		}
+	}
+}
+
+func TestEmptyFullMatcherGroup(t *testing.T) {
+	g := new(FullMatcherGroup)
+	r := g.Match("v2ray.com")
+	if r != 0 {
+		t.Error("Expect 0, but ", r)
+	}
+}

+ 6 - 9
common/strmatcher/strmatcher.go

@@ -53,27 +53,24 @@ type matcherEntry struct {
 
 type MatcherGroup struct {
 	count         uint32
-	fullMatchers  map[string]uint32
+	fullMatcher   FullMatcherGroup
 	domainMatcher DomainMatcherGroup
 	otherMatchers []matcherEntry
 }
 
 func NewMatcherGroup() *MatcherGroup {
-	return &MatcherGroup{
-		count:        1,
-		fullMatchers: make(map[string]uint32),
-	}
+	return &MatcherGroup{}
 }
 
 func (g *MatcherGroup) Add(m Matcher) uint32 {
-	c := g.count
 	g.count++
+	c := g.count
 
 	switch tm := m.(type) {
 	case fullMatcher:
-		g.fullMatchers[string(tm)] = c
+		g.fullMatcher.addMatcher(tm, c)
 	case domainMatcher:
-		g.domainMatcher.Add(string(tm), c)
+		g.domainMatcher.addMatcher(tm, c)
 	default:
 		g.otherMatchers = append(g.otherMatchers, matcherEntry{
 			m:  m,
@@ -85,7 +82,7 @@ func (g *MatcherGroup) Add(m Matcher) uint32 {
 }
 
 func (g *MatcherGroup) Match(pattern string) uint32 {
-	if c, f := g.fullMatchers[pattern]; f {
+	if c := g.fullMatcher.Match(pattern); c > 0 {
 		return c
 	}