From e8f2d6569055df7bd68702fae5be4bd50e37944e Mon Sep 17 00:00:00 2001 From: Ingmar Schoegl Date: Sun, 5 Mar 2023 10:54:19 -0600 Subject: [PATCH] [clib] Add reverse lookup table to SharedCabinet --- src/clib/Cabinet.h | 45 ++++++++++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/src/clib/Cabinet.h b/src/clib/Cabinet.h index fab4cc50ad3..c2840588810 100644 --- a/src/clib/Cabinet.h +++ b/src/clib/Cabinet.h @@ -9,6 +9,7 @@ #define CT_CABINET_H #include "cantera/base/ctexceptions.h" +#include namespace Cantera { @@ -216,7 +217,7 @@ class Cabinet * maintained by the appropriate SharedCabinet instance. The pointer is retrieved * from the list by the interface function, the desired method is invoked, and the * result returned to the non-C++ calling procedure. By storing the pointers in a - * SharedCabinet, there is no need to encode them in a std::string or integer and pass + * SharedCabinet, there is no need to encode them in a string or integer and pass * them out to the non-C++ calling routine, as some other interfacing schemes do. * * The SharedCabinet class can be used to store pointers to arbitrary objects. In @@ -243,7 +244,8 @@ template class SharedCabinet { public: - typedef std::vector>& dataRef; + typedef vector>& dataRef; + typedef std::unordered_map& lookupRef; /** * Constructor. @@ -253,10 +255,12 @@ class SharedCabinet /** * Add a new object. The index of the object is returned. */ - static int add(std::shared_ptr obj) { + static int add(shared_ptr obj) { dataRef data = getData(); data.push_back(obj); int index = data.size() - 1; + lookupRef lookup = getLookup(); + lookup[obj.get()] = index; return index; } @@ -284,6 +288,7 @@ class SharedCabinet */ static int reset() { getData().clear(); + getLookup().clear(); return 0; } @@ -293,6 +298,7 @@ class SharedCabinet static void del(size_t n) { dataRef data = getData(); if (n >= 0 && n < data.size()) { + getLookup().erase(data[n].get()); data[n].reset(); } else { throw CanteraError("SharedCabinet::del", @@ -303,7 +309,7 @@ class SharedCabinet /** * Return a shared pointer to object n. */ - static std::shared_ptr& at(size_t n) { + static shared_ptr& at(size_t n) { dataRef data = getData(); if (n < 0 || n >= data.size()) { throw CanteraError("SharedCabinet::at", "Index {} out of range.", n); @@ -340,15 +346,11 @@ class SharedCabinet * object is not in the SharedCabinet. */ static int index(const M& obj) { - dataRef data = getData(); - int count = 0; - for (const auto& item : data) { - if (item.get() == &obj) { - return count; - } - count++; + lookupRef lookup = getLookup(); + if (!lookup.count(&obj)) { + return -1; } - return -1; + return lookup.at(&obj); } private: @@ -364,15 +366,32 @@ class SharedCabinet return s_storage->m_table; } + /** + * Static function that returns a pointer to the reverse lookup table of + * the singleton SharedCabinet instance. All member functions should + * access the lookup table through this function. + */ + static lookupRef getLookup() { + if (s_storage == nullptr) { + s_storage = new SharedCabinet(); + } + return s_storage->m_lookup; + } + /** * Pointer to the single instance of this class. */ static SharedCabinet* s_storage; + /** + * Reverse lookup table for the single instance of this class. + */ + std::unordered_map m_lookup; + /** * list to hold pointers to objects. */ - std::vector> m_table; + vector> m_table; }; }