Skip to content

Commit d386da2

Browse files
authored
Optimise SchemaFrame::standalone() (#2224)
Signed-off-by: Juan Cruz Viotti <jv@jviotti.com>
1 parent d1345c4 commit d386da2

File tree

2 files changed

+19
-14
lines changed

2 files changed

+19
-14
lines changed

src/core/jsonschema/frame.cc

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1035,7 +1035,20 @@ auto SchemaFrame::analyse(const JSON &root, const SchemaWalker &walker,
10351035
}
10361036

10371037
// A schema is standalone if all references can be resolved within itself
1038-
if (this->standalone()) {
1038+
this->standalone_ =
1039+
std::ranges::all_of(this->references_, [&](const auto &reference) {
1040+
assert(!reference.first.second.empty());
1041+
assert(reference.first.second.back().is_property());
1042+
// TODO: This check might need to be more elaborate given
1043+
// https://github.com/sourcemeta/core/issues/1390
1044+
return reference.first.second.back().to_property() == "$schema" ||
1045+
this->locations_.contains({SchemaReferenceType::Static,
1046+
reference.second.destination}) ||
1047+
this->locations_.contains({SchemaReferenceType::Dynamic,
1048+
reference.second.destination});
1049+
});
1050+
1051+
if (this->standalone_) {
10391052
// Find all dynamic anchors
10401053
// Values are pointers to full URIs in locations_
10411054
std::unordered_map<JSON::String, std::vector<const JSON::String *>>
@@ -1113,18 +1126,8 @@ auto SchemaFrame::reference(const SchemaReferenceType type,
11131126
return std::nullopt;
11141127
}
11151128

1116-
auto SchemaFrame::standalone() const -> bool {
1117-
return std::ranges::all_of(this->references_, [&](const auto &reference) {
1118-
assert(!reference.first.second.empty());
1119-
assert(reference.first.second.back().is_property());
1120-
// TODO: This check might need to be more elaborate given
1121-
// https://github.com/sourcemeta/core/issues/1390
1122-
return reference.first.second.back().to_property() == "$schema" ||
1123-
this->locations_.contains(
1124-
{SchemaReferenceType::Static, reference.second.destination}) ||
1125-
this->locations_.contains(
1126-
{SchemaReferenceType::Dynamic, reference.second.destination});
1127-
});
1129+
auto SchemaFrame::standalone() const noexcept -> bool {
1130+
return this->standalone_;
11281131
}
11291132

11301133
auto SchemaFrame::root() const noexcept -> const JSON::String & {
@@ -1392,6 +1395,7 @@ auto SchemaFrame::reset() -> void {
13921395
this->root_.clear();
13931396
this->locations_.clear();
13941397
this->references_.clear();
1398+
this->standalone_ = false;
13951399
}
13961400

13971401
auto SchemaFrame::populate_pointer_to_location() const -> void {

src/core/jsonschema/include/sourcemeta/core/jsonschema_frame.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ class SOURCEMETA_CORE_JSONSCHEMA_EXPORT SchemaFrame {
163163
-> std::optional<std::reference_wrapper<const ReferencesEntry>>;
164164

165165
/// Check whether the analysed schema has no external references
166-
[[nodiscard]] auto standalone() const -> bool;
166+
[[nodiscard]] auto standalone() const noexcept -> bool;
167167

168168
/// Get the root schema identifier (empty if none)
169169
[[nodiscard]] auto root() const noexcept -> const JSON::String &;
@@ -268,6 +268,7 @@ class SOURCEMETA_CORE_JSONSCHEMA_EXPORT SchemaFrame {
268268
mutable std::unordered_map<std::reference_wrapper<const WeakPointer>, bool,
269269
WeakPointer::Hasher, WeakPointer::Comparator>
270270
reachability_;
271+
bool standalone_{false};
271272
#if defined(_MSC_VER)
272273
#pragma warning(default : 4251 4275)
273274
#endif

0 commit comments

Comments
 (0)