diff options
author | Hop311 <Hop3114@gmail.com> | 2024-07-19 00:26:16 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-19 00:26:16 +0200 |
commit | a673f89bb2705826b1c646365eab1775727372b7 (patch) | |
tree | 3f2a270b5b85f91a22289091084a30c105f10f4d /src/openvic-simulation/dataloader | |
parent | 93d095ba30747c7158882668577c854be7ea39a1 (diff) | |
parent | d236dcf30c001e540377184565f4d173ed56f76e (diff) |
Merge pull request #171 from OpenVicProject/optimize/string-interning
Optimize some string interning cases
Diffstat (limited to 'src/openvic-simulation/dataloader')
-rw-r--r-- | src/openvic-simulation/dataloader/Dataloader.cpp | 6 | ||||
-rw-r--r-- | src/openvic-simulation/dataloader/NodeTools.cpp | 136 | ||||
-rw-r--r-- | src/openvic-simulation/dataloader/NodeTools.hpp | 13 |
3 files changed, 106 insertions, 49 deletions
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 <type_traits> +#include <concepts> +#include <string_view> +#include <openvic-dataloader/detail/SymbolIntern.hpp> #include <openvic-dataloader/detail/Utility.hpp> #include <openvic-dataloader/v2script/AbstractSyntaxTree.hpp> @@ -61,13 +63,13 @@ static NodeCallback auto _abstract_statement_node_callback(Callback<_NodeStateme } template<std::derived_from<ast::FlatValue> T> -static Callback<T const*> auto _abstract_string_node_callback(Callback<std::string_view> auto&& callback, bool allow_empty) { +static Callback<T const*> auto _abstract_symbol_node_callback(Callback<ovdl::symbol<char>> 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<T const*> auto _abstract_string_node_callback(Callback<std::stri }; } +template<std::derived_from<ast::FlatValue> T> +static Callback<T const*> auto _abstract_string_node_callback(Callback<std::string_view> auto callback, bool allow_empty) { + return _abstract_symbol_node_callback<T>( + [callback](ovdl::symbol<char> symbol) -> bool { + return callback(symbol.view()); + }, + allow_empty + ); +} + node_callback_t NodeTools::expect_identifier(callback_t<std::string_view> callback) { return _expect_type<ast::IdentifierValue>(_abstract_string_node_callback<ast::IdentifierValue>(callback, false)); } +static NodeCallback auto _expect_identifier(Callback<ovdl::symbol<char>> auto callback) { + return _expect_type<ast::IdentifierValue>(_abstract_symbol_node_callback<ast::IdentifierValue>(callback, false)); +} + node_callback_t NodeTools::expect_string(callback_t<std::string_view> callback, bool allow_empty) { return _expect_type<ast::StringValue>(_abstract_string_node_callback<ast::StringValue>(callback, allow_empty)); } +static NodeCallback auto _expect_string(Callback<ovdl::symbol<char>> auto callback, bool allow_empty) { + return _expect_type<ast::StringValue>(_abstract_symbol_node_callback<ast::StringValue>(callback, allow_empty)); +} + + node_callback_t NodeTools::expect_identifier_or_string(callback_t<std::string_view> 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<size_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<ast::AssignStatement>(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<typename Key> +static node_callback_t _expect_key(Key key, NodeCallback auto callback, bool* key_found, bool allow_duplicates) { + if constexpr (std::same_as<Key, ovdl::symbol<char>>) { + 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<Key, std::string_view>) { + return expect_identifier(assign_variable_callback(left)); + } else if (std::same_as<Key, ovdl::symbol<char>>) { + return _expect_identifier(assign_variable_callback_cast<ovdl::symbol<char>>(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<ast::AssignStatement>(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<Key, std::string_view>) { + 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<char> 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 <optional> #include <type_traits> +#include <openvic-dataloader/detail/SymbolIntern.hpp> #include <openvic-dataloader/v2script/AbstractSyntaxTree.hpp> #include <tsl/ordered_set.h> @@ -173,6 +174,10 @@ namespace OpenVic { node_callback_t expect_length(callback_t<size_t> callback); node_callback_t expect_key( + ovdl::symbol<char> 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<StringMapCase Case> - constexpr bool add_key_map_entries(template_key_map_t<Case>& key_map) { + template<IsOrderedMap Map> + constexpr bool add_key_map_entries(Map&& key_map) { return true; } - template<StringMapCase Case> - constexpr bool add_key_map_entries(template_key_map_t<Case>&& key_map) { - return add_key_map_entries(key_map); - } template<IsOrderedMap Map, typename... Args> bool add_key_map_entries( |