Use hash of input do control if calculation is required

Add hash functions
Add serial number to SummaryReaderInterface
Add hash for RimSummaryCase

Use hash based on input parameters to control caching of data in RimEnsembleStatisticsCase::calculate  and RimEnsembleCurveSet::appendOptionItemsForSummaryAddresses
This commit is contained in:
Magne Sjaastad 2024-10-22 16:24:11 +02:00
parent ac96150875
commit 581b268928
10 changed files with 191 additions and 15 deletions

View File

@ -53,6 +53,7 @@ set(SOURCE_GROUP_HEADER_FILES
${CMAKE_CURRENT_LIST_DIR}/RiaFileLogger.h
${CMAKE_CURRENT_LIST_DIR}/RiaProjectBackupTools.h
${CMAKE_CURRENT_LIST_DIR}/RiaQuantityInfoTools.h
${CMAKE_CURRENT_LIST_DIR}/RiaHashTools.h
)
set(SOURCE_GROUP_SOURCE_FILES

View File

@ -0,0 +1,90 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2024- Equinor ASA
//
// ResInsight is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include <cstddef>
#include <functional>
#include <ranges>
//==================================================================================================
//
//
//
//==================================================================================================
namespace RiaHashTools
{
//--------------------------------------------------------------------------------------------------
/// Variadic template function to combine multiple parameters into a single hash
//--------------------------------------------------------------------------------------------------
template <typename T>
void combineHash( size_t& seed, const T& value )
{
// Based on https://www.boost.org/doc/libs/1_84_0/libs/container_hash/doc/html/hash.html#notes_hash_combine
seed ^= std::hash<T>()( value ) + 0x9e3779b9 + ( seed << 6 ) + ( seed >> 2 );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
template <typename T, typename... Rest>
void combineHash( size_t& seed, const T& value, const Rest&... rest )
{
combineHash( seed, value );
( combineHash( seed, rest ), ... );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
template <std::ranges::range Range, typename... Rest>
void combineHash( size_t& seed, const Range& range, const Rest&... rest )
{
for ( const auto& elem : range )
{
combineHash( seed, elem );
}
( combineHash( seed, rest ), ... );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
template <typename... Args>
size_t hash( const Args&... args )
{
size_t seed = 0;
combineHash( seed, args... );
return seed;
}
//--------------------------------------------------------------------------------------------------
/// Generic hash function for any range
//--------------------------------------------------------------------------------------------------
template <std::ranges::range Range>
size_t hash( const Range& range )
{
size_t seed = 0;
for ( const auto& elem : range )
{
combineHash( seed, elem );
}
return seed;
}
}; // namespace RiaHashTools

View File

@ -22,6 +22,8 @@
#include <QDateTime>
int RifSummaryReaderInterface::m_nextSerialNumber = 0;
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -56,6 +58,23 @@ void RifSummaryReaderInterface::buildMetaData()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RifSummaryReaderInterface::serialNumber() const
{
return m_serialNumber;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RifSummaryReaderInterface::RifSummaryReaderInterface()
{
#pragma omp critical
m_serialNumber = m_nextSerialNumber++;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -37,6 +37,8 @@ class QDateTime;
class RifSummaryReaderInterface : public cvf::Object
{
public:
RifSummaryReaderInterface();
bool hasAddress( const RifEclipseSummaryAddress& resultAddress ) const;
const std::set<RifEclipseSummaryAddress>& allResultAddresses() const;
@ -53,7 +55,13 @@ public:
virtual void buildMetaData();
int serialNumber() const;
protected:
std::set<RifEclipseSummaryAddress> m_allResultAddresses; // Result and error addresses
std::set<RifEclipseSummaryAddress> m_allErrorAddresses; // Error addresses
private:
static int m_nextSerialNumber;
int m_serialNumber;
};

View File

@ -20,6 +20,7 @@
#include "RiaColorTools.h"
#include "RiaGuiApplication.h"
#include "RiaHashTools.h"
#include "RiaPreferences.h"
#include "RiaQDateTimeTools.h"
#include "RiaResultNames.h"
@ -116,6 +117,7 @@ CAF_PDM_SOURCE_INIT( RimEnsembleCurveSet, "RimEnsembleCurveSet" );
//--------------------------------------------------------------------------------------------------
RimEnsembleCurveSet::RimEnsembleCurveSet()
: filterChanged( this )
, m_hash( 0 )
{
CAF_PDM_InitObject( "Ensemble Curve Set", ":/EnsembleCurveSet16x16.png" );
@ -1664,26 +1666,38 @@ void RimEnsembleCurveSet::appendOptionItemsForSummaryAddresses( QList<caf::PdmOp
{
if ( !summaryCaseGroup ) return;
std::set<RifEclipseSummaryAddress> addrSet;
for ( RimSummaryCase* summaryCase : summaryCaseGroup->allSummaryCases() )
auto allSummaryCases = summaryCaseGroup->allSummaryCases();
auto hash = RiaHashTools::hash( allSummaryCases );
if ( hash != m_hash )
{
RifSummaryReaderInterface* reader = summaryCase->summaryReader();
const std::set<RifEclipseSummaryAddress>& addrs = reader ? reader->allResultAddresses() : std::set<RifEclipseSummaryAddress>();
m_hash = hash;
for ( auto& addr : addrs )
std::set<RifEclipseSummaryAddress> addressesForEnsemble;
for ( RimSummaryCase* summaryCase : allSummaryCases )
{
addrSet.insert( addr );
if ( !summaryCase ) continue;
if ( auto reader = summaryCase->summaryReader() )
{
const auto& addrs = reader->allResultAddresses();
addressesForEnsemble.insert( addrs.begin(), addrs.end() );
}
}
m_cachedAddressOptions.clear();
for ( const auto& addr : addressesForEnsemble )
{
std::string name = addr.uiText();
QString s = QString::fromStdString( name );
m_cachedAddressOptions.push_back( caf::PdmOptionItemInfo( s, QVariant::fromValue( addr ) ) );
}
m_cachedAddressOptions.push_front(
caf::PdmOptionItemInfo( RiaResultNames::undefinedResultName(), QVariant::fromValue( RifEclipseSummaryAddress() ) ) );
}
for ( auto& addr : addrSet )
{
std::string name = addr.uiText();
QString s = QString::fromStdString( name );
options->push_back( caf::PdmOptionItemInfo( s, QVariant::fromValue( addr ) ) );
}
options->push_front( caf::PdmOptionItemInfo( RiaResultNames::undefinedResultName(), QVariant::fromValue( RifEclipseSummaryAddress() ) ) );
options->append( m_cachedAddressOptions );
}
//--------------------------------------------------------------------------------------------------

View File

@ -180,7 +180,7 @@ public:
void appendColorGroup( caf::PdmUiOrdering& uiOrdering );
static void appendOptionItemsForSummaryAddresses( QList<caf::PdmOptionItemInfo>* options, RimSummaryEnsemble* summaryCaseGroup );
void appendOptionItemsForSummaryAddresses( QList<caf::PdmOptionItemInfo>* options, RimSummaryEnsemble* summaryCaseGroup );
const RimEnsembleCurveFilterCollection* curveFilters() const;
@ -317,4 +317,7 @@ private:
bool m_disableStatisticCurves;
bool m_isCurveSetFiltered;
QList<caf::PdmOptionItemInfo> m_cachedAddressOptions;
size_t m_hash;
};

View File

@ -19,6 +19,7 @@
#include "RimEnsembleStatisticsCase.h"
#include "RiaCurveMerger.h"
#include "RiaHashTools.h"
#include "RiaTimeHistoryCurveResampler.h"
#include "Summary/RiaSummaryTools.h"
@ -129,6 +130,11 @@ void RimEnsembleStatisticsCase::calculate( const std::vector<RimSummaryCase*>& s
const RifEclipseSummaryAddress& inputAddress,
bool includeIncompleteCurves )
{
auto hash = RiaHashTools::hash( summaryCases, inputAddress.toEclipseTextAddress(), includeIncompleteCurves );
if ( hash == m_hash ) return;
m_hash = hash;
clearData();
if ( !inputAddress.isValid() ) return;

View File

@ -64,4 +64,5 @@ private:
std::vector<double> m_meanData;
caf::PdmPointer<RimSummaryCase> m_firstSummaryCase;
size_t m_hash = 0;
};

View File

@ -225,6 +225,15 @@ void RimSummaryCase::buildChildNodes()
m_dataVectorFolders->updateFolderStructure( addresses, m_caseId );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RimSummaryCase::serialNumber()
{
auto reader = summaryReader();
return reader ? reader->serialNumber() : -1;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -18,6 +18,9 @@
#pragma once
#include "RiaDefines.h"
#include "RiaHashTools.h"
#include "RigCaseRealizationParameters.h"
#include "RimCaseDisplayNameTools.h"
@ -105,6 +108,7 @@ protected:
private:
void buildChildNodes();
int serialNumber();
protected:
caf::PdmField<QString> m_displayName;
@ -123,4 +127,25 @@ protected:
caf::PdmField<bool> m_useAutoShortName_OBSOLETE;
static const QString DEFAULT_DISPLAY_NAME;
friend struct std::hash<RimSummaryCase*>;
};
// Custom specialization of std::hash injected in namespace std
// NB! Note that this is a specialization of std::hash for a pointer type
template <>
struct std::hash<RimSummaryCase*>
{
std::size_t operator()( RimSummaryCase* s ) const noexcept
{
if ( !s ) return 0;
auto serialNumber = s->serialNumber();
if ( serialNumber != -1 )
{
return RiaHashTools::hash( serialNumber );
}
return RiaHashTools::hash( s->summaryHeaderFilename().toStdString() );
}
};