Add all records to Deck at once
Rather than doing add-item-check-duplicates per DeckItem added to a record, construct all the items at once, then pass them in full to the DeckRecord object. The DeckRecord object still check for duplicate names, but with lower complexity and cost.
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
|
||||
|
||||
#include <unordered_set>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
@@ -29,8 +30,26 @@
|
||||
namespace Opm {
|
||||
|
||||
|
||||
DeckRecord::DeckRecord( size_t sz ) {
|
||||
this->m_items.reserve( sz );
|
||||
DeckRecord::DeckRecord( std::vector< DeckItem >&& items ) :
|
||||
m_items( std::move( items ) ) {
|
||||
|
||||
std::unordered_set< std::string > names;
|
||||
for( const auto& item : this->m_items )
|
||||
names.insert( item.name() );
|
||||
|
||||
if( names.size() == this->m_items.size() )
|
||||
return;
|
||||
|
||||
names.clear();
|
||||
std::string msg = "Duplicate item names in DeckRecord:";
|
||||
for( const auto& item : this->m_items ) {
|
||||
if( names.count( item.name() ) != 0 )
|
||||
msg += std::string( " " ) += item.name();
|
||||
|
||||
names.insert( item.name() );
|
||||
}
|
||||
|
||||
throw std::invalid_argument( msg );
|
||||
}
|
||||
|
||||
size_t DeckRecord::size() const {
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace Opm {
|
||||
typedef std::vector< DeckItem >::const_iterator const_iterator;
|
||||
|
||||
DeckRecord() = default;
|
||||
DeckRecord( size_t );
|
||||
DeckRecord( std::vector< DeckItem >&& );
|
||||
|
||||
size_t size() const;
|
||||
void addItem( DeckItem&& deckItem );
|
||||
|
||||
@@ -71,6 +71,8 @@ BOOST_AUTO_TEST_CASE(addItem_differentItemsSameName_throws) {
|
||||
DeckRecord deckRecord;
|
||||
deckRecord.addItem( mkIntItem( "TEST" ) );
|
||||
BOOST_CHECK_THROW( deckRecord.addItem( mkIntItem( "TEST" ) ), std::invalid_argument );
|
||||
std::vector< DeckItem > items = { mkIntItem( "TEST" ), mkIntItem( "TEST" ) };
|
||||
BOOST_CHECK_THROW( DeckRecord( std::move( items ) ), std::invalid_argument );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(get_byIndex_returnsItem) {
|
||||
|
||||
@@ -118,11 +118,10 @@ namespace Opm {
|
||||
}
|
||||
|
||||
DeckRecord ParserRecord::parse(const ParseContext& parseContext , MessageContainer& msgContainer, RawRecord& rawRecord ) const {
|
||||
DeckRecord deckRecord( size() + 20 );
|
||||
for (size_t i = 0; i < size(); i++) {
|
||||
auto parserItem = get(i);
|
||||
deckRecord.addItem( parserItem->scan( rawRecord ) );
|
||||
}
|
||||
std::vector< DeckItem > items;
|
||||
items.reserve( this->size() + 20 );
|
||||
for( const auto& parserItem : *this )
|
||||
items.emplace_back( parserItem->scan( rawRecord ) );
|
||||
|
||||
if (rawRecord.size() > 0) {
|
||||
std::string msg = "The RawRecord for keyword \"" + rawRecord.getKeywordName() + "\" in file\"" + rawRecord.getFileName() + "\" contained " +
|
||||
@@ -131,7 +130,7 @@ namespace Opm {
|
||||
parseContext.handleError(ParseContext::PARSE_EXTRA_DATA , msgContainer, msg);
|
||||
}
|
||||
|
||||
return deckRecord;
|
||||
return { std::move( items ) };
|
||||
}
|
||||
|
||||
bool ParserRecord::equal(const ParserRecord& other) const {
|
||||
|
||||
Reference in New Issue
Block a user