Optimize types.CertAuthority comparison (#20008)

This commit is contained in:
STeve (Xin) Huang 2023-01-09 14:20:52 -05:00 committed by GitHub
parent ef43b4cef9
commit f05ca9c4a0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 52 additions and 0 deletions

View file

@ -23,6 +23,7 @@ import (
"encoding/json"
"time"
"github.com/gogo/protobuf/proto"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"github.com/gravitational/trace"
@ -47,6 +48,14 @@ func CertAuthoritiesEquivalent(lhs, rhs types.CertAuthority) bool {
return cmp.Equal(lhs, rhs,
ignoreProtoXXXFields(),
cmpopts.IgnoreFields(types.Metadata{}, "ID"),
// Optimize types.CAKeySet comparison.
cmp.Comparer(func(a, b types.CAKeySet) bool {
// Note that Clone drops XXX_ fields. And it's benchmarked that cloning
// plus using proto.Equal is more efficient than cmp.Equal.
aClone := a.Clone()
bClone := b.Clone()
return proto.Equal(&aClone, &bClone)
}),
)
}

View file

@ -17,6 +17,7 @@ limitations under the License.
package services_test
import (
"bytes"
"crypto/x509/pkix"
"testing"
"time"
@ -186,3 +187,45 @@ func TestCertAuthorityUTCUnmarshal(t *testing.T) {
require.True(t, CertAuthoritiesEquivalent(caLocal, caUTC))
}
func BenchmarkCertAuthoritiesEquivalent(b *testing.B) {
ca1, err := types.NewCertAuthority(types.CertAuthoritySpecV2{
Type: types.HostCA,
ClusterName: "cluster1",
ActiveKeys: types.CAKeySet{
TLS: []*types.TLSKeyPair{{
Cert: bytes.Repeat([]byte{49}, 1600),
Key: bytes.Repeat([]byte{49}, 1200),
}},
},
})
require.NoError(b, err)
// ca2 is a clone of ca1.
ca2 := ca1.Clone()
// ca3 has different cert bytes from ca1.
ca3, err := types.NewCertAuthority(types.CertAuthoritySpecV2{
Type: types.HostCA,
ClusterName: "cluster1",
ActiveKeys: types.CAKeySet{
TLS: []*types.TLSKeyPair{{
Cert: bytes.Repeat([]byte{49}, 1666),
Key: bytes.Repeat([]byte{49}, 1222),
}},
},
})
require.NoError(b, err)
b.Run("true", func(b *testing.B) {
for i := 0; i < b.N; i++ {
require.True(b, CertAuthoritiesEquivalent(ca1, ca2))
}
})
b.Run("false", func(b *testing.B) {
for i := 0; i < b.N; i++ {
require.False(b, CertAuthoritiesEquivalent(ca1, ca3))
}
})
}