CMS 3D CMS Logo

IgStateKey.cc

Go to the documentation of this file.
00001 //<<<<<< INCLUDES                                                       >>>>>>
00002 
00003 #include "Iguana/Framework/interface/IgStateKey.h"
00004 #include "classlib/utils/DebugAids.h"
00005 
00006 //<<<<<< PRIVATE DEFINES                                                >>>>>>
00007 //<<<<<< PRIVATE CONSTANTS                                              >>>>>>
00008 //<<<<<< PRIVATE TYPES                                                  >>>>>>
00009 //<<<<<< PRIVATE VARIABLE DEFINITIONS                                   >>>>>>
00010 //<<<<<< PUBLIC VARIABLE DEFINITIONS                                    >>>>>>
00011 //<<<<<< CLASS STRUCTURE INITIALIZATION                                 >>>>>>
00012 
00013 unsigned IgStateKey::s_count = 0;
00014 
00015 //<<<<<< PRIVATE FUNCTION DEFINITIONS                                   >>>>>>
00016 //<<<<<< PUBLIC FUNCTION DEFINITIONS                                    >>>>>>
00017 //<<<<<< MEMBER FUNCTION DEFINITIONS                                    >>>>>>
00018 
00020 IgStateKeyDef::IgStateKeyDef (const std::string &label)
00021     : IgStateKey (create (label)),
00022       m_label (label)
00023 {}
00024 
00026 IgStateKeyDef::~IgStateKeyDef (void)
00027 { remove (m_label); }
00028 
00032 
00033 IgStateKey::IgStateKey (unsigned value)
00034     : m_value (value)
00035 {}
00036 
00038 std::string
00039 IgStateKey::label (void) const
00040 {
00041     Map &keys = keymap ();
00042     for (Map::iterator pos = keys.begin (); pos != keys.end (); ++pos)
00043         if (pos->second == m_value)
00044             return pos->first;
00045 
00046     // This can occur for the unknown key (~0U, see #index())
00047     return "<UNDEFINED>";
00048 }
00049 
00051 
00053 IgStateKey::Map &
00054 IgStateKey::keymap (void)
00055 {
00056     static char buf [sizeof (Map)];
00057     static Map  *bufmap = new (buf) Map;
00058     return *bufmap;
00059 }
00060 
00062 unsigned
00063 IgStateKey::create (const std::string &label)
00064 {
00065     // FIXME: Thread safety.
00066 
00067     // The logic here accommodates for keys that are getting recreated
00068     // due to dynamic loading and unloading of a library.  Once a key
00069     // has been created, we always keep it in the same index.  If the
00070     // library is unloaded, we keep the key in the dictionary but mark
00071     // it unused by turning on the 32nd (~ top) bit.  If the library
00072     // is subsequently re-loaded, we give it the same index back and
00073     // turn the bit off to indicate the index is in use again.
00074     ASSERT (! label.empty ());
00075     Map &keys = keymap ();
00076     if (! keys.count (label))
00077     {
00078         // Not seen this one before.  Allocate a new index for this.
00079         // Make sure we don't overrun to the area of our mark bits (if
00080         // this triggers, we'll be screwed anyway as we have far too
00081         // many state elements by then in every state).
00082         ASSERT (s_count < 0x8000000);
00083         unsigned value = s_count++;
00084         keys [label] = value;
00085         return value;
00086     }
00087     else
00088     {
00089         // We've seen this before.  Make sure the key index is not
00090         // active and then give it back.
00091         ASSERT (keys [label] & 0x8000000);
00092         unsigned &value = keys [label];
00093         value &= ~0x8000000;
00094         return value;
00095     }
00096 }
00097 
00099 void
00100 IgStateKey::remove (const std::string &label)
00101 {
00102     // See comments in #create() for the logic.  FIXME: Thread safety.
00103     ASSERT (! label.empty ());
00104     Map &keys = keymap ();
00105     ASSERT (keys.count (label));
00106     ASSERT (! (keys [label] & 0x8000000));
00107     keys [label] |= 0x8000000;
00108 }
00109 
00113 IgStateKey
00114 IgStateKey::index (const std::string &label)
00115 {
00116     // FIXME: Thread safety.
00117     ASSERT (! label.empty ());
00118     Map           &keys = keymap ();
00119     Map::iterator pos = keys.find (label);
00120     return pos == keys.end () ? ~0U : pos->second;
00121 }

Generated on Tue Jun 9 17:38:29 2009 for CMSSW by  doxygen 1.5.4