Change OrderMap to more closely resemble std::map

- Removed the hasKey() and get() methods.
 - Key type is a template parameter
 - insert takes a pair
 - implement count()
 - implement find()
 - implement operator[]
 - implement erase
This commit is contained in:
Joakim Hove
2019-03-08 09:00:36 +01:00
parent 3542d43c72
commit f80b220b44
10 changed files with 185 additions and 104 deletions

View File

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

View File

@@ -169,8 +169,8 @@ namespace Opm
void applyAction(size_t reportStep, const ActionX& action, const std::vector<std::string>& matching_wells);
private:
TimeMap m_timeMap;
OrderedMap< Well > m_wells;
OrderedMap< Group > m_groups;
OrderedMap< std::string, Well > m_wells;
OrderedMap< std::string, Group > m_groups;
DynamicState< GroupTree > m_rootGroupTree;
DynamicState< OilVaporizationProperties > m_oilvaporizationproperties;
Events m_events;

View File

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

View File

@@ -38,7 +38,7 @@ namespace Opm {
/* Number of columns */
size_t size() const;
private:
OrderedMap<ColumnSchema> m_columns;
OrderedMap<std::string, ColumnSchema> m_columns;
};
}

View File

@@ -24,128 +24,157 @@
#include <vector>
#include <string>
#include <stdexcept>
#include <iterator>
namespace Opm {
template <typename T>
template <typename K, typename T>
class OrderedMap {
using storage_type = typename std::vector<std::pair<K,T>>;
using index_type = typename std::unordered_map<K,std::size_t>;
using iter_type = typename storage_type::iterator;
using const_iter_type = typename storage_type::const_iterator;
private:
std::unordered_map<std::string , size_t> m_map;
std::vector<T> m_vector;
index_type m_map;
storage_type m_vector;
public:
bool hasKey(const std::string& key) const {
auto iter = m_map.find(key);
if (iter == m_map.end())
return false;
else
return true;
std::size_t count(const K& key) const {
return this->m_map.count(key);
}
void insert(std::string key, T value) {
if (hasKey(key)) {
auto iter = m_map.find( key );
T& operator[](const K& key) {
if (this->count(key) == 0)
this->insert( std::make_pair(key, T()));
return this->at(key);
}
std::size_t erase(const K& key) {
if (this->count(key) == 0)
return 0;
std::size_t index = this->m_map.at(key);
this->m_map.erase(key);
this->m_vector.erase(this->m_vector.begin() + index);
for (const auto& index_pair : this->m_map) {
auto target_index = index_pair.second;
if (target_index > index)
target_index--;
this->m_map[index_pair.first] = target_index;
}
return 1;
}
void insert(std::pair<K,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;
m_vector[index] = value;
m_vector[index] = key_value_pair;
} else {
size_t index = m_vector.size();
m_vector.push_back( std::move( value ) );
m_map.insert( std::pair<std::string, size_t>(key , index));
this->m_map.emplace(key_value_pair.first, index);
this->m_vector.push_back( std::move( key_value_pair ) );
}
}
T& get(const std::string& key) {
T& get(const K& key) {
auto iter = m_map.find( key );
if (iter == m_map.end())
throw std::invalid_argument("Key not found:" + key);
throw std::invalid_argument("Key not found:");
else {
size_t index = iter->second;
return get(index);
return iget(index);
}
}
T& get(size_t index) {
T& iget(size_t index) {
if (index >= m_vector.size())
throw std::invalid_argument("Invalid index");
return m_vector[index];
return m_vector[index].second;
}
const T& get(const std::string& key) const {
auto iter = m_map.find( key );
const T& get(const K& key) const {
const auto& iter = this->m_map.find( key );
if (iter == m_map.end())
throw std::invalid_argument("Key not found:" + key);
throw std::invalid_argument("Key not found: ??");
else {
size_t index = iter->second;
return get(index);
return iget(index);
}
}
const T& get(size_t index) const {
const T& iget(size_t index) const {
if (index >= m_vector.size())
throw std::invalid_argument("Invalid index");
return m_vector[index];
return m_vector[index].second;
}
const T& at(size_t index) const {
return this->get(index);
return this->iget(index);
}
const T& at(const std::string &key) const {
const T& at(const K& key) const {
return this->get(key);
}
T& at(size_t index) {
return this->get(index);
return this->iget(index);
}
T& at(const std::string& key) {
T& at(const K& key) {
return this->get(key);
}
T* getPtr(const std::string& key) const {
auto iter = m_map.find( key );
if (iter == m_map.end())
throw std::invalid_argument("Key not found:" + key);
else {
size_t index = iter->second;
return getPtr(index);
}
}
T* getPtr(size_t index) const {
if (index >= m_vector.size())
throw std::invalid_argument("Invalid index");
return &m_vector[index];
}
size_t size() const {
return m_vector.size();
}
typename std::vector<T>::const_iterator begin() const {
const_iter_type begin() const {
return m_vector.begin();
}
typename std::vector<T>::const_iterator end() const {
const_iter_type end() const {
return m_vector.end();
}
typename std::vector<T>::iterator begin() {
iter_type begin() {
return m_vector.begin();
}
typename std::vector<T>::iterator end() {
iter_type end() {
return m_vector.end();
}
iter_type find(const K& key) {
const auto map_iter = this->m_map.find(key);
if (map_iter == this->m_map.end())
return this->m_vector.end();
return std::next(this->m_vector.begin(), map_iter->second);
}
const_iter_type find(const K& key) const {
const auto map_iter = this->m_map.find(key);
if (map_iter == this->m_map.end())
return this->m_vector.end();
return std::next(this->m_vector.begin(), map_iter->second);
}
};
}

View File

@@ -85,7 +85,7 @@ namespace Opm {
}
bool FaultCollection::hasFault(const std::string& faultName) const {
return m_faults.hasKey( faultName );
return m_faults.count( faultName ) > 0;
}
const Fault& FaultCollection::getFault(const std::string& faultName) const {
@@ -97,16 +97,16 @@ namespace Opm {
}
Fault& FaultCollection::getFault(size_t faultIndex) {
return m_faults.get( faultIndex );
return m_faults.iget( faultIndex );
}
const Fault& FaultCollection::getFault(size_t faultIndex) const {
return m_faults.get( faultIndex );
return m_faults.iget( faultIndex );
}
void FaultCollection::addFault(const std::string& faultName) {
Fault fault(faultName);
m_faults.insert(fault.getName() , fault);
m_faults.insert(std::make_pair(fault.getName() , fault));
}
void FaultCollection::setTransMult(const std::string& faultName , double transMult) {

View File

@@ -653,7 +653,6 @@ namespace Opm {
for( auto* well : wells ) {
WellProductionProperties properties;
if (isPredictionMode) {
auto addGrupProductionControl = well->isAvailableForGroupControl(currentStep);
properties = WellProductionProperties::prediction( record, addGrupProductionControl );
@@ -1672,8 +1671,10 @@ namespace Opm {
well->updateRFTActive( currentStep, RFTConnections::RFTEnum::YES);
}
for( auto& well : this->m_wells )
for( auto& well_pair : this->m_wells ) {
auto& well = well_pair.second;
well.setRFTForWellWhenFirstOpen( currentStep );
}
}
void Schedule::handleWRFTPLT( const DeckKeyword& keyword, size_t currentStep) {
@@ -1751,7 +1752,7 @@ namespace Opm {
timeStep,
wellConnectionOrder, allowCrossFlow, automaticShutIn);
m_wells.insert( wellName, well );
m_wells.insert( std::make_pair(wellName, well ));
m_events.addEvent( ScheduleEvents::NEW_WELL , timeStep );
}
@@ -1764,7 +1765,7 @@ namespace Opm {
}
bool Schedule::hasWell(const std::string& wellName) const {
return m_wells.hasKey( wellName );
return m_wells.count( wellName ) > 0;
}
std::vector< const Well* > Schedule::getWells() const {
@@ -1833,7 +1834,7 @@ namespace Opm {
if (!child_groups.size()) {
//for (const auto& well_name : group.getWells( timeStep )) {
const auto& ch_wells = group.getWells( timeStep );
const auto& ch_wells = group.getWells( timeStep );
for (auto it= ch_wells.begin(); it != ch_wells.end(); it++) {
wells.push_back( getWell( *it ));
}
@@ -1856,7 +1857,8 @@ namespace Opm {
};
std::vector< const Well* > wells;
for( const auto& well : m_wells ) {
for( const auto& well_pair : m_wells ) {
const auto& well = well_pair.second;
if( !defined( well ) ) continue;
wells.push_back( std::addressof( well ) );
}
@@ -1882,7 +1884,8 @@ namespace Opm {
};
std::vector< const Well* > wells;
for( const auto& well : m_wells ) {
for( const auto& well_pair : m_wells ) {
const auto& well = well_pair.second;
if( !open( well ) ) continue;
wells.push_back( std::addressof( well ) );
}
@@ -1908,12 +1911,13 @@ namespace Opm {
auto wildcard_pos = wellNamePattern.find("*");
if( wildcard_pos != wellNamePattern.length()-1 ) {
if( !m_wells.hasKey( wellNamePattern ) ) return {};
if( m_wells.count( wellNamePattern ) == 0 ) return {};
return { std::addressof( m_wells.get( wellNamePattern ) ) };
}
std::vector< Well* > wells;
for( auto& well : this->m_wells ) {
for( auto& well_pair : this->m_wells ) {
auto& well = well_pair.second;
if( Well::wellNameInWellNamePattern( well.name(), wellNamePattern ) ) {
wells.push_back( std::addressof( well ) );
}
@@ -1925,7 +1929,7 @@ namespace Opm {
void Schedule::addGroup(const std::string& groupName, size_t timeStep) {
const size_t gseqIndex = m_groups.size();
m_groups.insert( groupName, Group { groupName, gseqIndex, m_timeMap, timeStep } );
m_groups.insert( std::make_pair( groupName, Group { groupName, gseqIndex, m_timeMap, timeStep } ));
m_events.addEvent( ScheduleEvents::NEW_GROUP , timeStep );
}
@@ -1937,7 +1941,7 @@ namespace Opm {
}
bool Schedule::hasGroup(const std::string& groupName) const {
return m_groups.hasKey(groupName);
return m_groups.count(groupName) > 0;
}
@@ -1952,7 +1956,7 @@ namespace Opm {
std::vector< const Group* > groups;
for( const auto& group : m_groups )
groups.push_back( &group );
groups.push_back( std::addressof(group.second) );
return groups;
}
@@ -1961,12 +1965,13 @@ namespace Opm {
size_t wildcard_pos = groupNamePattern.find("*");
if( wildcard_pos != groupNamePattern.length()-1 ) {
if( !m_groups.hasKey( groupNamePattern ) ) return {};
if( m_groups.count( groupNamePattern ) == 0) return {};
return { std::addressof( m_groups.get( groupNamePattern ) ) };
}
std::vector< Group* > groups;
for( auto& group : this->m_groups ) {
for( auto& group_pair : this->m_groups ) {
auto& group = group_pair.second;
if( Group::groupNameInGroupNamePattern( group.name(), groupNamePattern ) ) {
groups.push_back( std::addressof( group ) );
}
@@ -1977,7 +1982,7 @@ namespace Opm {
std::vector< const Group* > Schedule::getGroups(size_t timeStep) const {
if (timeStep >= m_timeMap.size()) {
if (timeStep >= m_timeMap.size()) {
throw std::invalid_argument("Timestep to large");
}
@@ -1987,10 +1992,11 @@ namespace Opm {
std::vector< const Group* > groups;
for( const auto& group : m_groups ) {
if( !defined( group ) ) continue;
groups.push_back( &group );
}
for( const auto& group_pair : m_groups ) {
const auto& group = group_pair.second;
if( !defined( group) ) continue;
groups.push_back( &group );
}
return groups;
}
@@ -2095,7 +2101,8 @@ namespace Opm {
}
void Schedule::checkIfAllConnectionsIsShut(size_t timestep) {
for( auto& well : this->m_wells ) {
for( auto& well_pair : this->m_wells ) {
auto& well = well_pair.second;
const auto& completions = well.getConnections(timestep);
if( completions.allConnectionsShut() )
this->updateWellStatus( well, timestep, WellCommon::StatusEnum::SHUT);
@@ -2104,8 +2111,10 @@ namespace Opm {
void Schedule::filterConnections(const EclipseGrid& grid) {
for (auto& well : this->m_wells)
for (auto& well_pair : this->m_wells) {
auto well = well_pair.second;
well.filterConnections(grid);
}
}
const VFPProdTable& Schedule::getVFPProdTable(int table_id, size_t timeStep) const {

View File

@@ -56,7 +56,7 @@ namespace Opm {
for (size_t colIdx = 0; colIdx < m_schema.size(); ++colIdx) {
const auto& schemaColumn = m_schema.getColumn( colIdx );
TableColumn column(schemaColumn); // Some move trickery here ...
m_columns.insert( schemaColumn.name() , column );
m_columns.insert( std::make_pair( schemaColumn.name() , column ));
}
}
@@ -115,7 +115,7 @@ namespace Opm {
}
const TableColumn& SimpleTable::getColumn( size_t columnIndex ) const {
return m_columns.get( columnIndex );
return m_columns.iget( columnIndex );
}
@@ -129,7 +129,7 @@ namespace Opm {
}
TableColumn& SimpleTable::getColumn( size_t columnIndex ) {
return m_columns.get( columnIndex );
return m_columns.iget( columnIndex );
}

View File

@@ -23,7 +23,7 @@
namespace Opm {
void TableSchema::addColumn( ColumnSchema column ) {
m_columns.insert( column.name(), column );
m_columns.insert( std::make_pair( column.name(), column ));
}
const ColumnSchema& TableSchema::getColumn( const std::string& name ) const {
@@ -31,7 +31,7 @@ namespace Opm {
}
const ColumnSchema& TableSchema::getColumn( size_t columnIndex ) const {
return m_columns.get( columnIndex );
return m_columns.iget( columnIndex );
}
size_t TableSchema::size() const {
@@ -39,7 +39,7 @@ namespace Opm {
}
bool TableSchema::hasColumn(const std::string& name) const {
return m_columns.hasKey( name );
return m_columns.count( name ) > 0;
}
}

View File

@@ -29,47 +29,90 @@
BOOST_AUTO_TEST_CASE( check_empty) {
Opm::OrderedMap<std::string> map;
Opm::OrderedMap<std::string, std::string> map;
BOOST_CHECK_EQUAL( 0U , map.size() );
BOOST_CHECK( !map.hasKey("KEY"));
BOOST_CHECK_THROW( map.get( 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.at("KEY"), std::invalid_argument);
BOOST_CHECK_THROW( map.at(0), std::invalid_argument);
BOOST_CHECK_EQUAL( map.count("NO_SUCH_KEY"), 0);
}
BOOST_AUTO_TEST_CASE( operator_square ) {
Opm::OrderedMap<std::string, std::string> map;
map.insert(std::make_pair("CKEY1" , "Value1"));
map.insert(std::make_pair("BKEY2" , "Value2"));
map.insert(std::make_pair("AKEY3" , "Value3"));
const auto& value = map["CKEY1"];
BOOST_CHECK_EQUAL( value, std::string("Value1"));
BOOST_CHECK_EQUAL( map.size(), 3);
auto& new_value = map["NEW_KEY"];
BOOST_CHECK_EQUAL( map.size(), 4);
BOOST_CHECK_EQUAL( new_value, "");
}
BOOST_AUTO_TEST_CASE( find ) {
Opm::OrderedMap<std::string, std::string> map;
map.insert(std::make_pair("CKEY1" , "Value1"));
map.insert(std::make_pair("BKEY2" , "Value2"));
map.insert(std::make_pair("AKEY3" , "Value3"));
auto iter_end = map.find("NO_SUCH_KEY");
BOOST_CHECK( iter_end == map.end());
auto iter_found = map.find("CKEY1");
BOOST_CHECK_EQUAL( iter_found->first, std::string("CKEY1"));
BOOST_CHECK_EQUAL( iter_found->second, std::string("Value1"));
}
BOOST_AUTO_TEST_CASE( check_order ) {
Opm::OrderedMap<std::string> map;
map.insert("CKEY1" , "Value1");
map.insert("BKEY2" , "Value2");
map.insert("AKEY3" , "Value3");
Opm::OrderedMap<std::string, std::string> map;
map.insert(std::make_pair("CKEY1" , "Value1"));
map.insert(std::make_pair("BKEY2" , "Value2"));
map.insert(std::make_pair("AKEY3" , "Value3"));
BOOST_CHECK_EQUAL( 3U , map.size() );
BOOST_CHECK( map.hasKey("CKEY1"));
BOOST_CHECK( map.hasKey("BKEY2"));
BOOST_CHECK( map.hasKey("AKEY3"));
BOOST_CHECK( map.count("CKEY1") > 0);
BOOST_CHECK( map.count("BKEY2") > 0);
BOOST_CHECK( map.count("AKEY3") > 0);
BOOST_CHECK_EQUAL( "Value1" , map.get("CKEY1"));
BOOST_CHECK_EQUAL( "Value1" , map.get( 0 ));
BOOST_CHECK_EQUAL( "Value1" , map.iget( 0 ));
BOOST_CHECK_EQUAL( map.count("CKEY"), 0);
BOOST_CHECK_EQUAL( "Value2" , map.get("BKEY2"));
BOOST_CHECK_EQUAL( "Value2" , map.get( 1 ));
BOOST_CHECK_EQUAL( "Value2" , map.iget( 1 ));
BOOST_CHECK_EQUAL( "Value3" , map.at("AKEY3"));
BOOST_CHECK_EQUAL( "Value3" , map.at( 2 ));
map.insert( "CKEY1" , "NewValue1");
map.insert( std::make_pair("CKEY1" , "NewValue1"));
BOOST_CHECK_EQUAL( "NewValue1" , map.get("CKEY1"));
BOOST_CHECK_EQUAL( "NewValue1" , map.get( 0 ));
BOOST_CHECK_EQUAL( "NewValue1" , map.iget( 0 ));
{
std::vector<std::string> values;
for (auto iter = map.begin(); iter != map.end(); ++iter)
values.push_back( *iter );
values.push_back( iter->second );
BOOST_CHECK_EQUAL( values[0] , "NewValue1");
BOOST_CHECK_EQUAL( values[1] , "Value2");
BOOST_CHECK_EQUAL( values[2] , "Value3");
}
BOOST_CHECK_EQUAL(map.erase("NO_SUCH_KEY"), 0);
BOOST_CHECK_EQUAL(map.erase("BKEY2"), 1);
/*
BOOST_CHECK_EQUAL( "NewValue1" , map.get("CKEY1"));
BOOST_CHECK_EQUAL( "NewValue1" , map.iget( 0 ));
BOOST_CHECK_EQUAL( map.count("CKEY"), 0);
BOOST_CHECK_EQUAL( "Value3" , map.at("AKEY3"));
BOOST_CHECK_EQUAL( "Value3" , map.at( 1 ));
*/
}