00001 // $Id: FragmentStore.cc,v 1.10 2011/03/30 15:16:48 mommsen Exp $ 00003 00004 #include "EventFilter/StorageManager/interface/FragmentStore.h" 00005 #include "EventFilter/StorageManager/interface/Utils.h" 00006 00007 using namespace stor; 00008 00009 00010 FragmentStore::FragmentStore(size_t maxMemoryUsageMB) 00011 : maxMemoryUsage_(maxMemoryUsageMB*1024*1024) 00012 { 00013 clear(); 00014 } 00015 00016 const bool FragmentStore::addFragment(I2OChain &chain) 00017 { 00018 // the trivial case that the chain is already complete 00019 if ( chain.complete() ) return true; 00020 00021 memoryUsed_ += chain.memoryUsed(); 00022 const FragKey newKey = chain.fragmentKey(); 00023 00024 // Use efficientAddOrUpdates pattern suggested by Item 24 of 00025 // 'Effective STL' by Scott Meyers 00026 fragmentMap::iterator pos = store_.lower_bound(newKey); 00027 00028 if(pos != store_.end() && !(store_.key_comp()(newKey, pos->first))) 00029 { 00030 // key already exists 00031 pos->second.addToChain(chain); 00032 00033 if ( pos->second.complete() ) 00034 { 00035 chain = pos->second; 00036 store_.erase(pos); 00037 memoryUsed_ -= chain.memoryUsed(); 00038 return true; 00039 } 00040 } 00041 else 00042 { 00043 chain.resetStaleWindowStartTime(); 00044 00045 // The key does not exist in the map, add it to the map 00046 // Use pos as a hint to insert, so it can avoid another lookup 00047 store_.insert(pos, fragmentMap::value_type(newKey, chain)); 00048 chain.release(); 00049 00050 // We already handled the trivial case that the chain is complete. 00051 // Thus, store_ will not have a complete event. 00052 } 00053 00054 return false; 00055 } 00056 00057 void FragmentStore::addToStaleEventTimes(const utils::Duration_t duration) 00058 { 00059 for ( 00060 fragmentMap::iterator it = store_.begin(), itEnd = store_.end(); 00061 it != itEnd; 00062 ++it 00063 ) 00064 { 00065 it->second.addToStaleWindowStartTime(duration); 00066 } 00067 } 00068 00069 void FragmentStore::resetStaleEventTimes() 00070 { 00071 for ( 00072 fragmentMap::iterator it = store_.begin(), itEnd = store_.end(); 00073 it != itEnd; 00074 ++it 00075 ) 00076 { 00077 it->second.resetStaleWindowStartTime(); 00078 } 00079 } 00080 00081 const bool FragmentStore::getStaleEvent(I2OChain &chain, utils::Duration_t timeout) 00082 { 00083 const utils::TimePoint_t cutOffTime = utils::getCurrentTime() - timeout; 00084 00085 fragmentMap::iterator pos = store_.begin(); 00086 fragmentMap::iterator end = store_.end(); 00087 00088 while ( (pos != end) && (pos->second.staleWindowStartTime() > cutOffTime ) ) 00089 { 00090 ++pos; 00091 } 00092 00093 if ( pos == end ) 00094 { 00095 chain.release(); 00096 return false; 00097 } 00098 else 00099 { 00100 chain = pos->second; 00101 store_.erase(pos); 00102 memoryUsed_ -= chain.memoryUsed(); 00103 chain.markFaulty(); 00104 return true; 00105 } 00106 } 00107 00108 00109