Merge pull request #3065 from blattms/ordered-map-truncate-key

Use only first 8 characters as fault name when comparing/searching.
This commit is contained in:
Bård Skaflestad 2022-06-28 10:22:35 +02:00 committed by GitHub
commit 1516b63a39
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 98 additions and 32 deletions

View File

@ -62,7 +62,7 @@ private:
void addFaultFaces(const GridDims& grid, void addFaultFaces(const GridDims& grid,
const DeckRecord& faultRecord, const DeckRecord& faultRecord,
const std::string& faultName); const std::string& faultName);
OrderedMap<std::string, Fault> m_faults; OrderedMap<Fault, 8> m_faults;
}; };
} }

View File

@ -84,7 +84,7 @@ namespace Opm {
protected: protected:
TableSchema m_schema; TableSchema m_schema;
OrderedMap<std::string, TableColumn> m_columns; OrderedMap<TableColumn> m_columns;
bool m_jfunc = false; bool m_jfunc = false;
}; };
} }

View File

@ -49,7 +49,7 @@ namespace Opm {
} }
private: private:
OrderedMap<std::string, ColumnSchema> m_columns; OrderedMap<ColumnSchema> m_columns;
}; };
} }

View File

@ -34,19 +34,11 @@ namespace Opm {
namespace OrderedMapDetail namespace OrderedMapDetail
{ {
template<class T, class A>
//typename std::enable_if_t<!std::is_same<T,std::string>::value, std::string>
std::string
findSimilarStrings(const std::string&,
const std::vector<T,A>&)
{
return {};
}
template<class A, class K> template<class T, class A>
std::string std::string
findSimilarStrings(std::string str, findSimilarStrings(std::string str,
const std::vector<std::pair<std::string, K>,A>& storage) const std::vector<std::pair<std::string, T>,A>& storage)
{ {
auto toUpper = [](const char c){ return std::toupper(c);}; auto toUpper = [](const char c){ return std::toupper(c);};
std::transform(str.begin(), str.end(), str.begin(), toUpper); std::transform(str.begin(), str.end(), str.begin(), toUpper);
@ -75,13 +67,56 @@ findSimilarStrings(std::string str,
auto concatedStr = concated.str(); auto concatedStr = concated.str();
return concatedStr.substr(0, concatedStr.size()-2); return concatedStr.substr(0, concatedStr.size()-2);
} }
template<std::size_t MAX_CHARS>
class TruncatedStringHash
{
public:
std::size_t operator()(const std::string_view& key) const
{
return hasher(key.substr(0, MAX_CHARS));
}
private:
std::hash<std::string_view> hasher;
};
template<>
class TruncatedStringHash<std::string::npos> : public std::hash<std::string_view>
{};
template<std::size_t MAX_CHARS>
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<std::string::npos> : public std::equal_to<std::string>
{};
} // end namespace detail } // end namespace detail
template <typename K, typename T> /// \brief A map with iteration in the order of insertion.
///
/// Each entry has an associated index indicating when a value with that key was
/// first inserted. When itering over it's entries values with lower insertion index
/// are traversed before ones with an higher insertion index.
///
/// \tparam MAX_CHARS The maximum number of characters that are use a keys. Default is
/// std::string::npos, which honors all characters. Any keys with the
/// same first MAX_CHARS characters are considered equal.
///
template <typename T, std::size_t MAX_CHARS = std::string::npos>
class OrderedMap { class OrderedMap {
public: public:
using storage_type = typename std::vector<std::pair<K,T>>; using storage_type = typename std::vector<std::pair<std::string,T>>;
using index_type = typename std::unordered_map<K,std::size_t>; using index_type = typename std::unordered_map<std::string,std::size_t,
Opm::OrderedMapDetail::TruncatedStringHash<MAX_CHARS>,
Opm::OrderedMapDetail::TruncatedStringEquals<MAX_CHARS>>;
using iter_type = typename storage_type::iterator; using iter_type = typename storage_type::iterator;
using const_iter_type = typename storage_type::const_iterator; using const_iter_type = typename storage_type::const_iterator;
@ -103,13 +138,13 @@ public:
const storage_type& getStorage() const { return m_vector; } 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); return this->m_map.count(key);
} }
T& operator[](const K& key) { T& operator[](const std::string& key) {
if (this->count(key) == 0) if (this->count(key) == 0)
this->insert( std::make_pair(key, T())); this->insert( std::make_pair(key, T()));
@ -117,7 +152,7 @@ public:
} }
std::size_t erase(const K& key) { std::size_t erase(const std::string& key) {
if (this->count(key) == 0) if (this->count(key) == 0)
return 0; return 0;
@ -136,7 +171,7 @@ public:
} }
void insert(std::pair<K,T> key_value_pair) { void insert(std::pair<std::string,T> key_value_pair) {
if (this->count(key_value_pair.first) > 0) { if (this->count(key_value_pair.first) > 0) {
auto iter = m_map.find( key_value_pair.first ); auto iter = m_map.find( key_value_pair.first );
size_t index = iter->second; size_t index = iter->second;
@ -149,7 +184,7 @@ public:
} }
T& get(const K& key) { T& get(const std::string& key) {
auto iter = m_map.find( key ); auto iter = m_map.find( key );
if (iter == m_map.end()) if (iter == m_map.end())
{ {
@ -176,7 +211,7 @@ public:
return m_vector[index].second; 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 ); const auto& iter = this->m_map.find( key );
if (iter == m_map.end()) if (iter == m_map.end())
{ {
@ -212,7 +247,7 @@ public:
return this->iget(index); return this->iget(index);
} }
const T& at(const K& key) const { const T& at(const std::string& key) const {
return this->get(key); return this->get(key);
} }
@ -220,7 +255,7 @@ public:
return this->iget(index); return this->iget(index);
} }
T& at(const K& key) { T& at(const std::string& key) {
return this->get(key); return this->get(key);
} }
@ -246,7 +281,7 @@ public:
return m_vector.end(); 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); const auto map_iter = this->m_map.find(key);
if (map_iter == this->m_map.end()) if (map_iter == this->m_map.end())
return this->m_vector.end(); return this->m_vector.end();
@ -254,7 +289,7 @@ public:
return std::next(this->m_vector.begin(), map_iter->second); 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); const auto map_iter = this->m_map.find(key);
if (map_iter == this->m_map.end()) if (map_iter == this->m_map.end())
return this->m_vector.end(); return this->m_vector.end();
@ -262,7 +297,8 @@ public:
return std::next(this->m_vector.begin(), map_iter->second); return std::next(this->m_vector.begin(), map_iter->second);
} }
bool operator==(const OrderedMap<K,T>& data) const { template<size_t n>
bool operator==(const OrderedMap<T,n>& data) const {
return this->getIndex() == data.getIndex() && return this->getIndex() == data.getIndex() &&
this->getStorage() == data.getStorage(); this->getStorage() == data.getStorage();
} }

View File

@ -132,7 +132,7 @@ namespace Opm {
std::unordered_map<std::string, std::string> units; std::unordered_map<std::string, std::string> units;
IOrderSet<std::string> define_order; IOrderSet<std::string> define_order;
OrderedMap<std::string, UDQIndex> input_index; OrderedMap<UDQIndex> input_index;
std::map<UDQVarType, std::size_t> type_count; std::map<UDQVarType, std::size_t> type_count;
}; };
} }

View File

@ -28,7 +28,7 @@
BOOST_AUTO_TEST_CASE( check_empty) { BOOST_AUTO_TEST_CASE( check_empty) {
Opm::OrderedMap<std::string, std::string> map; Opm::OrderedMap<std::string> map;
BOOST_CHECK_EQUAL( 0U , map.size() ); BOOST_CHECK_EQUAL( 0U , map.size() );
BOOST_CHECK_THROW( map.iget( 0 ) , std::invalid_argument); BOOST_CHECK_THROW( map.iget( 0 ) , std::invalid_argument);
BOOST_CHECK_THROW( map.get( "KEY" ) , 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 ) { BOOST_AUTO_TEST_CASE( operator_square ) {
Opm::OrderedMap<std::string, std::string> map; Opm::OrderedMap<std::string> map;
map.insert(std::make_pair("CKEY1" , "Value1")); map.insert(std::make_pair("CKEY1" , "Value1"));
map.insert(std::make_pair("BKEY2" , "Value2")); map.insert(std::make_pair("BKEY2" , "Value2"));
map.insert(std::make_pair("AKEY3" , "Value3")); map.insert(std::make_pair("AKEY3" , "Value3"));
@ -53,7 +53,7 @@ BOOST_AUTO_TEST_CASE( operator_square ) {
} }
BOOST_AUTO_TEST_CASE( find ) { BOOST_AUTO_TEST_CASE( find ) {
Opm::OrderedMap<std::string, std::string> map; Opm::OrderedMap<std::string> map;
map.insert(std::make_pair("CKEY1" , "Value1")); map.insert(std::make_pair("CKEY1" , "Value1"));
map.insert(std::make_pair("BKEY2" , "Value2")); map.insert(std::make_pair("BKEY2" , "Value2"));
map.insert(std::make_pair("AKEY3" , "Value3")); map.insert(std::make_pair("AKEY3" , "Value3"));
@ -67,8 +67,38 @@ BOOST_AUTO_TEST_CASE( find ) {
BOOST_CHECK_EQUAL( iter_found->second, std::string("Value1")); BOOST_CHECK_EQUAL( iter_found->second, std::string("Value1"));
} }
BOOST_AUTO_TEST_CASE( check_long_truncated_keys)
{
Opm::OrderedMap<std::string, 8> 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<std::string> 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 ) { BOOST_AUTO_TEST_CASE( check_order ) {
Opm::OrderedMap<std::string, std::string> map; Opm::OrderedMap<std::string> map;
map.insert(std::make_pair("CKEY1" , "Value1")); map.insert(std::make_pair("CKEY1" , "Value1"));
map.insert(std::make_pair("BKEY2" , "Value2")); map.insert(std::make_pair("BKEY2" , "Value2"));
map.insert(std::make_pair("AKEY3" , "Value3")); map.insert(std::make_pair("AKEY3" , "Value3"));