diff options
author | 2018-05-08 18:36:29 +0100 | |
---|---|---|
committer | 2018-05-08 18:36:29 +0100 | |
commit | 68b45f5377ff0c8661f987398e316f3acae4835d (patch) | |
tree | ea744740986e9faefe660ba7500276ec8f348d61 | |
parent | 565e4164071778d076a48ece1698a0cf66e7548b (diff) | |
download | coredns-68b45f5377ff0c8661f987398e316f3acae4835d.tar.gz coredns-68b45f5377ff0c8661f987398e316f3acae4835d.tar.zst coredns-68b45f5377ff0c8661f987398e316f3acae4835d.zip |
plugin/cache: unroll minTTL loop (#1773)
This allocates memory because of the append, just unroll the loop.
Also add benchmark.
Before:
goos: linux
goarch: amd64
pkg: github.com/coredns/coredns/plugin/cache
BenchmarkCacheResponse-4 100000 11910 ns/op
BenchmarkMinMsgTTL-4 1000000 1494 ns/op
PASS
After:
goos: linux
goarch: amd64
pkg: github.com/coredns/coredns/plugin/cache
BenchmarkCacheResponse-4 100000 12016 ns/op
BenchmarkMinMsgTTL-4 2000000 668 ns/op
PASS
-rw-r--r-- | plugin/cache/item.go | 29 | ||||
-rw-r--r-- | plugin/cache/minttl_test.go | 30 |
2 files changed, 57 insertions, 2 deletions
diff --git a/plugin/cache/item.go b/plugin/cache/item.go index 094b8bb2e..5761cdf87 100644 --- a/plugin/cache/item.go +++ b/plugin/cache/item.go @@ -99,7 +99,32 @@ func minMsgTTL(m *dns.Msg, mt response.Type) time.Duration { } minTTL := maxTTL - for _, r := range append(append(m.Answer, m.Ns...), m.Extra...) { + for _, r := range m.Answer { + switch mt { + case response.NameError, response.NoData: + if r.Header().Rrtype == dns.TypeSOA { + minTTL = time.Duration(r.(*dns.SOA).Minttl) * time.Second + } + case response.NoError, response.Delegation: + if r.Header().Ttl < uint32(minTTL.Seconds()) { + minTTL = time.Duration(r.Header().Ttl) * time.Second + } + } + } + for _, r := range m.Ns { + switch mt { + case response.NameError, response.NoData: + if r.Header().Rrtype == dns.TypeSOA { + minTTL = time.Duration(r.(*dns.SOA).Minttl) * time.Second + } + case response.NoError, response.Delegation: + if r.Header().Ttl < uint32(minTTL.Seconds()) { + minTTL = time.Duration(r.Header().Ttl) * time.Second + } + } + } + + for _, r := range m.Extra { if r.Header().Rrtype == dns.TypeOPT { // OPT records use TTL field for extended rcode and flags continue @@ -107,7 +132,7 @@ func minMsgTTL(m *dns.Msg, mt response.Type) time.Duration { switch mt { case response.NameError, response.NoData: if r.Header().Rrtype == dns.TypeSOA { - return time.Duration(r.(*dns.SOA).Minttl) * time.Second + minTTL = time.Duration(r.(*dns.SOA).Minttl) * time.Second } case response.NoError, response.Delegation: if r.Header().Ttl < uint32(minTTL.Seconds()) { diff --git a/plugin/cache/minttl_test.go b/plugin/cache/minttl_test.go index 5ce4f2341..376c638a1 100644 --- a/plugin/cache/minttl_test.go +++ b/plugin/cache/minttl_test.go @@ -40,3 +40,33 @@ func TestMinMsgTTL(t *testing.T) { t.Fatalf("Expected minttl duration to be %d, got %d", 3600, dur) } } + +func BenchmarkMinMsgTTL(b *testing.B) { + m := new(dns.Msg) + m.SetQuestion("example.org.", dns.TypeA) + m.Ns = []dns.RR{ + test.A("a.example.org. 1800 IN A 127.0.0.53"), + test.A("b.example.org. 1900 IN A 127.0.0.53"), + test.A("c.example.org. 1600 IN A 127.0.0.53"), + test.A("d.example.org. 1100 IN A 127.0.0.53"), + test.A("e.example.org. 1000 IN A 127.0.0.53"), + } + m.Extra = []dns.RR{ + test.A("a.example.org. 1800 IN A 127.0.0.53"), + test.A("b.example.org. 1600 IN A 127.0.0.53"), + test.A("c.example.org. 1400 IN A 127.0.0.53"), + test.A("d.example.org. 1200 IN A 127.0.0.53"), + test.A("e.example.org. 1100 IN A 127.0.0.53"), + } + + utc := time.Now().UTC() + mt, _ := response.Typify(m, utc) + + b.ResetTimer() + for i := 0; i < b.N; i++ { + dur := minMsgTTL(m, mt) + if dur != 1000*time.Second { + b.Fatalf("Wrong minMsgTTL %d, expected %d", dur, 1000*time.Second) + } + } +} |