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 {
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 }
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 }