Browse Source

improve domain matcher performance

Darien Raymond 7 years ago
parent
commit
7b28a19013
2 changed files with 16 additions and 0 deletions
  1. 6 0
      common/strmatcher/domain_matcher.go
  2. 10 0
      common/strmatcher/domain_matcher_test.go

+ 6 - 0
common/strmatcher/domain_matcher.go

@@ -25,6 +25,11 @@ func (g *DomainMatcherGroup) Add(domain string, value uint32) {
 	current := g.root
 	parts := breakDomain(domain)
 	for i := len(parts) - 1; i >= 0; i-- {
+		if current.value > 0 {
+			// if current node is already a match, it is not necessary to match further.
+			return
+		}
+
 		part := parts[i]
 		if current.sub == nil {
 			current.sub = make(map[string]*node)
@@ -38,6 +43,7 @@ func (g *DomainMatcherGroup) Add(domain string, value uint32) {
 	}
 
 	current.value = value
+	current.sub = nil // shortcut sub nodes as current node is a match.
 }
 
 func (g *DomainMatcherGroup) addMatcher(m domainMatcher, value uint32) {

+ 10 - 0
common/strmatcher/domain_matcher_test.go

@@ -11,6 +11,8 @@ func TestDomainMatcherGroup(t *testing.T) {
 	g.Add("v2ray.com", 1)
 	g.Add("google.com", 2)
 	g.Add("x.a.com", 3)
+	g.Add("a.b.com", 4)
+	g.Add("c.a.b.com", 5)
 
 	testCases := []struct {
 		Domain string
@@ -24,6 +26,14 @@ func TestDomainMatcherGroup(t *testing.T) {
 			Domain: "y.com",
 			Result: 0,
 		},
+		{
+			Domain: "a.b.com",
+			Result: 4,
+		},
+		{
+			Domain: "c.a.b.com",
+			Result: 4,
+		},
 	}
 
 	for _, testCase := range testCases {