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,
const DeckRecord& faultRecord,
const std::string& faultName);
OrderedMap<std::string, Fault> m_faults;
OrderedMap<Fault, 8> m_faults;
};
}

View File

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

View File

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

View File

@ -34,19 +34,11 @@ namespace Opm {
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
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);};
std::transform(str.begin(), str.end(), str.begin(), toUpper);
@ -75,13 +67,56 @@ findSimilarStrings(std::string str,
auto concatedStr = concated.str();
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
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 {
public:
using storage_type = typename std::vector<std::pair<K,T>>;
using index_type = typename std::unordered_map<K,std::size_t>;
using storage_type = typename std::vector<std::pair<std::string,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 const_iter_type = typename storage_type::const_iterator;
@ -103,13 +138,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 +152,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 +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) {
auto iter = m_map.find( key_value_pair.first );
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 );
if (iter == m_map.end())
{
@ -176,7 +211,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 +247,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 +255,7 @@ public:
return this->iget(index);
}
T& at(const K& key) {
T& at(const std::string& key) {
return this->get(key);
}
@ -246,7 +281,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 +289,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 +297,8 @@ public:
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() &&
this->getStorage() == data.getStorage();
}

View File

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

View File

@ -28,7 +28,7 @@
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_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<std::string, std::string> map;
Opm::OrderedMap<std::string> 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<std::string, std::string> map;
Opm::OrderedMap<std::string> map;
map.insert(std::make_pair("CKEY1" , "Value1"));
map.insert(std::make_pair("BKEY2" , "Value2"));
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_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 ) {
Opm::OrderedMap<std::string, std::string> map;
Opm::OrderedMap<std::string> map;
map.insert(std::make_pair("CKEY1" , "Value1"));
map.insert(std::make_pair("BKEY2" , "Value2"));
map.insert(std::make_pair("AKEY3" , "Value3"));