mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-20 18:31:15 +00:00
Merge pull request #115403 from apelisse/hasschema-pool
apiextensions: Benchmark escaping in SchemaHas and pool Schemas
This commit is contained in:
commit
f3562d9dea
@ -23,6 +23,7 @@ import (
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
|
||||
@ -1364,6 +1365,27 @@ func HasSchemaWith(spec *apiextensions.CustomResourceDefinitionSpec, pred func(s
|
||||
return false
|
||||
}
|
||||
|
||||
var schemaPool = sync.Pool{
|
||||
New: func() any {
|
||||
return new(apiextensions.JSONSchemaProps)
|
||||
},
|
||||
}
|
||||
|
||||
func schemaHasRecurse(s *apiextensions.JSONSchemaProps, pred func(s *apiextensions.JSONSchemaProps) bool) bool {
|
||||
if s == nil {
|
||||
return false
|
||||
}
|
||||
schema := schemaPool.Get().(*apiextensions.JSONSchemaProps)
|
||||
defer schemaPool.Put(schema)
|
||||
*schema = *s
|
||||
return SchemaHas(schema, pred)
|
||||
}
|
||||
|
||||
// SchemaHas recursively traverses the Schema and calls the `pred`
|
||||
// predicate to see if the schema contains specific values.
|
||||
//
|
||||
// The predicate MUST NOT keep a copy of the json schema NOR modify the
|
||||
// schema.
|
||||
func SchemaHas(s *apiextensions.JSONSchemaProps, pred func(s *apiextensions.JSONSchemaProps) bool) bool {
|
||||
if s == nil {
|
||||
return false
|
||||
@ -1374,60 +1396,60 @@ func SchemaHas(s *apiextensions.JSONSchemaProps, pred func(s *apiextensions.JSON
|
||||
}
|
||||
|
||||
if s.Items != nil {
|
||||
if s.Items != nil && SchemaHas(s.Items.Schema, pred) {
|
||||
if s.Items != nil && schemaHasRecurse(s.Items.Schema, pred) {
|
||||
return true
|
||||
}
|
||||
for i := range s.Items.JSONSchemas {
|
||||
if SchemaHas(&s.Items.JSONSchemas[i], pred) {
|
||||
if schemaHasRecurse(&s.Items.JSONSchemas[i], pred) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
for i := range s.AllOf {
|
||||
if SchemaHas(&s.AllOf[i], pred) {
|
||||
if schemaHasRecurse(&s.AllOf[i], pred) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
for i := range s.AnyOf {
|
||||
if SchemaHas(&s.AnyOf[i], pred) {
|
||||
if schemaHasRecurse(&s.AnyOf[i], pred) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
for i := range s.OneOf {
|
||||
if SchemaHas(&s.OneOf[i], pred) {
|
||||
if schemaHasRecurse(&s.OneOf[i], pred) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
if SchemaHas(s.Not, pred) {
|
||||
if schemaHasRecurse(s.Not, pred) {
|
||||
return true
|
||||
}
|
||||
for _, s := range s.Properties {
|
||||
if SchemaHas(&s, pred) {
|
||||
if schemaHasRecurse(&s, pred) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
if s.AdditionalProperties != nil {
|
||||
if SchemaHas(s.AdditionalProperties.Schema, pred) {
|
||||
if schemaHasRecurse(s.AdditionalProperties.Schema, pred) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
for _, s := range s.PatternProperties {
|
||||
if SchemaHas(&s, pred) {
|
||||
if schemaHasRecurse(&s, pred) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
if s.AdditionalItems != nil {
|
||||
if SchemaHas(s.AdditionalItems.Schema, pred) {
|
||||
if schemaHasRecurse(s.AdditionalItems.Schema, pred) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
for _, s := range s.Definitions {
|
||||
if SchemaHas(&s, pred) {
|
||||
if schemaHasRecurse(&s, pred) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
for _, d := range s.Dependencies {
|
||||
if SchemaHas(d.Schema, pred) {
|
||||
if schemaHasRecurse(d.Schema, pred) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
@ -8624,6 +8624,30 @@ func TestSchemaHasDefaults(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkSchemaHas(b *testing.B) {
|
||||
scheme := runtime.NewScheme()
|
||||
codecs := serializer.NewCodecFactory(scheme)
|
||||
if err := apiextensions.AddToScheme(scheme); err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
fuzzerFuncs := fuzzer.MergeFuzzerFuncs(apiextensionsfuzzer.Funcs)
|
||||
seed := int64(5577006791947779410)
|
||||
f := fuzzer.FuzzerFor(fuzzerFuncs, rand.NewSource(seed), codecs)
|
||||
// fuzz internal types
|
||||
schema := &apiextensions.JSONSchemaProps{}
|
||||
f.NilChance(0).NumElements(10, 10).MaxDepth(10).Fuzz(schema)
|
||||
|
||||
b.ReportAllocs()
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
if SchemaHas(schema, func(_ *apiextensions.JSONSchemaProps) bool {
|
||||
return false
|
||||
}) {
|
||||
b.Errorf("Function returned true")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var example = apiextensions.JSON(`"This is an example"`)
|
||||
|
||||
var validValidationSchema = &apiextensions.JSONSchemaProps{
|
||||
|
Loading…
Reference in New Issue
Block a user