engine: more performance improvements

This commit is contained in:
2026-05-18 09:17:24 +05:30
parent 77dba0c4fa
commit 581041b1a7
12 changed files with 1005 additions and 103 deletions
+69 -21
View File
@@ -112,23 +112,35 @@ type geositeDomain struct {
}
type geositeMatcher struct {
Domains []geositeDomain
Domains []geositeDomain // legacy slow path for tests and manual construction
Plain []geositeDomain
Regex []geositeDomain
Root map[string]geositeDomain
Full map[string]geositeDomain
// Attributes are matched using "and" logic - if you have multiple attributes here,
// a domain must have all of those attributes to be considered a match.
Attrs []string
}
func (m *geositeMatcher) matchDomain(domain geositeDomain, host HostInfo) bool {
// Match attributes first
if len(m.Attrs) > 0 {
if len(domain.Attrs) == 0 {
func (m *geositeMatcher) attrsMatch(domain geositeDomain) bool {
if len(m.Attrs) == 0 {
return true
}
if len(domain.Attrs) == 0 {
return false
}
for _, attr := range m.Attrs {
if !domain.Attrs[attr] {
return false
}
for _, attr := range m.Attrs {
if !domain.Attrs[attr] {
return false
}
}
}
return true
}
func (m *geositeMatcher) matchDomain(domain geositeDomain, host HostInfo) bool {
// Match attributes first
if !m.attrsMatch(domain) {
return false
}
switch domain.Type {
@@ -152,7 +164,35 @@ func (m *geositeMatcher) matchDomain(domain geositeDomain, host HostInfo) bool {
}
func (m *geositeMatcher) Match(host HostInfo) bool {
for _, domain := range m.Domains {
if host.Name == "" {
return false
}
if domain, ok := m.Full[host.Name]; ok && m.attrsMatch(domain) {
return true
}
for name := host.Name; name != ""; {
if domain, ok := m.Root[name]; ok && m.attrsMatch(domain) {
return true
}
idx := strings.IndexByte(name, '.')
if idx < 0 {
break
}
name = name[idx+1:]
}
for _, domain := range m.Plain {
if m.matchDomain(domain, host) {
return true
}
}
if len(m.Plain) == 0 && len(m.Regex) == 0 && len(m.Root) == 0 && len(m.Full) == 0 {
for _, domain := range m.Domains {
if m.matchDomain(domain, host) {
return true
}
}
}
for _, domain := range m.Regex {
if m.matchDomain(domain, host) {
return true
}
@@ -161,45 +201,53 @@ func (m *geositeMatcher) Match(host HostInfo) bool {
}
func newGeositeMatcher(list *v2geo.GeoSite, attrs []string) (*geositeMatcher, error) {
domains := make([]geositeDomain, len(list.Domain))
for i, domain := range list.Domain {
matcher := &geositeMatcher{
Root: make(map[string]geositeDomain),
Full: make(map[string]geositeDomain),
Attrs: attrs,
}
for _, domain := range list.Domain {
var compiled geositeDomain
switch domain.Type {
case v2geo.Domain_Plain:
domains[i] = geositeDomain{
compiled = geositeDomain{
Type: geositeDomainPlain,
Value: domain.Value,
Attrs: domainAttributeToMap(domain.Attribute),
}
matcher.Plain = append(matcher.Plain, compiled)
case v2geo.Domain_Regex:
regex, err := regexp.Compile(domain.Value)
if err != nil {
return nil, err
}
domains[i] = geositeDomain{
compiled = geositeDomain{
Type: geositeDomainRegex,
Value: domain.Value,
Regex: regex,
Attrs: domainAttributeToMap(domain.Attribute),
}
matcher.Regex = append(matcher.Regex, compiled)
case v2geo.Domain_Full:
domains[i] = geositeDomain{
compiled = geositeDomain{
Type: geositeDomainFull,
Value: domain.Value,
Attrs: domainAttributeToMap(domain.Attribute),
}
matcher.Full[domain.Value] = compiled
case v2geo.Domain_RootDomain:
domains[i] = geositeDomain{
compiled = geositeDomain{
Type: geositeDomainRoot,
Value: domain.Value,
Attrs: domainAttributeToMap(domain.Attribute),
}
matcher.Root[domain.Value] = compiled
default:
return nil, errors.New("unsupported domain type")
}
matcher.Domains = append(matcher.Domains, compiled)
}
return &geositeMatcher{
Domains: domains,
Attrs: attrs,
}, nil
return matcher, nil
}
func domainAttributeToMap(attrs []*v2geo.Domain_Attribute) map[string]bool {