Skip to content

Commit

Permalink
Optimize patternProperties set to wildcard schemas before 2019-09 (#…
Browse files Browse the repository at this point in the history
…1189)

Signed-off-by: Juan Cruz Viotti <[email protected]>
  • Loading branch information
jviotti authored Sep 12, 2024
1 parent 9959e1f commit 8e19ade
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 28 deletions.
22 changes: 15 additions & 7 deletions src/jsonschema/default_compiler_draft4.h
Original file line number Diff line number Diff line change
Expand Up @@ -470,13 +470,21 @@ auto compiler_draft4_applicator_patternproperties_conditional_annotation(
SchemaCompilerValueNone{}));
}

// Loop over the instance properties
children.push_back(make<SchemaCompilerLoopPropertiesRegex>(
// Treat this as an internal step
false, context, schema_context, relative_dynamic_context,
SchemaCompilerValueRegex{std::regex{pattern, std::regex::ECMAScript},
pattern},
std::move(substeps)));
// If the `patternProperties` subschema for the given pattern does
// nothing, then we can avoid generating an entire loop for it
if (!substeps.empty()) {
// Loop over the instance properties
children.push_back(make<SchemaCompilerLoopPropertiesRegex>(
// Treat this as an internal step
false, context, schema_context, relative_dynamic_context,
SchemaCompilerValueRegex{std::regex{pattern, std::regex::ECMAScript},
pattern},
std::move(substeps)));
}
}

if (children.empty()) {
return {};
}

// If the instance is an object...
Expand Down
60 changes: 39 additions & 21 deletions test/jsonschema/jsonschema_compile_draft4_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1391,16 +1391,7 @@ TEST(JSONSchema_compile_draft4, patternProperties_2) {
const sourcemeta::jsontoolkit::JSON instance{
sourcemeta::jsontoolkit::parse("{ \"foo\": 1, \"bar\": 2 }")};

EVALUATE_WITH_TRACE_FAST_SUCCESS(compiled_schema, instance, 1);
EVALUATE_TRACE_PRE(0, LogicalWhenType, "/patternProperties",
"#/patternProperties", "");
EVALUATE_TRACE_POST_SUCCESS(0, LogicalWhenType, "/patternProperties",
"#/patternProperties", "");

EVALUATE_TRACE_POST_DESCRIBE(
instance, 0,
"The object value was expected to validate against the single defined "
"pattern property subschema");
EVALUATE_WITH_TRACE_FAST_SUCCESS(compiled_schema, instance, 0);
}

TEST(JSONSchema_compile_draft4, patternProperties_3) {
Expand All @@ -1420,17 +1411,7 @@ TEST(JSONSchema_compile_draft4, patternProperties_3) {
const sourcemeta::jsontoolkit::JSON instance{
sourcemeta::jsontoolkit::parse("{ \"foo\": 1, \"bar\": 2 }")};

EVALUATE_WITH_TRACE_FAST_SUCCESS(compiled_schema, instance, 1);

EVALUATE_TRACE_PRE(0, LogicalWhenType, "/patternProperties",
"#/patternProperties", "");
EVALUATE_TRACE_POST_SUCCESS(0, LogicalWhenType, "/patternProperties",
"#/patternProperties", "");

EVALUATE_TRACE_POST_DESCRIBE(
instance, 0,
"The object value was expected to validate against the single defined "
"pattern property subschema");
EVALUATE_WITH_TRACE_FAST_SUCCESS(compiled_schema, instance, 0);
}

TEST(JSONSchema_compile_draft4, patternProperties_4) {
Expand Down Expand Up @@ -1615,6 +1596,43 @@ TEST(JSONSchema_compile_draft4, patternProperties_7) {
"pattern property subschema");
}

TEST(JSONSchema_compile_draft4, patternProperties_8) {
const sourcemeta::jsontoolkit::JSON schema{
sourcemeta::jsontoolkit::parse(R"JSON({
"$schema": "http://json-schema.org/draft-04/schema#",
"patternProperties": { "^@": true },
"additionalProperties": { "type": "string" }
})JSON")};

const auto compiled_schema{sourcemeta::jsontoolkit::compile(
schema, sourcemeta::jsontoolkit::default_schema_walker,
sourcemeta::jsontoolkit::official_resolver,
sourcemeta::jsontoolkit::default_schema_compiler)};

const sourcemeta::jsontoolkit::JSON instance{
sourcemeta::jsontoolkit::parse("{ \"@foo\": 1, \"bar\": \"baz\" }")};

EVALUATE_WITH_TRACE_FAST_SUCCESS(compiled_schema, instance, 2);

EVALUATE_TRACE_PRE(0, LoopPropertiesExcept, "/additionalProperties",
"#/additionalProperties", "");
EVALUATE_TRACE_PRE(1, AssertionTypeStrict, "/additionalProperties/type",
"#/additionalProperties/type", "/bar");

EVALUATE_TRACE_POST_SUCCESS(0, AssertionTypeStrict,
"/additionalProperties/type",
"#/additionalProperties/type", "/bar");
EVALUATE_TRACE_POST_SUCCESS(1, LoopPropertiesExcept, "/additionalProperties",
"#/additionalProperties", "");

EVALUATE_TRACE_POST_DESCRIBE(instance, 0,
"The value was expected to be of type string");
EVALUATE_TRACE_POST_DESCRIBE(
instance, 1,
"The object properties not covered by other adjacent object keywords "
"were expected to validate against this subschema");
}

TEST(JSONSchema_compile_draft4, additionalProperties_1) {
const sourcemeta::jsontoolkit::JSON schema{
sourcemeta::jsontoolkit::parse(R"JSON({
Expand Down

4 comments on commit 8e19ade

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark (macos/llvm)

Benchmark suite Current: 8e19ade Previous: 9959e1f Ratio
JSONSchema_Validate_Draft4_Meta_1_No_Callback 729.2259159815563 ns/iter 860.1924572099057 ns/iter 0.85
JSONSchema_Validate_Draft4_Required_Properties 783.4522755427253 ns/iter 900.2756496918734 ns/iter 0.87
JSONSchema_Validate_Draft4_Optional_Properties_Minimal_Match 142.60770723519462 ns/iter 164.33741192037593 ns/iter 0.87
JSONSchema_Validate_Draft4_Items_Schema 1981.7646428004973 ns/iter 2187.7293666896176 ns/iter 0.91
JSONSchema_Validate_Draft4_Nested_Object 1218.7000199129448 ns/iter 1318.0500697691245 ns/iter 0.92
JSONSchema_Validate_Draft4_Properties_Triad_Optional 1308.8919149587318 ns/iter 1424.3751930556991 ns/iter 0.92
JSONSchema_Validate_Draft4_Properties_Triad_Closed 966.8050658239378 ns/iter 1036.6805817005236 ns/iter 0.93
JSONSchema_Validate_Draft4_Properties_Triad_Required 1332.716966606539 ns/iter 1447.221323094018 ns/iter 0.92
JSONSchema_Validate_Draft4_Non_Recursive_Ref 1557.8809775030786 ns/iter 1715.9723310554687 ns/iter 0.91
JSONSchema_Validate_Draft4_Pattern_Properties_True 1298.0003340271753 ns/iter 2599.1591901258803 ns/iter 0.50

This comment was automatically generated by workflow using github-action-benchmark.

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark (linux/llvm)

Benchmark suite Current: 8e19ade Previous: 9959e1f Ratio
JSONSchema_Validate_Draft4_Meta_1_No_Callback 16390.157861008476 ns/iter 16493.874066945 ns/iter 0.99
JSONSchema_Validate_Draft4_Required_Properties 6683.140428864843 ns/iter 6596.7442602773735 ns/iter 1.01
JSONSchema_Validate_Draft4_Optional_Properties_Minimal_Match 1638.282423644848 ns/iter 1667.0908480738394 ns/iter 0.98
JSONSchema_Validate_Draft4_Items_Schema 101797.30592395469 ns/iter 102160.41978726503 ns/iter 1.00
JSONSchema_Validate_Draft4_Nested_Object 47504.917347496885 ns/iter 47690.828184547594 ns/iter 1.00
JSONSchema_Validate_Draft4_Properties_Triad_Optional 8009.690801003745 ns/iter 8027.300906559587 ns/iter 1.00
JSONSchema_Validate_Draft4_Properties_Triad_Closed 7455.075406935326 ns/iter 7487.039361553931 ns/iter 1.00
JSONSchema_Validate_Draft4_Properties_Triad_Required 8214.782690378115 ns/iter 8213.957437345201 ns/iter 1.00
JSONSchema_Validate_Draft4_Non_Recursive_Ref 77086.67579202124 ns/iter 77241.89286498258 ns/iter 1.00
JSONSchema_Validate_Draft4_Pattern_Properties_True 6141.686634824218 ns/iter 10077.137492126014 ns/iter 0.61

This comment was automatically generated by workflow using github-action-benchmark.

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark (linux/gcc)

Benchmark suite Current: 8e19ade Previous: 9959e1f Ratio
JSONSchema_Validate_Draft4_Meta_1_No_Callback 1111.093942538803 ns/iter 1137.8396604036463 ns/iter 0.98
JSONSchema_Validate_Draft4_Required_Properties 2289.560508156796 ns/iter 2395.0251305508523 ns/iter 0.96
JSONSchema_Validate_Draft4_Optional_Properties_Minimal_Match 200.009947128165 ns/iter 192.7588232752665 ns/iter 1.04
JSONSchema_Validate_Draft4_Items_Schema 3564.8858236484775 ns/iter 3605.537419460414 ns/iter 0.99
JSONSchema_Validate_Draft4_Nested_Object 1702.6830949565804 ns/iter 1744.948762432967 ns/iter 0.98
JSONSchema_Validate_Draft4_Properties_Triad_Optional 1695.1832815895204 ns/iter 1716.5968664347563 ns/iter 0.99
JSONSchema_Validate_Draft4_Properties_Triad_Closed 1387.3433879265365 ns/iter 1407.4107281360866 ns/iter 0.99
JSONSchema_Validate_Draft4_Properties_Triad_Required 1764.117300169156 ns/iter 1790.1480478903732 ns/iter 0.99
JSONSchema_Validate_Draft4_Non_Recursive_Ref 2731.708552826035 ns/iter 2810.960409425121 ns/iter 0.97
JSONSchema_Validate_Draft4_Pattern_Properties_True 2336.953321063876 ns/iter 3968.978388363654 ns/iter 0.59

This comment was automatically generated by workflow using github-action-benchmark.

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark (windows/msvc)

Benchmark suite Current: 8e19ade Previous: 9959e1f Ratio
JSONSchema_Validate_Draft4_Meta_1_No_Callback 3097.5736607134404 ns/iter 3119.204464285628 ns/iter 0.99
JSONSchema_Validate_Draft4_Required_Properties 1644.5178571429558 ns/iter 1637.6573660714655 ns/iter 1.00
JSONSchema_Validate_Draft4_Optional_Properties_Minimal_Match 602.638214285735 ns/iter 615.6332142856919 ns/iter 0.98
JSONSchema_Validate_Draft4_Items_Schema 11487.128571425435 ns/iter 11282.723437499699 ns/iter 1.02
JSONSchema_Validate_Draft4_Nested_Object 6536.537946428515 ns/iter 6509.093749999449 ns/iter 1.00
JSONSchema_Validate_Draft4_Properties_Triad_Optional 5691.988392858402 ns/iter 5752.680000000509 ns/iter 0.99
JSONSchema_Validate_Draft4_Properties_Triad_Closed 4710.593290708664 ns/iter 4762.572907529241 ns/iter 0.99
JSONSchema_Validate_Draft4_Properties_Triad_Required 5777.740000000904 ns/iter 5847.480357143046 ns/iter 0.99
JSONSchema_Validate_Draft4_Non_Recursive_Ref 7338.311383929659 ns/iter 7242.4620535700105 ns/iter 1.01
JSONSchema_Validate_Draft4_Pattern_Properties_True 8028.24665178749 ns/iter 15381.665178568126 ns/iter 0.52

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.