File indexing completed on 2023-03-17 11:16:01
0001 #include <algorithm>
0002 #include <cstddef>
0003 #include <cstdlib>
0004 #include <cstring>
0005 #include <mutex>
0006 #include <set>
0007
0008 #include "FWCore/Utilities/interface/thread_safety_macros.h"
0009 #include "PhysicsTools/MVAComputer/interface/AtomicId.h"
0010
0011 namespace {
0012 struct StringLess {
0013 bool operator()(const char *id1, const char *id2) const { return std::strcmp(id1, id2) < 0; }
0014 };
0015
0016 class IdCache {
0017 public:
0018 ~IdCache();
0019
0020 inline const char *findOrInsert(const char *string) throw();
0021
0022 private:
0023 typedef std::multiset<const char *, StringLess> IdSet;
0024
0025 IdSet idSet;
0026 std::allocator<char> stringAllocator;
0027 std::mutex mutex;
0028 };
0029 }
0030
0031 IdCache::~IdCache() {
0032 for (std::multiset<const char *, StringLess>::iterator iter = idSet.begin(); iter != idSet.end(); iter++)
0033 stringAllocator.deallocate(const_cast<char *>(*iter), std::strlen(*iter) + 1);
0034 }
0035
0036 const char *IdCache::findOrInsert(const char *string) throw() {
0037 std::lock_guard<std::mutex> scoped_lock(mutex);
0038
0039 IdSet::iterator pos = idSet.lower_bound(string);
0040 if (pos != idSet.end() && std::strcmp(*pos, string) == 0)
0041 return *pos;
0042
0043 std::size_t size = std::strlen(string) + 1;
0044 char *unique = stringAllocator.allocate(size);
0045 std::memcpy(unique, string, size);
0046
0047 idSet.insert(pos, unique);
0048
0049 return unique;
0050 }
0051
0052 namespace PhysicsTools {
0053
0054 static IdCache &getAtomicIdCache() {
0055 CMS_THREAD_SAFE static IdCache atomicIdCache;
0056 return atomicIdCache;
0057 }
0058
0059 const char *AtomicId::lookup(const char *string) throw() {
0060 if (string)
0061 return getAtomicIdCache().findOrInsert(string);
0062
0063 return nullptr;
0064 }
0065
0066 }