Fix TM2 DS match to not loop

Fixes Traffic Monitor 2.0 delivery service matching from ATS astats
to be a direct hash lookup, instead of a looped string compare.
This is a massive CPU gain, profiling it appeared to be up to 30% of
the entire app's CPU usage.


Project: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/commit/a722d929
Tree: 
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/tree/a722d929
Diff: 
http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/diff/a722d929

Branch: refs/heads/master
Commit: a722d929bdd658bd22ec0fa1724d9f5762efe5ff
Parents: 129a47e
Author: Robert Butts <robert.o.bu...@gmail.com>
Authored: Fri Jan 27 13:33:24 2017 -0700
Committer: Dave Neuman <neu...@apache.org>
Committed: Mon Jan 30 08:28:47 2017 -0700

----------------------------------------------------------------------
 traffic_monitor_golang/traffic_monitor/cache/cache.go    | 11 ++++++++---
 .../traffic_monitor/trafficopsdata/trafficopsdata.go     | 11 +++++------
 2 files changed, 13 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a722d929/traffic_monitor_golang/traffic_monitor/cache/cache.go
----------------------------------------------------------------------
diff --git a/traffic_monitor_golang/traffic_monitor/cache/cache.go 
b/traffic_monitor_golang/traffic_monitor/cache/cache.go
index 46cd68f..7436d2b 100644
--- a/traffic_monitor_golang/traffic_monitor/cache/cache.go
+++ b/traffic_monitor_golang/traffic_monitor/cache/cache.go
@@ -421,17 +421,22 @@ func processStatPlugin(server enum.CacheName, stats 
map[enum.DeliveryServiceName
 }
 
 func processStatPluginRemapStats(server enum.CacheName, stats 
map[enum.DeliveryServiceName]dsdata.Stat, toData todata.TOData, stat string, 
statParts []string, value interface{}, timeReceived time.Time) 
(map[enum.DeliveryServiceName]dsdata.Stat, error) {
-       if len(statParts) < 2 {
+       if len(statParts) < 3 {
                return stats, fmt.Errorf("stat has no remap_stats 
deliveryservice and name parts")
        }
 
-       fqdn := strings.Join(statParts[:len(statParts)-1], ".")
+       // the FQDN is `subsubdomain`.`subdomain`.`domain`. For a HTTP delivery 
service, `subsubdomain` will be the cache hostname; for a DNS delivery service, 
it will be `edge`. Then, `subdomain` is the delivery service regex.
+       subsubdomain := statParts[0]
+       subdomain := statParts[1]
+       domain := strings.Join(statParts[2:len(statParts)-1], ".")
 
-       ds, ok := toData.DeliveryServiceRegexes.DeliveryService(fqdn)
+       ds, ok := toData.DeliveryServiceRegexes.DeliveryService(domain, 
subdomain, subsubdomain)
        if !ok {
+               fqdn := fmt.Sprintf("%s.%s.%s", subsubdomain, subdomain, domain)
                return stats, fmt.Errorf("ERROR no delivery service match for 
fqdn '%v' stat '%v'\n", fqdn, strings.Join(statParts, "."))
        }
        if ds == "" {
+               fqdn := fmt.Sprintf("%s.%s.%s", subsubdomain, subdomain, domain)
                return stats, fmt.Errorf("ERROR EMPTY delivery service fqdn %v 
stat %v\n", fqdn, strings.Join(statParts, "."))
        }
 

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/a722d929/traffic_monitor_golang/traffic_monitor/trafficopsdata/trafficopsdata.go
----------------------------------------------------------------------
diff --git 
a/traffic_monitor_golang/traffic_monitor/trafficopsdata/trafficopsdata.go 
b/traffic_monitor_golang/traffic_monitor/trafficopsdata/trafficopsdata.go
index 69c7af1..afc6106 100644
--- a/traffic_monitor_golang/traffic_monitor/trafficopsdata/trafficopsdata.go
+++ b/traffic_monitor_golang/traffic_monitor/trafficopsdata/trafficopsdata.go
@@ -43,14 +43,13 @@ type Regexes struct {
 }
 
 // DeliveryService returns the delivery service which matches the given fqdn, 
or false.
-func (d Regexes) DeliveryService(fqdn string) (enum.DeliveryServiceName, bool) 
{
-       if ds, ok := d.DirectMatches[fqdn]; ok {
+func (d Regexes) DeliveryService(domain, subdomain, subsubdomain string) 
(enum.DeliveryServiceName, bool) {
+       if ds, ok := d.DotStartSlashDotFooSlashDotDotStar[subdomain]; ok {
                return ds, true
        }
-       for matchStr, ds := range d.DotStartSlashDotFooSlashDotDotStar {
-               if strings.Contains(fqdn, "."+matchStr+".") {
-                       return ds, true
-               }
+       fqdn := fmt.Sprintf("%s.%s.%s", subsubdomain, subdomain, domain)
+       if ds, ok := d.DirectMatches[fqdn]; ok {
+               return ds, true
        }
        for regex, ds := range d.RegexMatch {
                if regex.MatchString(fqdn) {

Reply via email to