From b4eb8fbd4f31bf7f43bfefc60ddf3e58a76c06cc Mon Sep 17 00:00:00 2001 From: Markus Blatt Date: Fri, 24 Jun 2022 09:32:10 +0200 Subject: [PATCH 1/4] OrderedMap: Remove template parameter for key type. It is only used with std::string anyway. --- .../EclipseState/Grid/FaultCollection.hpp | 2 +- .../EclipseState/Tables/SimpleTable.hpp | 2 +- .../EclipseState/Tables/TableSchema.hpp | 2 +- .../eclipse/EclipseState/Util/OrderedMap.hpp | 40 ++++++++----------- opm/input/eclipse/Schedule/UDQ/UDQConfig.hpp | 2 +- tests/parser/OrderedMapTests.cpp | 8 ++-- 6 files changed, 24 insertions(+), 32 deletions(-) diff --git a/opm/input/eclipse/EclipseState/Grid/FaultCollection.hpp b/opm/input/eclipse/EclipseState/Grid/FaultCollection.hpp index f8caee87a..2bd6a65ff 100644 --- a/opm/input/eclipse/EclipseState/Grid/FaultCollection.hpp +++ b/opm/input/eclipse/EclipseState/Grid/FaultCollection.hpp @@ -62,7 +62,7 @@ private: void addFaultFaces(const GridDims& grid, const DeckRecord& faultRecord, const std::string& faultName); - OrderedMap m_faults; + OrderedMap m_faults; }; } diff --git a/opm/input/eclipse/EclipseState/Tables/SimpleTable.hpp b/opm/input/eclipse/EclipseState/Tables/SimpleTable.hpp index 15aa7ca8b..fdca73862 100644 --- a/opm/input/eclipse/EclipseState/Tables/SimpleTable.hpp +++ b/opm/input/eclipse/EclipseState/Tables/SimpleTable.hpp @@ -84,7 +84,7 @@ namespace Opm { protected: TableSchema m_schema; - OrderedMap m_columns; + OrderedMap m_columns; bool m_jfunc = false; }; } diff --git a/opm/input/eclipse/EclipseState/Tables/TableSchema.hpp b/opm/input/eclipse/EclipseState/Tables/TableSchema.hpp index a70bd5d7a..77d5f8f5e 100644 --- a/opm/input/eclipse/EclipseState/Tables/TableSchema.hpp +++ b/opm/input/eclipse/EclipseState/Tables/TableSchema.hpp @@ -49,7 +49,7 @@ namespace Opm { } private: - OrderedMap m_columns; + OrderedMap m_columns; }; } diff --git a/opm/input/eclipse/EclipseState/Util/OrderedMap.hpp b/opm/input/eclipse/EclipseState/Util/OrderedMap.hpp index cc1b8a760..ad5d8d98c 100644 --- a/opm/input/eclipse/EclipseState/Util/OrderedMap.hpp +++ b/opm/input/eclipse/EclipseState/Util/OrderedMap.hpp @@ -34,19 +34,11 @@ namespace Opm { namespace OrderedMapDetail { -template -//typename std::enable_if_t::value, std::string> -std::string -findSimilarStrings(const std::string&, - const std::vector&) -{ - return {}; -} -template +template std::string findSimilarStrings(std::string str, - const std::vector,A>& storage) + const std::vector,A>& storage) { auto toUpper = [](const char c){ return std::toupper(c);}; std::transform(str.begin(), str.end(), str.begin(), toUpper); @@ -77,11 +69,11 @@ findSimilarStrings(std::string str, } } // end namespace detail -template +template class OrderedMap { public: - using storage_type = typename std::vector>; - using index_type = typename std::unordered_map; + using storage_type = typename std::vector>; + using index_type = typename std::unordered_map; using iter_type = typename storage_type::iterator; using const_iter_type = typename storage_type::const_iterator; @@ -103,13 +95,13 @@ public: const storage_type& getStorage() const { return m_vector; } - std::size_t count(const K& key) const { + std::size_t count(const std::string& key) const { return this->m_map.count(key); } - T& operator[](const K& key) { + T& operator[](const std::string& key) { if (this->count(key) == 0) this->insert( std::make_pair(key, T())); @@ -117,7 +109,7 @@ public: } - std::size_t erase(const K& key) { + std::size_t erase(const std::string& key) { if (this->count(key) == 0) return 0; @@ -136,7 +128,7 @@ public: } - void insert(std::pair key_value_pair) { + void insert(std::pair key_value_pair) { if (this->count(key_value_pair.first) > 0) { auto iter = m_map.find( key_value_pair.first ); size_t index = iter->second; @@ -149,7 +141,7 @@ public: } - T& get(const K& key) { + T& get(const std::string& key) { auto iter = m_map.find( key ); if (iter == m_map.end()) { @@ -176,7 +168,7 @@ public: return m_vector[index].second; } - const T& get(const K& key) const { + const T& get(const std::string& key) const { const auto& iter = this->m_map.find( key ); if (iter == m_map.end()) { @@ -212,7 +204,7 @@ public: return this->iget(index); } - const T& at(const K& key) const { + const T& at(const std::string& key) const { return this->get(key); } @@ -220,7 +212,7 @@ public: return this->iget(index); } - T& at(const K& key) { + T& at(const std::string& key) { return this->get(key); } @@ -246,7 +238,7 @@ public: return m_vector.end(); } - iter_type find(const K& key) { + iter_type find(const std::string& key) { const auto map_iter = this->m_map.find(key); if (map_iter == this->m_map.end()) return this->m_vector.end(); @@ -254,7 +246,7 @@ public: return std::next(this->m_vector.begin(), map_iter->second); } - const_iter_type find(const K& key) const { + const_iter_type find(const std::string& key) const { const auto map_iter = this->m_map.find(key); if (map_iter == this->m_map.end()) return this->m_vector.end(); @@ -262,7 +254,7 @@ public: return std::next(this->m_vector.begin(), map_iter->second); } - bool operator==(const OrderedMap& data) const { + bool operator==(const OrderedMap& data) const { return this->getIndex() == data.getIndex() && this->getStorage() == data.getStorage(); } diff --git a/opm/input/eclipse/Schedule/UDQ/UDQConfig.hpp b/opm/input/eclipse/Schedule/UDQ/UDQConfig.hpp index e71795eb8..1cf2b64e7 100644 --- a/opm/input/eclipse/Schedule/UDQ/UDQConfig.hpp +++ b/opm/input/eclipse/Schedule/UDQ/UDQConfig.hpp @@ -132,7 +132,7 @@ namespace Opm { std::unordered_map units; IOrderSet define_order; - OrderedMap input_index; + OrderedMap input_index; std::map type_count; }; } diff --git a/tests/parser/OrderedMapTests.cpp b/tests/parser/OrderedMapTests.cpp index a78ef79a4..5a763395d 100644 --- a/tests/parser/OrderedMapTests.cpp +++ b/tests/parser/OrderedMapTests.cpp @@ -28,7 +28,7 @@ BOOST_AUTO_TEST_CASE( check_empty) { - Opm::OrderedMap map; + Opm::OrderedMap map; BOOST_CHECK_EQUAL( 0U , map.size() ); BOOST_CHECK_THROW( map.iget( 0 ) , std::invalid_argument); BOOST_CHECK_THROW( map.get( "KEY" ) , std::invalid_argument); @@ -38,7 +38,7 @@ BOOST_AUTO_TEST_CASE( check_empty) { } BOOST_AUTO_TEST_CASE( operator_square ) { - Opm::OrderedMap map; + Opm::OrderedMap map; map.insert(std::make_pair("CKEY1" , "Value1")); map.insert(std::make_pair("BKEY2" , "Value2")); map.insert(std::make_pair("AKEY3" , "Value3")); @@ -53,7 +53,7 @@ BOOST_AUTO_TEST_CASE( operator_square ) { } BOOST_AUTO_TEST_CASE( find ) { - Opm::OrderedMap map; + Opm::OrderedMap map; map.insert(std::make_pair("CKEY1" , "Value1")); map.insert(std::make_pair("BKEY2" , "Value2")); map.insert(std::make_pair("AKEY3" , "Value3")); @@ -68,7 +68,7 @@ BOOST_AUTO_TEST_CASE( find ) { } BOOST_AUTO_TEST_CASE( check_order ) { - Opm::OrderedMap map; + Opm::OrderedMap map; map.insert(std::make_pair("CKEY1" , "Value1")); map.insert(std::make_pair("BKEY2" , "Value2")); map.insert(std::make_pair("AKEY3" , "Value3")); From d4cd92ee4057b906cc2f7742149bb648c89b7733 Mon Sep 17 00:00:00 2001 From: Markus Blatt Date: Fri, 24 Jun 2022 09:58:23 +0200 Subject: [PATCH 2/4] Support ignoring additional characters in key of OrderedMap. At least for faults we should only look at the first 8 characters. --- .../eclipse/EclipseState/Util/OrderedMap.hpp | 40 +++++++++++++++++-- tests/parser/OrderedMapTests.cpp | 30 ++++++++++++++ 2 files changed, 67 insertions(+), 3 deletions(-) diff --git a/opm/input/eclipse/EclipseState/Util/OrderedMap.hpp b/opm/input/eclipse/EclipseState/Util/OrderedMap.hpp index ad5d8d98c..cf60d2624 100644 --- a/opm/input/eclipse/EclipseState/Util/OrderedMap.hpp +++ b/opm/input/eclipse/EclipseState/Util/OrderedMap.hpp @@ -67,13 +67,46 @@ findSimilarStrings(std::string str, auto concatedStr = concated.str(); return concatedStr.substr(0, concatedStr.size()-2); } + +template +class TruncatedStringHash +{ +public: + std::size_t operator()(const std::string_view& key) const + { + return hasher(key.substr(0, MAX_CHARS)); + } +private: + std::hash hasher; +}; + + +template<> +class TruncatedStringHash : public std::hash +{}; + +template +struct TruncatedStringEquals +{ + bool operator()(const std::string& str1, const std::string& str2) const + { + return str1.substr(0, MAX_CHARS) == str2.substr(0, MAX_CHARS); + } +}; + +template<> +struct TruncatedStringEquals : public std::equal_to +{}; + } // end namespace detail -template +template class OrderedMap { public: using storage_type = typename std::vector>; - using index_type = typename std::unordered_map; + using index_type = typename std::unordered_map, + Opm::OrderedMapDetail::TruncatedStringEquals>; using iter_type = typename storage_type::iterator; using const_iter_type = typename storage_type::const_iterator; @@ -254,7 +287,8 @@ public: return std::next(this->m_vector.begin(), map_iter->second); } - bool operator==(const OrderedMap& data) const { + template + bool operator==(const OrderedMap& data) const { return this->getIndex() == data.getIndex() && this->getStorage() == data.getStorage(); } diff --git a/tests/parser/OrderedMapTests.cpp b/tests/parser/OrderedMapTests.cpp index 5a763395d..50839d041 100644 --- a/tests/parser/OrderedMapTests.cpp +++ b/tests/parser/OrderedMapTests.cpp @@ -67,6 +67,36 @@ BOOST_AUTO_TEST_CASE( find ) { BOOST_CHECK_EQUAL( iter_found->second, std::string("Value1")); } +BOOST_AUTO_TEST_CASE( check_long_truncated_keys) +{ + Opm::OrderedMap map; + map.insert({"AKEY_ABC", "8_characters"}); + BOOST_CHECK(map.count("AKEY_ABC") == 1); + map.insert({"AKEY_ABC_suffix", "too_long"}); + BOOST_CHECK(map.size() == 1); + BOOST_CHECK(map.count("AKEY_ABC") == 1); + BOOST_CHECK(map.count("AKEY_ABC_suffix") == 1); + BOOST_CHECK_EQUAL( "too_long" , map.get("AKEY_ABC")); + BOOST_CHECK_EQUAL( "too_long" , map.get("AKEY_ABC_suffix")); + BOOST_CHECK_EQUAL( "too_long" , map.get("AKEY_ABC_arbitray_suffix")); + BOOST_CHECK_EQUAL( "too_long" , map.iget(0)); +} + +BOOST_AUTO_TEST_CASE( check_long_keys) +{ + Opm::OrderedMap map; + map.insert({"AKEY_ABC", "8_characters"}); + BOOST_CHECK(map.count("AKEY_ABC") == 1); + map.insert({"AKEY_ABC_suffix", "too_long"}); + BOOST_CHECK(map.count("AKEY_ABC") == 1); + BOOST_CHECK(map.count("AKEY_ABC_suffix") == 1); + BOOST_CHECK(map.size() == 2); + BOOST_CHECK_EQUAL( "8_characters" , map.get("AKEY_ABC")); + BOOST_CHECK_EQUAL( "too_long" , map.get("AKEY_ABC_suffix")); + BOOST_CHECK_EQUAL( "8_characters" , map.iget(0)); + BOOST_CHECK_EQUAL( "too_long" , map.iget(1)); +} + BOOST_AUTO_TEST_CASE( check_order ) { Opm::OrderedMap map; map.insert(std::make_pair("CKEY1" , "Value1")); From 19c58e33c4bd460ff8b7c2fc4cafbaa47938eaac Mon Sep 17 00:00:00 2001 From: Markus Blatt Date: Fri, 24 Jun 2022 12:16:46 +0200 Subject: [PATCH 3/4] Document at least what OrderedMap class is all about. --- opm/input/eclipse/EclipseState/Util/OrderedMap.hpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/opm/input/eclipse/EclipseState/Util/OrderedMap.hpp b/opm/input/eclipse/EclipseState/Util/OrderedMap.hpp index cf60d2624..b1f9f152a 100644 --- a/opm/input/eclipse/EclipseState/Util/OrderedMap.hpp +++ b/opm/input/eclipse/EclipseState/Util/OrderedMap.hpp @@ -100,6 +100,16 @@ struct TruncatedStringEquals : public std::equal_to class OrderedMap { public: From 35029e03133f60e3a0e3fecf651635c65254a214 Mon Sep 17 00:00:00 2001 From: Markus Blatt Date: Mon, 27 Jun 2022 11:14:41 +0200 Subject: [PATCH 4/4] Only use first 8 characters as fault names when comparing/searching. Note this is currently done silently as the warnings will probably need to go to the validation code in opm-simulators. --- opm/input/eclipse/EclipseState/Grid/FaultCollection.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opm/input/eclipse/EclipseState/Grid/FaultCollection.hpp b/opm/input/eclipse/EclipseState/Grid/FaultCollection.hpp index 2bd6a65ff..c0b412716 100644 --- a/opm/input/eclipse/EclipseState/Grid/FaultCollection.hpp +++ b/opm/input/eclipse/EclipseState/Grid/FaultCollection.hpp @@ -62,7 +62,7 @@ private: void addFaultFaces(const GridDims& grid, const DeckRecord& faultRecord, const std::string& faultName); - OrderedMap m_faults; + OrderedMap m_faults; }; }