From 6ba762818acd2615306ce0f99d41444580d5cbfc Mon Sep 17 00:00:00 2001 From: Juan Cruz Viotti Date: Thu, 21 Nov 2024 16:12:16 -0400 Subject: [PATCH] Handle dynamic steps in the evaluator (#200) Signed-off-by: Juan Cruz Viotti --- src/evaluator/context.cc | 18 +------ src/evaluator/evaluator.cc | 48 ++++++++++++------- .../sourcemeta/blaze/evaluator_context.h | 5 +- 3 files changed, 34 insertions(+), 37 deletions(-) diff --git a/src/evaluator/context.cc b/src/evaluator/context.cc index a350a3c9..a64dd855 100644 --- a/src/evaluator/context.cc +++ b/src/evaluator/context.cc @@ -8,8 +8,7 @@ namespace sourcemeta::blaze { auto EvaluationContext::push( const sourcemeta::jsontoolkit::Pointer &relative_schema_location, const sourcemeta::jsontoolkit::Pointer &relative_instance_location, - const std::size_t &schema_resource, const bool dynamic, const bool track) - -> void { + const bool track) -> void { // Guard against infinite recursion in a cheap manner, as // infinite recursion will manifest itself through huge // ever-growing evaluate paths @@ -35,30 +34,17 @@ auto EvaluationContext::push( // recursion this->evaluate_path_size += relative_schema_location.size(); } - - if (dynamic) { - // Note that we are potentially repeatedly pushing back the - // same schema resource over and over again. However, the - // logic for making sure this list is "pure" takes a lot of - // computation power. Being silly seems faster. - this->resources.push_back(schema_resource); - } } auto EvaluationContext::pop(const std::size_t relative_schema_location_size, const std::size_t relative_instance_location_size, - const bool dynamic, const bool track) -> void { + const bool track) -> void { if (track) { this->evaluate_path.pop_back(relative_schema_location_size); this->instance_location.pop_back(relative_instance_location_size); } else { this->evaluate_path_size -= relative_schema_location_size; } - - if (dynamic) { - assert(!this->resources.empty()); - this->resources.pop_back(); - } } auto EvaluationContext::hash( diff --git a/src/evaluator/evaluator.cc b/src/evaluator/evaluator.cc index f4318e35..cdbb949f 100644 --- a/src/evaluator/evaluator.cc +++ b/src/evaluator/evaluator.cc @@ -70,16 +70,20 @@ auto evaluate_step( const auto &step_category{std::get(step)}; \ const auto track{step_category.track || callback.has_value()}; \ context.push(step_category.relative_schema_location, \ - step_category.relative_instance_location, \ - step_category.schema_resource, step_category.dynamic, track); \ + step_category.relative_instance_location, track); \ + if (step_category.dynamic) { \ + context.resources.push_back(step_category.schema_resource); \ + } \ const auto &target{resolve_target( \ property_target, \ sourcemeta::jsontoolkit::get( \ instance, step_category.relative_instance_location))}; \ if (!(precondition)) { \ context.pop(step_category.relative_schema_location.size(), \ - step_category.relative_instance_location.size(), \ - step_category.dynamic, track); \ + step_category.relative_instance_location.size(), track); \ + if (step_category.dynamic) { \ + context.resources.pop_back(); \ + } \ SOURCEMETA_TRACE_END(trace_id, STRINGIFY(step_type)); \ return true; \ } \ @@ -94,14 +98,18 @@ auto evaluate_step( const auto &step_category{std::get(step)}; \ const auto track{step_category.track || callback.has_value()}; \ context.push(step_category.relative_schema_location, \ - step_category.relative_instance_location, \ - step_category.schema_resource, step_category.dynamic, track); \ + step_category.relative_instance_location, track); \ + if (step_category.dynamic) { \ + context.resources.push_back(step_category.schema_resource); \ + } \ const auto &maybe_target{resolve_string_target( \ property_target, instance, step_category.relative_instance_location)}; \ if (!maybe_target.has_value()) { \ context.pop(step_category.relative_schema_location.size(), \ - step_category.relative_instance_location.size(), \ - step_category.dynamic, track); \ + step_category.relative_instance_location.size(), track); \ + if (step_category.dynamic) { \ + context.resources.pop_back(); \ + } \ SOURCEMETA_TRACE_END(trace_id, STRINGIFY(step_type)); \ return true; \ } \ @@ -132,8 +140,10 @@ auto evaluate_step( } \ const auto track{step_category.track || callback.has_value()}; \ context.push(step_category.relative_schema_location, \ - step_category.relative_instance_location, \ - step_category.schema_resource, step_category.dynamic, track); \ + step_category.relative_instance_location, track); \ + if (step_category.dynamic) { \ + context.resources.push_back(step_category.schema_resource); \ + } \ assert(!step_category.relative_instance_location.empty()); \ if (callback.has_value()) { \ callback.value()(EvaluationType::Pre, true, step, context.evaluate_path, \ @@ -146,8 +156,10 @@ auto evaluate_step( const auto &step_category{std::get(step)}; \ const auto track{step_category.track || callback.has_value()}; \ context.push(step_category.relative_schema_location, \ - step_category.relative_instance_location, \ - step_category.schema_resource, step_category.dynamic, track); \ + step_category.relative_instance_location, track); \ + if (step_category.dynamic) { \ + context.resources.push_back(step_category.schema_resource); \ + } \ if (callback.has_value()) { \ callback.value()(EvaluationType::Pre, true, step, context.evaluate_path, \ context.instance_location, context.null); \ @@ -175,8 +187,10 @@ auto evaluate_step( context.null); \ } \ context.pop(step_category.relative_schema_location.size(), \ - step_category.relative_instance_location.size(), \ - step_category.dynamic, track); \ + step_category.relative_instance_location.size(), track); \ + if (step_category.dynamic) { \ + context.resources.pop_back(); \ + } \ SOURCEMETA_TRACE_END(trace_id, STRINGIFY(step_type)); \ return result; @@ -200,8 +214,7 @@ auto evaluate_step( const auto track{step_category.track || callback.has_value()}; \ assert(track); \ context.push(step_category.relative_schema_location, \ - step_category.relative_instance_location, \ - step_category.schema_resource, step_category.dynamic, track); \ + step_category.relative_instance_location, track); \ if (callback.has_value()) { \ callback.value()(EvaluationType::Pre, true, step, context.evaluate_path, \ destination, context.null); \ @@ -209,8 +222,7 @@ auto evaluate_step( destination, annotation_value); \ } \ context.pop(step_category.relative_schema_location.size(), \ - step_category.relative_instance_location.size(), \ - step_category.dynamic, track); \ + step_category.relative_instance_location.size(), track); \ SOURCEMETA_TRACE_END(trace_id, STRINGIFY(step_type)); \ return true; diff --git a/src/evaluator/include/sourcemeta/blaze/evaluator_context.h b/src/evaluator/include/sourcemeta/blaze/evaluator_context.h index 7a49f310..d7f61297 100644 --- a/src/evaluator/include/sourcemeta/blaze/evaluator_context.h +++ b/src/evaluator/include/sourcemeta/blaze/evaluator_context.h @@ -30,11 +30,10 @@ class SOURCEMETA_BLAZE_EVALUATOR_EXPORT EvaluationContext { auto push(const sourcemeta::jsontoolkit::Pointer &relative_schema_location, const sourcemeta::jsontoolkit::Pointer &relative_instance_location, - const std::size_t &schema_resource, const bool dynamic, const bool track) -> void; auto pop(const std::size_t relative_schema_location_size, - const std::size_t relative_instance_location_size, - const bool dynamic, const bool track) -> void; + const std::size_t relative_instance_location_size, const bool track) + -> void; /////////////////////////////////////////////// // References and anchors