From 819352d0f00062cc2e7efeb67cb18cf3fa8c582f Mon Sep 17 00:00:00 2001
From: Johannes Josef Junggeburth <johannes.josef.junggeburth@cern.ch>
Date: Fri, 17 Jan 2025 10:58:53 +0100
Subject: [PATCH] Add GeoId caching

---
 .../GeoModelHelpers/GeoDeDuplicator.h            | 12 +++++++++---
 .../GeoModelHelpers/src/GeoDeDuplicator.cxx      | 16 +++++++++++++++-
 2 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/GeoModelCore/GeoModelHelpers/GeoModelHelpers/GeoDeDuplicator.h b/GeoModelCore/GeoModelHelpers/GeoModelHelpers/GeoDeDuplicator.h
index 60a4cfd17..1e0dbd8c1 100644
--- a/GeoModelCore/GeoModelHelpers/GeoModelHelpers/GeoDeDuplicator.h
+++ b/GeoModelCore/GeoModelHelpers/GeoModelHelpers/GeoDeDuplicator.h
@@ -9,6 +9,7 @@
 #include "GeoModelKernel/GeoTransform.h"
 #include "GeoModelKernel/GeoSerialIdentifier.h"
 #include "GeoModelKernel/GeoNameTag.h"
+#include "GeoModelKernel/GeoIdentifierTag.h"
 
 #include "GeoModelHelpers/GeoLogVolSorter.h"
 #include "GeoModelHelpers/GeoPhysVolSorter.h"
@@ -16,7 +17,7 @@
 #include "GeoModelHelpers/TransformSorter.h"
 
 #include <set>
-#include <map>
+#include <unordered_map>
 #include <mutex>
 #include <thread>
 /***
@@ -75,6 +76,7 @@ class GeoDeDuplicator {
         using GeoTrfPtr =  GeoIntrusivePtr<GeoTransform>;
         using GeoPhysVolPtr = GeoIntrusivePtr<GeoPhysVol>;
         using GeoSerialIdPtr = GeoIntrusivePtr<GeoSerialIdentifier>;
+        using GeoIdPtr = GeoIntrusivePtr<GeoIdentifierTag>;
         using GeoNamePtr = GeoIntrusivePtr<GeoNameTag>;
 
         /** @brief Standard constructor */
@@ -104,6 +106,8 @@ class GeoDeDuplicator {
         GeoNamePtr nameTag(const std::string& tagName) const;
         /** @brief Returns a new GeoSerial Id  */
         GeoSerialIdPtr serialId(const int id) const;
+        /** @brief Returns a new GeoIdentifier tag */
+        GeoIdPtr geoId(const int id) const;
 
         /** @brief Toggles whether shape deduplication shall be enabled */
         void setShapeDeDuplication(bool enable);
@@ -125,8 +129,9 @@ 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>;
+        using SerialIdMap = std::unordered_map<int, GeoSerialIdPtr>;
+        using GeoIdMap = std::unordered_map<int, GeoIdPtr>;
+        using NameTagMap = std::unordered_map<std::string, GeoNamePtr>;
 
         mutable PhysVolSet m_physVolStore{};
         mutable LogVolSet m_logVolStore{};
@@ -136,6 +141,7 @@ class GeoDeDuplicator {
         static ShapeSet s_shapeStore;
         static SerialIdMap s_serialIds;
         static NameTagMap s_nameTags;
+        static GeoIdMap s_geoIds;
 
         mutable std::mutex m_mutex{};
 };
diff --git a/GeoModelCore/GeoModelHelpers/src/GeoDeDuplicator.cxx b/GeoModelCore/GeoModelHelpers/src/GeoDeDuplicator.cxx
index 19432f217..f8ecad113 100644
--- a/GeoModelCore/GeoModelHelpers/src/GeoDeDuplicator.cxx
+++ b/GeoModelCore/GeoModelHelpers/src/GeoDeDuplicator.cxx
@@ -8,6 +8,7 @@ GeoDeDuplicator::TrfSet GeoDeDuplicator::s_trfStore{};
 GeoDeDuplicator::ShapeSet GeoDeDuplicator::s_shapeStore{};
 GeoDeDuplicator::SerialIdMap GeoDeDuplicator::s_serialIds{};
 GeoDeDuplicator::NameTagMap GeoDeDuplicator::s_nameTags{};
+GeoDeDuplicator::GeoIdMap GeoDeDuplicator::s_geoIds{};
 
 namespace {
     std::mutex s_mutex{};
@@ -31,6 +32,7 @@ void GeoDeDuplicator::clearSharedCaches() {
     s_shapeStore.clear();
     s_serialIds.clear();
     s_nameTags.clear();
+    s_geoIds.clear();
 }
 
 GeoDeDuplicator::GeoTrfPtr 
@@ -86,7 +88,8 @@ GeoDeDuplicator::GeoNamePtr GeoDeDuplicator::nameTag(const std::string& tagName)
     s_nameTags.insert(std::make_pair(tagName, newTag));
     return newTag;
 }
-GeoDeDuplicator::GeoSerialIdPtr GeoDeDuplicator::serialId(const int id) const {
+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()){
@@ -95,4 +98,15 @@ GeoDeDuplicator::GeoSerialIdPtr GeoDeDuplicator::serialId(const int id) const {
     GeoSerialIdPtr newId = make_intrusive<GeoSerialIdentifier>(id);
     s_serialIds.insert(std::make_pair(id, newId));
     return newId;
+}
+GeoDeDuplicator::GeoIdPtr 
+    GeoDeDuplicator::geoId(const int id) const {
+    std::lock_guard guard{s_mutex};
+    GeoIdMap::const_iterator itr = s_geoIds.find(id);
+    if (itr != s_geoIds.end()){
+        return itr->second;
+    }
+    GeoIdPtr newId = make_intrusive<GeoIdentifierTag>(id);
+    s_geoIds.insert(std::make_pair(id, newId));
+    return newId;
 }
\ No newline at end of file
-- 
GitLab