aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Miek Gieben <miek@miek.nl> 2018-05-08 18:36:29 +0100
committerGravatar GitHub <noreply@github.com> 2018-05-08 18:36:29 +0100
commit68b45f5377ff0c8661f987398e316f3acae4835d (patch)
treeea744740986e9faefe660ba7500276ec8f348d61
parent565e4164071778d076a48ece1698a0cf66e7548b (diff)
downloadcoredns-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.go29
-rw-r--r--plugin/cache/minttl_test.go30
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)
+ }
+ }
+}