Skip to content
Snippets Groups Projects
Commit 30e336a2 authored by Frank Winklmeier's avatar Frank Winklmeier
Browse files

DataObjID: on-demand lookup of className

Retrieving the class name to a CLID requires querying the `ClassIDSvc`,
which (at least in the ATLAS implementation) requires taking a lock
during the lookup and in general might be a costly operation. Instead of
doing this in the construction of `DataObjID` only lookup the
class name when needed and then cache the result.

Also cleanup the needlessly complicated code of one-time retrieval of
ClassIDSvc by using a simple static.

This fixes some performance problems in multi-threaded ATLAS
jobs (ATEAM-1054).
parent c86afe8b
No related branches found
No related tags found
No related merge requests found
Pipeline #10566945 failed
/***********************************************************************************\ /***********************************************************************************\
* (c) Copyright 1998-2024 CERN for the benefit of the LHCb and ATLAS collaborations * * (c) Copyright 1998-2025 CERN for the benefit of the LHCb and ATLAS collaborations *
* * * *
* This software is distributed under the terms of the Apache version 2 licence, * * This software is distributed under the terms of the Apache version 2 licence, *
* copied verbatim in the file "LICENSE". * * copied verbatim in the file "LICENSE". *
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <GaudiKernel/StatusCode.h> #include <GaudiKernel/StatusCode.h>
#include <iostream> #include <iostream>
#include <memory>
#include <mutex> #include <mutex>
#include <string> #include <string>
#include <unordered_set> #include <unordered_set>
...@@ -48,19 +49,27 @@ class DataObjID { ...@@ -48,19 +49,27 @@ class DataObjID {
public: public:
friend DataObjID_Hasher; friend DataObjID_Hasher;
DataObjID() = default; DataObjID() = default;
DataObjID( const DataObjID& ) = default; DataObjID( const DataObjID& other )
: m_clid( other.m_clid ), m_hash( other.m_hash ), m_key( other.m_key ), m_className( other.m_className ) {}
DataObjID( std::string key ); DataObjID( std::string key );
DataObjID( const CLID& clid, std::string key ); DataObjID( const CLID& clid, std::string key );
DataObjID( std::string className, std::string key ); DataObjID( std::string className, std::string key );
DataObjID& operator=( const DataObjID& ) = default; DataObjID& operator=( const DataObjID& other ) {
m_clid = other.m_clid;
m_hash = other.m_hash;
m_key = other.m_key;
m_className = other.m_className;
return *this;
}
/// only return the last part of the key /// only return the last part of the key
const std::string& key() const { return m_key; } const std::string& key() const { return m_key; }
/// return the ClassName (if available) /// return the ClassName (if available)
const std::string& className() const { return m_className; } const std::string& className() const;
/// combination of the key and the ClassName, mostly for debugging /// combination of the key and the ClassName, mostly for debugging
std::string fullKey() const; std::string fullKey() const;
...@@ -81,22 +90,18 @@ public: ...@@ -81,22 +90,18 @@ public:
private: private:
void hashGen(); void hashGen();
void setClid(); void setClid();
void setClassName();
CLID m_clid{ 0 }; CLID m_clid{ 0 };
std::size_t m_hash{ 0 }; std::size_t m_hash{ 0 };
std::string m_key{ "INVALID" }; std::string m_key{ "INVALID" };
std::string m_className; mutable std::string m_className;
mutable std::once_flag m_setClassName;
static IClassIDSvc* p_clidSvc;
static std::once_flag m_ip;
}; };
inline DataObjID::DataObjID( std::string key ) : m_key( std::move( key ) ) { hashGen(); } inline DataObjID::DataObjID( std::string key ) : m_key( std::move( key ) ) { hashGen(); }
inline DataObjID::DataObjID( const CLID& clid, std::string key ) : m_clid( clid ), m_key( std::move( key ) ) { inline DataObjID::DataObjID( const CLID& clid, std::string key ) : m_clid( clid ), m_key( std::move( key ) ) {
setClassName();
hashGen(); hashGen();
} }
......
/***********************************************************************************\ /***********************************************************************************\
* (c) Copyright 1998-2024 CERN for the benefit of the LHCb and ATLAS collaborations * * (c) Copyright 1998-2025 CERN for the benefit of the LHCb and ATLAS collaborations *
* * * *
* This software is distributed under the terms of the Apache version 2 licence, * * This software is distributed under the terms of the Apache version 2 licence, *
* copied verbatim in the file "LICENSE". * * copied verbatim in the file "LICENSE". *
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <GaudiKernel/DataObjID.h> #include <GaudiKernel/DataObjID.h>
#include <GaudiKernel/IClassIDSvc.h> #include <GaudiKernel/IClassIDSvc.h>
#include <GaudiKernel/ISvcLocator.h> #include <GaudiKernel/ISvcLocator.h>
#include <GaudiKernel/ToStream.h>
#include <functional> #include <functional>
#include <iomanip> #include <iomanip>
#include <iostream> #include <iostream>
...@@ -56,31 +57,22 @@ namespace Gaudi { ...@@ -56,31 +57,22 @@ namespace Gaudi {
StatusCode parse( DataObjID& dest, std::string_view src ) { return Gaudi::Parsers::parse_( dest, quote( src ) ); } StatusCode parse( DataObjID& dest, std::string_view src ) { return Gaudi::Parsers::parse_( dest, quote( src ) ); }
IClassIDSvc* DataObjID::p_clidSvc( nullptr );
std::once_flag DataObjID::m_ip;
namespace { namespace {
auto getClidSvc = []( std::reference_wrapper<IClassIDSvc*> p ) { /// Helper to retrieve and cache pointer to ClassIDSvc if available
p.get() = Gaudi::svcLocator()->service<IClassIDSvc>( "ClassIDSvc" ).get(); IClassIDSvc* getClidSvc() {
static IClassIDSvc* clidSvc = Gaudi::svcLocator()->service<IClassIDSvc>( "ClassIDSvc" ).get();
return clidSvc;
}; };
} } // namespace
void DataObjID::setClid() { void DataObjID::setClid() {
std::call_once( m_ip, getClidSvc, std::ref( p_clidSvc ) );
if ( !p_clidSvc || p_clidSvc->getIDOfTypeName( m_className, m_clid ).isFailure() ) { if ( !getClidSvc() || getClidSvc()->getIDOfTypeName( m_className, m_clid ).isFailure() ) {
m_clid = 0; m_clid = 0;
m_className = "UNKNOWN_CLASS:" + m_className; m_className = "UNKNOWN_CLASS:" + m_className;
} }
} }
void DataObjID::setClassName() {
std::call_once( m_ip, getClidSvc, std::ref( p_clidSvc ) );
if ( !p_clidSvc || p_clidSvc->getTypeNameOfID( m_clid, m_className ).isFailure() ) {
m_className = "UNKNOW_CLID:" + std::to_string( m_clid );
}
}
void DataObjID::hashGen() { void DataObjID::hashGen() {
m_hash = ( std::hash<std::string>()( m_key ) ); m_hash = ( std::hash<std::string>()( m_key ) );
if ( m_clid != 0 ) { if ( m_clid != 0 ) {
...@@ -89,15 +81,27 @@ void DataObjID::hashGen() { ...@@ -89,15 +81,27 @@ void DataObjID::hashGen() {
} }
} }
#include <GaudiKernel/ToStream.h>
std::ostream& toStream( const DataObjID& d, std::ostream& os ) { std::ostream& toStream( const DataObjID& d, std::ostream& os ) {
using Gaudi::Utils::toStream; using Gaudi::Utils::toStream;
return ( d.m_clid != 0 || !d.m_className.empty() ) ? toStream( std::tie( d.m_className, d.m_key ), os ) return ( d.m_clid != 0 || !d.className().empty() ) ? toStream( std::tie( d.className(), d.m_key ), os )
: toStream( d.m_key, os ); : toStream( d.m_key, os );
} }
const std::string& DataObjID::className() const {
// Set class name once if not done already
if ( m_clid !=0 && m_className.empty() ) {
std::call_once( m_setClassName, [&]() {
if ( !getClidSvc() || getClidSvc()->getTypeNameOfID( m_clid, m_className ).isFailure() ) {
m_className = "UNKNOWN_CLID:" + std::to_string( m_clid );
}
} );
}
return m_className;
}
std::string DataObjID::fullKey() const { std::string DataObjID::fullKey() const {
return ( m_clid == 0 && m_className.empty() ) ? m_key : ( m_className + '/' + m_key ); return ( m_clid == 0 && m_className.empty() ) ? m_key : ( className() + '/' + m_key );
} }
std::string Gaudi::Details::Property::StringConverter<DataObjIDColl>::toString( const DataObjIDColl& v ) { std::string Gaudi::Details::Property::StringConverter<DataObjIDColl>::toString( const DataObjIDColl& v ) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment