diff --git a/GeoModelCore/GeoModelHelpers/GeoModelHelpers/GeoDeDuplicator.h b/GeoModelCore/GeoModelHelpers/GeoModelHelpers/GeoDeDuplicator.h index 1c2ce58ee5206e128b7b1efa378de1f45da74395..60a4cfd17b5920de8e7d86f2d349395f8afd72b4 100644 --- a/GeoModelCore/GeoModelHelpers/GeoModelHelpers/GeoDeDuplicator.h +++ b/GeoModelCore/GeoModelHelpers/GeoModelHelpers/GeoDeDuplicator.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration */ #ifndef GeoModelHelpers_GEODEDUPLICATOR_H #define GeoModelHelpers_GEODEDUPLICATOR_H @@ -7,6 +7,8 @@ #include "GeoModelKernel/GeoPhysVol.h" #include "GeoModelKernel/GeoShape.h" #include "GeoModelKernel/GeoTransform.h" +#include "GeoModelKernel/GeoSerialIdentifier.h" +#include "GeoModelKernel/GeoNameTag.h" #include "GeoModelHelpers/GeoLogVolSorter.h" #include "GeoModelHelpers/GeoPhysVolSorter.h" @@ -14,6 +16,7 @@ #include "GeoModelHelpers/TransformSorter.h" #include <set> +#include <map> #include <mutex> #include <thread> /*** @@ -71,20 +74,48 @@ class GeoDeDuplicator { using GeoLogVolPtr = GeoIntrusivePtr<GeoLogVol>; using GeoTrfPtr = GeoIntrusivePtr<GeoTransform>; using GeoPhysVolPtr = GeoIntrusivePtr<GeoPhysVol>; + using GeoSerialIdPtr = GeoIntrusivePtr<GeoSerialIdentifier>; + using GeoNamePtr = GeoIntrusivePtr<GeoNameTag>; + /** @brief Standard constructor */ GeoDeDuplicator() = default; + /** @brief Standard destructor */ virtual ~GeoDeDuplicator() = default; - + /** @brief Takes a GeoPhysVol and adds it to the cache. If physVol deduplication + * is turned on and an equivalent volume has been parsed before, + * then that volume is returned instead */ GeoPhysVolPtr cacheVolume(GeoPhysVolPtr vol) const; + /** @brief Converts the transform into GeoTransform with(out) deduplication + * of equivalent transform nodes */ GeoTrfPtr makeTransform(const GeoTrf::Transform3D& trf) const; + /** @brief Take a GeoTransform node and adds it to the cahce. If transform deduplication + * is turned on and an equivalent transform node has been parsed before, + * then that mpde is returned instead */ + GeoTrfPtr cacheTransform(GeoTrfPtr transform) const; + /** @brief Takes a GeoLogVol and adds it to the cache. If LogVol deduplication + * is turned on and an equivalent volume has been parsed before, + * then that volume is returned instead */ GeoLogVolPtr cacheVolume(GeoLogVolPtr vol) const; + /** @brief Takes a GeoShape and adds it to the cache. If shape deduplication + * is turned on and an equivalent shape has been parsed before, + * then that shape is returned instead */ GeoShapePtr cacheShape(GeoShapePtr shape) const; + /** @brief Returns a new GeoName tag */ + GeoNamePtr nameTag(const std::string& tagName) const; + /** @brief Returns a new GeoSerial Id */ + GeoSerialIdPtr serialId(const int id) const; + /** @brief Toggles whether shape deduplication shall be enabled */ void setShapeDeDuplication(bool enable); + /** @brief Toggles whether logVol deduplication shall be enabled */ void setLogVolDeDuplication(bool enable); + /** @brief Toggles whether transform node deduplication shall be enabled */ void setTransformDeDuplication(bool enable); + /** @brief Toggles whether physVol node deduplication shall be enabled */ void setPhysVolDeDuplication(bool enable); + /** @brief Clears the shared Shape / Transform / SerialId & NameTag cache */ + static void clearSharedCaches(); private: bool m_deDuplicateLogVol{true}; bool m_deDuplicatePhysVol{true}; @@ -94,12 +125,17 @@ class GeoDeDuplicator { using LogVolSet = std::set<GeoLogVolPtr, GeoLogVolSorter>; using TrfSet = std::set<GeoTrfPtr, GeoTrf::TransformSorter>; using ShapeSet = std::set<GeoShapePtr, GeoShapeSorter>; + using SerialIdMap = std::map<int, GeoSerialIdPtr>; + using NameTagMap = std::map<std::string, GeoNamePtr>; + mutable PhysVolSet m_physVolStore{}; mutable LogVolSet m_logVolStore{}; mutable std::vector<GeoIntrusivePtr<const RCBase>> m_genericCache{}; static TrfSet s_trfStore; static ShapeSet s_shapeStore; + static SerialIdMap s_serialIds; + static NameTagMap s_nameTags; mutable std::mutex m_mutex{}; }; diff --git a/GeoModelCore/GeoModelHelpers/src/GeoDeDuplicator.cxx b/GeoModelCore/GeoModelHelpers/src/GeoDeDuplicator.cxx index e76926299712016ef55939b44ef68e56762bf580..19432f217f40839aadecf876a62f2b4c8f0bce73 100644 --- a/GeoModelCore/GeoModelHelpers/src/GeoDeDuplicator.cxx +++ b/GeoModelCore/GeoModelHelpers/src/GeoDeDuplicator.cxx @@ -1,11 +1,14 @@ /* - Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration */ #include "GeoModelHelpers/GeoDeDuplicator.h" GeoDeDuplicator::TrfSet GeoDeDuplicator::s_trfStore{}; GeoDeDuplicator::ShapeSet GeoDeDuplicator::s_shapeStore{}; +GeoDeDuplicator::SerialIdMap GeoDeDuplicator::s_serialIds{}; +GeoDeDuplicator::NameTagMap GeoDeDuplicator::s_nameTags{}; + namespace { std::mutex s_mutex{}; } @@ -23,9 +26,19 @@ void GeoDeDuplicator::setPhysVolDeDuplication(bool enable) { m_deDuplicatePhysVol = enable; } +void GeoDeDuplicator::clearSharedCaches() { + s_trfStore.clear(); + s_shapeStore.clear(); + s_serialIds.clear(); + s_nameTags.clear(); +} + GeoDeDuplicator::GeoTrfPtr GeoDeDuplicator::makeTransform(const GeoTrf::Transform3D& trf) const { - GeoTrfPtr trfNode{make_intrusive<GeoTransform>(trf)}; + return cacheTransform(make_intrusive<GeoTransform>(trf)); + } +GeoDeDuplicator::GeoTrfPtr + GeoDeDuplicator::cacheTransform(GeoTrfPtr trfNode) const { if (!m_deDuplicateTransform) { std::lock_guard guard{m_mutex}; m_genericCache.push_back(trfNode); @@ -62,3 +75,24 @@ GeoDeDuplicator::GeoShapePtr std::lock_guard guard{s_mutex}; return *s_shapeStore.insert(shape).first; } + +GeoDeDuplicator::GeoNamePtr GeoDeDuplicator::nameTag(const std::string& tagName) const{ + std::lock_guard guard{s_mutex}; + NameTagMap::const_iterator itr = s_nameTags.find(tagName); + if (itr != s_nameTags.end()){ + return itr->second; + } + GeoNamePtr newTag = make_intrusive<GeoNameTag>(tagName); + s_nameTags.insert(std::make_pair(tagName, newTag)); + return newTag; +} +GeoDeDuplicator::GeoSerialIdPtr GeoDeDuplicator::serialId(const int id) const { + std::lock_guard guard{s_mutex}; + SerialIdMap::const_iterator itr = s_serialIds.find(id); + if (itr != s_serialIds.end()){ + return itr->second; + } + GeoSerialIdPtr newId = make_intrusive<GeoSerialIdentifier>(id); + s_serialIds.insert(std::make_pair(id, newId)); + return newId; +} \ No newline at end of file diff --git a/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoNameTag.h b/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoNameTag.h index fcb7fe55d6b2bbd8031ccf01e400a6b1304ad07c..38868d29e5f050ab9e574be5523e5f9884edcd23 100644 --- a/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoNameTag.h +++ b/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoNameTag.h @@ -25,21 +25,15 @@ class GeoNameTag : public GeoGraphNode // Specifies the name of the next physical volume in the // node tree. - const std::string& getName () const; + const std::string& getName() const { + return m_name; + } protected: virtual ~GeoNameTag(); private: - GeoNameTag(const GeoNameTag &right); - GeoNameTag & operator=(const GeoNameTag &right); - - std::string m_name; + std::string m_name{}; }; -inline const std::string& GeoNameTag::getName () const -{ - return m_name; -} - #endif diff --git a/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoSerialIdentifier.h b/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoSerialIdentifier.h index b98285bda000f7da1a2bfd1a39d23aa7bb607fc2..971f435b8343ed1b0af9be1e575b89c755f69c04 100644 --- a/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoSerialIdentifier.h +++ b/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoSerialIdentifier.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration */ #ifndef GEOMODELKERNEL_GEOSERIALIDENTIFIER_H @@ -13,30 +13,23 @@ #include "GeoModelKernel/GeoGraphNode.h" -class GeoSerialIdentifier : public GeoGraphNode -{ +class GeoSerialIdentifier : public GeoGraphNode { public: GeoSerialIdentifier(int baseId); virtual void exec(GeoNodeAction *action) const; - inline int getBaseId() const; + inline int getBaseId() const{ + return m_baseId; + } protected: - virtual ~GeoSerialIdentifier(); + virtual ~GeoSerialIdentifier(); private: - GeoSerialIdentifier(const GeoSerialIdentifier &right); - const GeoSerialIdentifier & operator=(const GeoSerialIdentifier &right); - - int m_baseId; + int m_baseId{0}; }; -inline int GeoSerialIdentifier::getBaseId() const -{ - return m_baseId; -} - #endif