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
This commit is contained in:
parent
565e416407
commit
68b45f5377
2 changed files with 57 additions and 2 deletions
29
plugin/cache/item.go
vendored
29
plugin/cache/item.go
vendored
|
@ -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()) {
|
||||
|
|
30
plugin/cache/minttl_test.go
vendored
30
plugin/cache/minttl_test.go
vendored
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue