CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_2_SLHC2/src/PhysicsTools/MVAComputer/src/AtomicId.cc

Go to the documentation of this file.
00001 #include <algorithm>
00002 #include <cstdlib>
00003 #include <cstddef>
00004 #include <cstring>
00005 #include <set>
00006 
00007 #include <boost/thread.hpp>
00008 
00009 #include "PhysicsTools/MVAComputer/interface/AtomicId.h"
00010 
00011 namespace { // anonymous
00012         struct StringLess {
00013                 bool operator()(const char *id1, const char *id2) const
00014                 { return std::strcmp(id1, id2) < 0; }
00015         };
00016 
00017         class IdCache {
00018             public:
00019                 ~IdCache();
00020 
00021                 inline const char *findOrInsert(const char *string) throw();
00022 
00023             private:
00024                 typedef std::multiset<const char *, StringLess> IdSet;
00025 
00026                 IdSet                           idSet;
00027                 static std::allocator<char>     stringAllocator;
00028                 mutable boost::mutex            mutex;
00029         };
00030 } // anonymous namespace
00031 
00032 std::allocator<char> IdCache::stringAllocator;
00033 
00034 IdCache::~IdCache()
00035 {
00036         for(std::multiset<const char*, StringLess>::iterator iter =
00037             idSet.begin(); iter != idSet.end(); iter++)
00038                 stringAllocator.deallocate(const_cast<char*>(*iter),
00039                                            std::strlen(*iter));
00040 }
00041 
00042 const char *IdCache::findOrInsert(const char *string) throw()
00043 {
00044         boost::mutex::scoped_lock scoped_lock(mutex);
00045 
00046         IdSet::iterator pos = idSet.lower_bound(string);
00047         if (pos != idSet.end() && std::strcmp(*pos, string) == 0)
00048                 return *pos;
00049 
00050         std::size_t size = std::strlen(string) + 1;
00051         char *unique = stringAllocator.allocate(size);
00052         std::memcpy(unique, string, size);
00053 
00054         idSet.insert(pos, unique);
00055 
00056         return unique;
00057 }
00058 
00059 namespace PhysicsTools {
00060 
00061 static IdCache &getAtomicIdCache()
00062 {
00063         static IdCache atomicIdCache;
00064         return atomicIdCache;
00065 }
00066 
00067 const char *AtomicId::lookup(const char *string) throw()
00068 {
00069         if (string)
00070                 return getAtomicIdCache().findOrInsert(string);
00071 
00072         return 0;
00073 }
00074 
00075 } // namespace PhysicsTools