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:
Jørgen Kvalsvik
2016-08-05 10:45:31 +02:00
parent f571f21171
commit 99570ff72e
4 changed files with 29 additions and 9 deletions

View File

@@ -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 {

View File

@@ -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 );

View File

@@ -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) {

View File

@@ -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 {