From d236dcf30c001e540377184565f4d173ed56f76e Mon Sep 17 00:00:00 2001 From: Spartan322 Date: Sat, 6 Jul 2024 10:40:57 -0400 Subject: Optimize some string interning cases --- src/openvic-simulation/dataloader/Dataloader.cpp | 6 +- src/openvic-simulation/dataloader/NodeTools.cpp | 136 ++++++++++++++++------- src/openvic-simulation/dataloader/NodeTools.hpp | 13 ++- 3 files changed, 106 insertions(+), 49 deletions(-) (limited to 'src/openvic-simulation/dataloader') diff --git a/src/openvic-simulation/dataloader/Dataloader.cpp b/src/openvic-simulation/dataloader/Dataloader.cpp index 4fbd86b..2058ce5 100644 --- a/src/openvic-simulation/dataloader/Dataloader.cpp +++ b/src/openvic-simulation/dataloader/Dataloader.cpp @@ -371,7 +371,7 @@ bool Dataloader::_load_units(DefinitionManager& definition_manager) const { definition_manager.get_economy_manager().get_good_definition_manager(), definition_manager.get_map_definition().get_terrain_type_manager(), definition_manager.get_modifier_manager(), - parse_defines(file).get_file_node() + parse_defines(file) ); } ); @@ -905,7 +905,7 @@ bool Dataloader::load_defines(DefinitionManager& definition_manager) { ret = false; } if (!definition_manager.get_economy_manager().load_production_types_file(definition_manager.get_pop_manager(), - parse_defines_cached(lookup_file(production_types_file)).get_file_node() + parse_defines_cached(lookup_file(production_types_file)) )) { Logger::error("Failed to load production types!"); ret = false; @@ -1001,7 +1001,7 @@ bool Dataloader::load_defines(DefinitionManager& definition_manager) { ret = false; } if (!definition_manager.get_military_manager().get_wargoal_type_manager().load_wargoal_file( - parse_defines_cached(lookup_file(cb_types_file)).get_file_node() + parse_defines_cached(lookup_file(cb_types_file)) )) { Logger::error("Failed to load wargoals!"); ret = false; diff --git a/src/openvic-simulation/dataloader/NodeTools.cpp b/src/openvic-simulation/dataloader/NodeTools.cpp index 8ed82eb..25c5041 100644 --- a/src/openvic-simulation/dataloader/NodeTools.cpp +++ b/src/openvic-simulation/dataloader/NodeTools.cpp @@ -1,7 +1,9 @@ #include "NodeTools.hpp" -#include +#include +#include +#include #include #include @@ -61,13 +63,13 @@ static NodeCallback auto _abstract_statement_node_callback(Callback<_NodeStateme } template T> -static Callback auto _abstract_string_node_callback(Callback auto&& callback, bool allow_empty) { +static Callback auto _abstract_symbol_node_callback(Callback> auto&& callback, bool allow_empty) { return [callback = FWD(callback), allow_empty](T const* node) -> bool { if (allow_empty) { - return callback(node->value().view()); + return callback(node->value()); } else { if (node->value()) { - return callback(node->value().view()); + return callback(node->value()); } else { Logger::error("Invalid string value - empty!"); return false; @@ -76,14 +78,33 @@ static Callback auto _abstract_string_node_callback(Callback T> +static Callback auto _abstract_string_node_callback(Callback auto callback, bool allow_empty) { + return _abstract_symbol_node_callback( + [callback](ovdl::symbol symbol) -> bool { + return callback(symbol.view()); + }, + allow_empty + ); +} + node_callback_t NodeTools::expect_identifier(callback_t callback) { return _expect_type(_abstract_string_node_callback(callback, false)); } +static NodeCallback auto _expect_identifier(Callback> auto callback) { + return _expect_type(_abstract_symbol_node_callback(callback, false)); +} + node_callback_t NodeTools::expect_string(callback_t callback, bool allow_empty) { return _expect_type(_abstract_string_node_callback(callback, allow_empty)); } +static NodeCallback auto _expect_string(Callback> auto callback, bool allow_empty) { + return _expect_type(_abstract_symbol_node_callback(callback, allow_empty)); +} + + node_callback_t NodeTools::expect_identifier_or_string(callback_t callback, bool allow_empty) { return [callback, allow_empty](ast::NodeCPtr node) -> bool { if (node != nullptr) { @@ -335,48 +356,83 @@ node_callback_t NodeTools::expect_length(callback_t callback) { }; } -node_callback_t NodeTools::expect_key(std::string_view key, node_callback_t callback, bool* key_found, bool allow_duplicates) { - return _abstract_statement_node_callback( - [key, callback, key_found, allow_duplicates](_NodeStatementRange list) -> bool { - bool ret = true; - size_t keys_found = 0; - for (auto sub_node : list) { - auto const* assign_node = dryad::node_try_cast(sub_node); - if (assign_node == nullptr) { - continue; - } - std::string_view left; - if (!expect_identifier(assign_variable_callback(left))(assign_node->left())) { - continue; - } - if (left == key) { - if (keys_found++ == 0) { - ret &= callback(assign_node->right()); - if (allow_duplicates) { - break; - } +template +static node_callback_t _expect_key(Key key, NodeCallback auto callback, bool* key_found, bool allow_duplicates) { + if constexpr (std::same_as>) { + if (!key) { + if (key_found != nullptr) { + *key_found = false; + } + return [](ast::NodeCPtr) -> bool { + Logger::error("Failed to find expected interned key."); + return false; + }; + } + } + + static constexpr auto assign_left = [](Key& left) { + if constexpr (std::same_as) { + return expect_identifier(assign_variable_callback(left)); + } else if (std::same_as>) { + return _expect_identifier(assign_variable_callback_cast>(left)); + } + }; + + return _abstract_statement_node_callback([key, callback, key_found, allow_duplicates](_NodeStatementRange list) -> bool { + bool ret = true; + size_t keys_found = 0; + for (auto sub_node : list) { + auto const* assign_node = dryad::node_try_cast(sub_node); + if (assign_node == nullptr) { + continue; + } + Key left; + if (!assign_left(left)(assign_node->left())) { + continue; + } + if (left == key) { + if (keys_found++ == 0) { + ret &= callback(assign_node->right()); + if (allow_duplicates) { + break; } } } - if (keys_found == 0) { - if (key_found != nullptr) { - *key_found = false; - } else { - Logger::error("Failed to find expected key: \"", key, "\""); - } - ret = false; + } + std::string_view key_str = [&] { + if constexpr (std::same_as) { + return key; } else { - if (key_found != nullptr) { - *key_found = true; - } - if (!allow_duplicates && keys_found > 1) { - Logger::error("Found ", keys_found, " instances of key: \"", key, "\" (expected 1)"); - ret = false; - } + return key.view(); + } + }(); + if (keys_found == 0) { + if (key_found != nullptr) { + *key_found = false; + } else { + Logger::error("Failed to find expected key: \"", key_str, "\""); + } + ret = false; + } else { + if (key_found != nullptr) { + *key_found = true; + } + if (!allow_duplicates && keys_found > 1) { + Logger::error("Found ", keys_found, " instances of key: \"", key_str, "\" (expected 1)"); + ret = false; } - return ret; } - ); + return ret; + }); +} + +node_callback_t NodeTools::expect_key(std::string_view key, node_callback_t callback, bool* key_found, bool allow_duplicates) { + return _expect_key(key, callback, key_found, allow_duplicates); +} + +node_callback_t +NodeTools::expect_key(ovdl::symbol key, node_callback_t callback, bool* key_found, bool allow_duplicates) { + return _expect_key(key, callback, key_found, allow_duplicates); } node_callback_t NodeTools::expect_dictionary_and_length(length_callback_t length_callback, key_value_callback_t callback) { diff --git a/src/openvic-simulation/dataloader/NodeTools.hpp b/src/openvic-simulation/dataloader/NodeTools.hpp index acf5a41..30cba65 100644 --- a/src/openvic-simulation/dataloader/NodeTools.hpp +++ b/src/openvic-simulation/dataloader/NodeTools.hpp @@ -5,6 +5,7 @@ #include #include +#include #include #include @@ -172,6 +173,10 @@ namespace OpenVic { node_callback_t expect_list(node_callback_t callback); node_callback_t expect_length(callback_t callback); + node_callback_t expect_key( + ovdl::symbol key, node_callback_t callback, bool* key_found = nullptr, bool allow_duplicates = false + ); + node_callback_t expect_key( std::string_view key, node_callback_t callback, bool* key_found = nullptr, bool allow_duplicates = false ); @@ -269,14 +274,10 @@ namespace OpenVic { return ret; } - template - constexpr bool add_key_map_entries(template_key_map_t& key_map) { + template + constexpr bool add_key_map_entries(Map&& key_map) { return true; } - template - constexpr bool add_key_map_entries(template_key_map_t&& key_map) { - return add_key_map_entries(key_map); - } template bool add_key_map_entries( -- cgit v1.2.3-56-ga3b1