CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_14/src/EventFilter/StorageManager/src/InitMsgCollection.cc

Go to the documentation of this file.
00001 // $Id: InitMsgCollection.cc,v 1.17 2012/04/20 10:48:02 mommsen Exp $
00003 
00004 #include "DataFormats/Streamer/interface/StreamedProducts.h"
00005 #include "EventFilter/StorageManager/interface/I2OChain.h"
00006 #include "EventFilter/StorageManager/interface/InitMsgCollection.h"
00007 #include "FWCore/Framework/interface/EventSelector.h"
00008 #include "FWCore/Utilities/interface/DebugMacros.h"
00009 #include "FWCore/Utilities/interface/Exception.h"
00010 #include "IOPool/Streamer/interface/DumpTools.h"
00011 #include "IOPool/Streamer/interface/OtherMessage.h"
00012 #include "IOPool/Streamer/interface/StreamerInputSource.h"
00013 #include "IOPool/Streamer/interface/Utilities.h"
00014 
00015 #include "boost/algorithm/string/trim.hpp"
00016 #include <iostream>
00017 
00018 using namespace stor;
00019 using namespace edm;
00020 
00021 InitMsgCollection::InitMsgCollection()
00022 {
00023   clear();
00024 }
00025 
00026 
00027 InitMsgCollection::~InitMsgCollection()
00028 {
00029 }
00030 
00031 
00032 bool InitMsgCollection::addIfUnique(InitMsgView const& initMsgView)
00033 {
00034   boost::mutex::scoped_lock sl(listLock_);
00035   
00036   // check if the outputModuleId was already seen
00037   const uint32_t outputModuleId = initMsgView.outputModuleId();
00038   InitMsgMap::iterator pos = initMsgMap_.lower_bound(outputModuleId);
00039   if ( pos != initMsgMap_.end() && !(initMsgMap_.key_comp()(outputModuleId, pos->first)))
00040     return false; // init message already exists
00041   
00042   checkOutputModuleLabel(initMsgView);
00043   
00044   // add the message to the internal list
00045   InitMsgSharedPtr serializedProds(new InitMsgBuffer(initMsgView.size()));
00046   std::copy(
00047     initMsgView.startAddress(),
00048     initMsgView.startAddress()+initMsgView.size(),
00049     &(*serializedProds)[0]
00050   );
00051   initMsgMap_.insert(pos, InitMsgMap::value_type(outputModuleId,serializedProds));
00052   
00053   return true; // new init message
00054 }
00055 
00056 
00057 bool InitMsgCollection::addIfUnique(I2OChain const& i2oChain, InitMsgSharedPtr& serializedProds)
00058 {
00059   boost::mutex::scoped_lock sl(listLock_);
00060 
00061   // check if the outputModuleId was already seen
00062   const uint32_t outputModuleId = i2oChain.outputModuleId();
00063   InitMsgMap::iterator pos = initMsgMap_.lower_bound(outputModuleId);
00064   if ( pos != initMsgMap_.end() && !(initMsgMap_.key_comp()(outputModuleId, pos->first)))
00065     return false; // init message already exists
00066   
00067   // build the init message view
00068   serializedProds.reset( new InitMsgBuffer(i2oChain.totalDataSize()) );
00069   i2oChain.copyFragmentsIntoBuffer( *serializedProds );
00070   InitMsgView initMsgView(&(*serializedProds)[0]);
00071   
00072   checkOutputModuleLabel(initMsgView);
00073   
00074   // add the message to the internal list
00075   initMsgMap_.insert(pos, InitMsgMap::value_type(outputModuleId,serializedProds));
00076 
00077   return true; // new init message
00078 }
00079 
00080 
00081 void InitMsgCollection::checkOutputModuleLabel(InitMsgView const& initMsgView) const
00082 {
00083   const std::string inputOMLabel = initMsgView.outputModuleLabel();
00084   const std::string trimmedOMLabel = boost::algorithm::trim_copy(inputOMLabel);
00085   if (trimmedOMLabel.empty()) {
00086     throw cms::Exception("InitMsgCollection", "addIfUnique:")
00087       << "Invalid INIT message: the HLT output module label is empty!"
00088         << std::endl;
00089   }
00090 }
00091 
00092 
00093 InitMsgSharedPtr
00094 InitMsgCollection::getElementForOutputModuleId(const uint32_t& requestedOutputModuleId) const
00095 {
00096   boost::mutex::scoped_lock sl(listLock_);
00097   InitMsgSharedPtr serializedProds;
00098   
00099   InitMsgMap::const_iterator it = initMsgMap_.find(requestedOutputModuleId);
00100   if (it != initMsgMap_.end())
00101     serializedProds = it->second;
00102 
00103   return serializedProds;
00104 }
00105 
00106 
00107 InitMsgSharedPtr
00108 InitMsgCollection::getElementForOutputModuleLabel(const std::string& requestedOutputModuleLabel) const
00109 {
00110   boost::mutex::scoped_lock sl(listLock_);
00111   InitMsgSharedPtr serializedProds;
00112 
00113   // handle the special case of an empty request
00114   // (If we want to use class methods to check the collection size and
00115   // fetch the last element in the collection, then we would need to 
00116   // switch to recursive mutexes...)
00117   if (requestedOutputModuleLabel.empty()) {
00118     if (initMsgMap_.size() == 1) {
00119       serializedProds = initMsgMap_.begin()->second;
00120     }
00121     else if (initMsgMap_.size() > 1) {
00122       std::string msg = "Invalid INIT message lookup: the requested ";
00123       msg.append("HLT output module label is empty but there are multiple ");
00124       msg.append("HLT output modules to choose from.");
00125       throw cms::Exception("InitMsgCollection", "getElementForOutputModule:")
00126         << msg << std::endl;
00127     }
00128   }
00129 
00130   else {
00131     // loop over the existing messages
00132     for (InitMsgMap::const_iterator msgIter = initMsgMap_.begin(),
00133            msgIterEnd = initMsgMap_.end();
00134          msgIter != msgIterEnd;
00135          msgIter++)
00136     {
00137       InitMsgSharedPtr workingMessage = msgIter->second;
00138       InitMsgView existingInitMsg(&(*workingMessage)[0]);
00139       std::string existingOMLabel = existingInitMsg.outputModuleLabel();
00140       
00141       // check if the output module labels match
00142       if (requestedOutputModuleLabel == existingOMLabel) {
00143         serializedProds = workingMessage;
00144         break;
00145       }
00146     }
00147   }
00148 
00149   return serializedProds;
00150 }
00151 
00152 
00153 InitMsgSharedPtr InitMsgCollection::getElementAt(const unsigned int index) const
00154 {
00155   boost::mutex::scoped_lock sl(listLock_);
00156 
00157   InitMsgSharedPtr ptrToElement;
00158   try
00159   {
00160     ptrToElement = initMsgMap_.at(index);
00161   }
00162   catch (std::out_of_range& e)
00163   { }
00164 
00165   return ptrToElement;
00166 }
00167 
00168 
00169 void InitMsgCollection::clear()
00170 {
00171   boost::mutex::scoped_lock sl(listLock_);
00172   initMsgMap_.clear();
00173 }
00174 
00175 
00176 size_t InitMsgCollection::size() const
00177 {
00178   boost::mutex::scoped_lock sl(listLock_);
00179   return initMsgMap_.size();
00180 }
00181 
00182 
00183 std::string InitMsgCollection::getSelectionHelpString() const
00184 {
00185   boost::mutex::scoped_lock sl(listLock_);
00186 
00187   // nothing much we can say if the collection is empty
00188   if (initMsgMap_.empty()) {
00189     return "No information is available about the available triggers.";
00190   }
00191 
00192   // list the full set of available triggers
00193   std::string helpString;
00194   helpString.append("The full list of trigger paths is the following:");
00195 
00196   // we can just use the list from the first entry since all
00197   // subsequent entries are forced to be the same
00198   InitMsgSharedPtr serializedProds = initMsgMap_.begin()->second;
00199   InitMsgView existingInitMsg(&(*serializedProds)[0]);
00200   Strings existingTriggerList;
00201   existingInitMsg.hltTriggerNames(existingTriggerList);
00202   for (unsigned int idx = 0; idx < existingTriggerList.size(); idx++) {
00203     helpString.append("\n    " + existingTriggerList[idx]);
00204   }
00205 
00206   // list the output modules (INIT messages)
00207   helpString.append("\nThe registered HLT output modules and their ");
00208   helpString.append("trigger selections are the following:");
00209 
00210   // loop over the existing messages
00211     for (InitMsgMap::const_iterator msgIter = initMsgMap_.begin(),
00212            msgIterEnd = initMsgMap_.end();
00213          msgIter != msgIterEnd;
00214          msgIter++)
00215     {
00216     serializedProds = msgIter->second;
00217     InitMsgView workingInitMsg(&(*serializedProds)[0]);
00218     helpString.append("\n  *** Output module \"");
00219     helpString.append(workingInitMsg.outputModuleLabel());
00220     helpString.append("\" ***");
00221     Strings workingSelectionList;
00222     workingInitMsg.hltTriggerSelections(workingSelectionList);
00223     for (unsigned int idx = 0; idx < workingSelectionList.size(); idx++) {
00224       helpString.append("\n    " + workingSelectionList[idx]);
00225     }
00226   }
00227 
00228   // return the result
00229   return helpString;
00230 }
00231 
00232 
00233 std::string InitMsgCollection::getOutputModuleName(const uint32_t outputModuleId) const
00234 {
00235   boost::mutex::scoped_lock sl(listLock_);
00236 
00237   InitMsgMap::const_iterator it = initMsgMap_.find(outputModuleId);
00238 
00239   if (it == initMsgMap_.end())
00240   {
00241     return "";
00242   }
00243   else {
00244     InitMsgSharedPtr serializedProds = it->second;
00245     const InitMsgView initMsgView(&(*serializedProds)[0]);
00246     return initMsgView.outputModuleLabel();
00247   }
00248 }
00249 
00250 
00251 std::string InitMsgCollection::stringsToText(Strings const& list,
00252                                              unsigned int maxCount)
00253 {
00254   std::string resultString = "";
00255   unsigned int elementCount = list.size();
00256   if (maxCount > 0 && maxCount < elementCount) {elementCount = maxCount;}
00257   for (unsigned int idx = 0; idx < elementCount; idx++)
00258   {
00259     resultString.append(list[idx]);
00260     if (idx < (elementCount-1)) {
00261       resultString.append(", ");
00262     }
00263   }
00264   if (elementCount < list.size())
00265   {
00266     resultString.append(", ...");
00267   }
00268   return resultString;
00269 }
00270 
00271