Skip to content

Commit 12555b9

Browse files
committed
Add extra options
1 parent fb987b2 commit 12555b9

File tree

4 files changed

+69
-46
lines changed

4 files changed

+69
-46
lines changed

src/compiler/default_compiler_2019_09.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -355,14 +355,18 @@ auto compiler_2019_09_applicator_unevaluatedproperties(
355355
} else if (keyword == "patternProperties") {
356356
if (subschema.is_object()) {
357357
for (const auto &property : subschema.as_object()) {
358-
const auto maybe_prefix{pattern_as_prefix(property.first)};
358+
std::optional<std::basic_string<char>> maybe_prefix{std::nullopt};
359+
if (options.simplify_regexes) {
360+
maybe_prefix = pattern_as_prefix(property.first);
361+
}
359362
if (maybe_prefix.has_value()) {
360363
filter_prefixes.push_back(maybe_prefix.value());
361364
} else {
362365
filter_regexes.push_back(
363366
{parse_regex(property.first, schema_context.base,
364367
schema_context.relative_pointer.initial().concat(
365-
{"patternProperties"})),
368+
{"patternProperties"}),
369+
options.simplify_regexes),
366370
property.first});
367371
}
368372
}

src/compiler/default_compiler_draft4.h

Lines changed: 35 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,10 @@
1616

1717
static auto parse_regex(const std::string &pattern,
1818
const sourcemeta::core::URI &base,
19-
const sourcemeta::core::Pointer &schema_location)
19+
const sourcemeta::core::Pointer &schema_location,
20+
const bool simplify_regexes)
2021
-> sourcemeta::core::Regex<sourcemeta::core::JSON::String> {
21-
const auto result{sourcemeta::core::to_regex(pattern)};
22+
const auto result{sourcemeta::core::to_regex(pattern, simplify_regexes)};
2223
if (!result.has_value()) {
2324
std::ostringstream message;
2425
message << "Invalid regular expression: " << pattern;
@@ -252,7 +253,8 @@ auto compiler_draft4_core_ref(const Context &context,
252253
.pointer)) ||
253254
schema_context.references.contains(reference.destination)};
254255

255-
if (!is_recursive && direct_children_references <= 5) {
256+
if (!is_recursive &&
257+
direct_children_references <= options.expand_ref_threshold) {
256258
if (context.mode == Mode::FastValidation &&
257259
// Expanding references inline when dynamic scoping is required
258260
// may not work, as we might omit the instruction that introduces
@@ -610,8 +612,9 @@ auto compiler_draft4_validation_required(const Context &context,
610612
if (context.mode == Mode::FastValidation &&
611613
properties_set.size() == 3 &&
612614
std::all_of(properties_set.begin(), properties_set.end(),
613-
[&hasher](const auto &property) {
614-
return hasher.is_perfect(property.second);
615+
[&hasher, &options](const auto &property) {
616+
return options.perfect_hash &&
617+
hasher.is_perfect(property.second);
615618
})) {
616619
std::vector<std::pair<ValueString, ValueStringSet::hash_type>> hashes;
617620
for (const auto &property : properties_set) {
@@ -1018,7 +1021,7 @@ auto compiler_draft4_applicator_properties_with_options(
10181021
perfect_hashes;
10191022
for (const auto &entry : required) {
10201023
assert(required.contains(entry.first, entry.second));
1021-
if (hasher.is_perfect(entry.second)) {
1024+
if (options.perfect_hash && hasher.is_perfect(entry.second)) {
10221025
perfect_hashes.emplace_back(entry.first, entry.second);
10231026
}
10241027
}
@@ -1249,14 +1252,18 @@ auto compiler_draft4_applicator_patternproperties_with_options(
12491252
make(sourcemeta::blaze::InstructionIndex::LoopPropertiesRegexClosed,
12501253
context, schema_context, dynamic_context,
12511254
ValueRegex{parse_regex(pattern, schema_context.base,
1252-
schema_context.relative_pointer),
1255+
schema_context.relative_pointer,
1256+
options.simplify_regexes),
12531257
pattern},
12541258
std::move(substeps)));
12551259

12561260
// If the `patternProperties` subschema for the given pattern does
12571261
// nothing, then we can avoid generating an entire loop for it
12581262
} else if (!substeps.empty()) {
1259-
const auto maybe_prefix{pattern_as_prefix(pattern)};
1263+
std::optional<std::basic_string<char>> maybe_prefix{std::nullopt};
1264+
if (options.simplify_regexes) {
1265+
maybe_prefix = pattern_as_prefix(pattern);
1266+
}
12601267
if (maybe_prefix.has_value()) {
12611268
children.push_back(
12621269
make(sourcemeta::blaze::InstructionIndex::LoopPropertiesStartsWith,
@@ -1267,7 +1274,8 @@ auto compiler_draft4_applicator_patternproperties_with_options(
12671274
make(sourcemeta::blaze::InstructionIndex::LoopPropertiesRegex,
12681275
context, schema_context, dynamic_context,
12691276
ValueRegex{parse_regex(pattern, schema_context.base,
1270-
schema_context.relative_pointer),
1277+
schema_context.relative_pointer,
1278+
options.simplify_regexes),
12711279
pattern},
12721280
std::move(substeps)));
12731281
}
@@ -1323,14 +1331,18 @@ auto compiler_draft4_applicator_additionalproperties_with_options(
13231331
schema_context.schema.at("patternProperties").is_object()) {
13241332
for (const auto &entry :
13251333
schema_context.schema.at("patternProperties").as_object()) {
1326-
const auto maybe_prefix{pattern_as_prefix(entry.first)};
1334+
std::optional<std::basic_string<char>> maybe_prefix{std::nullopt};
1335+
if (options.simplify_regexes) {
1336+
maybe_prefix = pattern_as_prefix(entry.first);
1337+
}
13271338
if (maybe_prefix.has_value()) {
13281339
filter_prefixes.push_back(maybe_prefix.value());
13291340
} else {
13301341
filter_regexes.push_back(
13311342
{parse_regex(entry.first, schema_context.base,
13321343
schema_context.relative_pointer.initial().concat(
1333-
{"patternProperties"})),
1344+
{"patternProperties"}),
1345+
options.simplify_regexes),
13341346
entry.first});
13351347
}
13361348
}
@@ -1450,7 +1462,7 @@ auto compiler_draft4_applicator_additionalproperties(
14501462

14511463
auto compiler_draft4_validation_pattern(const Context &context,
14521464
const SchemaContext &schema_context,
1453-
const CompileOptions &,
1465+
const CompileOptions &options,
14541466
const DynamicContext &dynamic_context,
14551467
const Instructions &) -> Instructions {
14561468
assert(schema_context.schema.at(dynamic_context.keyword).is_string());
@@ -1466,13 +1478,14 @@ auto compiler_draft4_validation_pattern(const Context &context,
14661478
return {make(sourcemeta::blaze::InstructionIndex::AssertionRegex, context,
14671479
schema_context, dynamic_context,
14681480
ValueRegex{parse_regex(regex_string, schema_context.base,
1469-
schema_context.relative_pointer),
1481+
schema_context.relative_pointer,
1482+
options.simplify_regexes),
14701483
regex_string})};
14711484
}
14721485

14731486
auto compiler_draft4_validation_format(const Context &context,
14741487
const SchemaContext &schema_context,
1475-
const CompileOptions &,
1488+
const CompileOptions &options,
14761489
const DynamicContext &dynamic_context,
14771490
const Instructions &) -> Instructions {
14781491
if (!schema_context.schema.at(dynamic_context.keyword).is_string()) {
@@ -1507,7 +1520,8 @@ auto compiler_draft4_validation_format(const Context &context,
15071520
make(sourcemeta::blaze::InstructionIndex::AssertionRegex, context, \
15081521
schema_context, dynamic_context, \
15091522
ValueRegex{parse_regex(regular_expression, schema_context.base, \
1510-
schema_context.relative_pointer), \
1523+
schema_context.relative_pointer, \
1524+
options.simplify_regexes), \
15111525
(regular_expression)})}; \
15121526
}
15131527

@@ -1916,7 +1930,7 @@ auto compiler_draft4_applicator_dependencies(
19161930

19171931
auto compiler_draft4_validation_enum(const Context &context,
19181932
const SchemaContext &schema_context,
1919-
const CompileOptions &,
1933+
const CompileOptions &options,
19201934
const DynamicContext &dynamic_context,
19211935
const Instructions &) -> Instructions {
19221936
assert(schema_context.schema.at(dynamic_context.keyword).is_array());
@@ -1932,32 +1946,32 @@ auto compiler_draft4_validation_enum(const Context &context,
19321946
std::vector<std::pair<sourcemeta::blaze::ValueString,
19331947
sourcemeta::blaze::ValueStringSet::hash_type>>
19341948
perfect_string_hashes;
1935-
ValueSet options;
1949+
ValueSet enums;
19361950
sourcemeta::core::PropertyHashJSON<ValueString> hasher;
19371951
for (const auto &option :
19381952
schema_context.schema.at(dynamic_context.keyword).as_array()) {
19391953
if (option.is_string()) {
19401954
const auto hash{hasher(option.to_string())};
1941-
if (hasher.is_perfect(hash)) {
1955+
if (options.perfect_hash && hasher.is_perfect(hash)) {
19421956
perfect_string_hashes.emplace_back(option.to_string(), hash);
19431957
}
19441958
}
19451959

1946-
options.insert(option);
1960+
enums.insert(option);
19471961
}
19481962

19491963
// Only apply this optimisation on fast validation, as it
19501964
// can affect error messages
19511965
if (context.mode == Mode::FastValidation &&
1952-
perfect_string_hashes.size() == options.size()) {
1966+
perfect_string_hashes.size() == enums.size()) {
19531967
return {
19541968
make(sourcemeta::blaze::InstructionIndex::AssertionEqualsAnyStringHash,
19551969
context, schema_context, dynamic_context,
19561970
to_string_hashes(perfect_string_hashes))};
19571971
}
19581972

19591973
return {make(sourcemeta::blaze::InstructionIndex::AssertionEqualsAny, context,
1960-
schema_context, dynamic_context, std::move(options))};
1974+
schema_context, dynamic_context, std::move(enums))};
19611975
}
19621976

19631977
auto compiler_draft4_validation_uniqueitems(

src/compiler/include/sourcemeta/blaze/compiler.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,13 @@ struct DynamicContext {
6262
};
6363

6464
struct CompileOptions {
65+
const bool perfect_hash;
66+
const size_t expand_ref_threshold;
6567
const bool unroll;
68+
const bool simplify_regexes;
6669
};
6770

68-
const CompileOptions default_compile_options{true};
71+
const CompileOptions default_compile_options{true, 5, true, true};
6972

7073
/* auto default_compile_options = CompileOptions{true}; */
7174

vendor/core/src/core/regex/include/sourcemeta/core/regex.h

Lines changed: 24 additions & 22 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)