$treeview $search $mathjax $extrastylesheet
artdaq_core
v3_04_20a
$projectbrief
|
$projectbrief
|
$searchbox |
00001 #ifndef artdaq_core_Data_ContainerFragmentLoader_hh 00002 #define artdaq_core_Data_ContainerFragmentLoader_hh 00003 00005 // ContainerFragmentLoader 00006 // 00007 // This class gives write access to a ContainerFragment. It should be 00008 // used when multiple fragments are generated by one BoardReader for a 00009 // single event. 00010 // 00012 00013 #include "artdaq-core/Data/Fragment.hh" 00014 #include "artdaq-core/Data/ContainerFragment.hh" 00015 00016 #include "tracemf.h" 00017 00018 #include <iostream> 00019 00020 00021 namespace artdaq 00022 { 00023 class ContainerFragmentLoader; 00024 } 00025 00026 00030 class artdaq::ContainerFragmentLoader : public artdaq::ContainerFragment 00031 { 00032 public: 00033 00034 00041 explicit ContainerFragmentLoader(Fragment& f, Fragment::type_t expectedFragmentType); 00042 00043 // ReSharper disable once CppMemberFunctionMayBeConst 00048 Metadata* metadata() 00049 { 00050 assert(artdaq_Fragment_.hasMetadata()); 00051 return reinterpret_cast<Metadata *>(&*artdaq_Fragment_.metadataAddress()); 00052 } 00053 00058 void set_fragment_type(Fragment::type_t type) 00059 { 00060 metadata()->fragment_type = type; 00061 } 00062 00071 void set_missing_data(bool isDataMissing) 00072 { 00073 metadata()->missing_data = isDataMissing; 00074 } 00075 00081 void addFragment(artdaq::Fragment& frag); 00082 00087 void addFragment(artdaq::FragmentPtr& frag); 00088 00093 void addFragments(artdaq::FragmentPtrs& frags); 00094 00095 private: 00096 // Note that this non-const reference hides the const reference in the base class 00097 artdaq::Fragment& artdaq_Fragment_; 00098 00099 static size_t words_to_frag_words_(size_t nWords); 00100 00101 void addSpace_(size_t bytes); 00102 00103 uint8_t* dataBegin_() { return reinterpret_cast<uint8_t*>(&*artdaq_Fragment_.dataBegin()); } 00104 void* dataEnd_() { return reinterpret_cast<void*>(dataBegin_() + lastFragmentIndex()); } 00105 }; 00106 00107 inline artdaq::ContainerFragmentLoader::ContainerFragmentLoader(artdaq::Fragment& f, artdaq::Fragment::type_t expectedFragmentType = Fragment::EmptyFragmentType) : 00108 ContainerFragment(f) 00109 , artdaq_Fragment_(f) 00110 { 00111 artdaq_Fragment_.setSystemType(Fragment::ContainerFragmentType); 00112 Metadata m; 00113 m.block_count = 0; 00114 m.fragment_type = expectedFragmentType; 00115 m.missing_data = false; 00116 m.has_index = true; 00117 m.version = ContainerFragment::CURRENT_VERSION; 00118 m.index_offset = 0; 00119 artdaq_Fragment_.setMetadata<Metadata>(m); 00120 00121 if (artdaq_Fragment_.size() != 00122 artdaq::detail::RawFragmentHeader::num_words() + 00123 words_to_frag_words_(Metadata::size_words)) 00124 { 00125 TLOG(TLVL_ERROR,"ContainerFragmentLoader") << "ContainerFragmentLoader: Raw artdaq::Fragment object size suggests it does not consist of its own header + the ContainerFragment::Metadata object" ; 00126 TLOG(TLVL_ERROR,"ContainerFragmentLoader") << "artdaq_Fragment size: " << artdaq_Fragment_.size() << ", Expected size: " << artdaq::detail::RawFragmentHeader::num_words() + words_to_frag_words_(Metadata::size_words) ; 00127 00128 throw cet::exception("InvalidFragment") << "ContainerFragmentLoader: Raw artdaq::Fragment object size suggests it does not consist of its own header + the ContainerFragment::Metadata object"; 00129 } 00130 00131 artdaq_Fragment_.resize(1); 00132 *artdaq_Fragment_.dataBegin() = CONTAINER_MAGIC; 00133 } 00134 00135 inline size_t artdaq::ContainerFragmentLoader::words_to_frag_words_(size_t nWords) 00136 { 00137 size_t mod = nWords % words_per_frag_word_(); 00138 return mod ? 00139 nWords / words_per_frag_word_() + 1 : 00140 nWords / words_per_frag_word_(); 00141 } 00142 00143 inline void artdaq::ContainerFragmentLoader::addSpace_(size_t bytes) 00144 { 00145 auto currSize = sizeof(artdaq::Fragment::value_type) * artdaq_Fragment_.dataSize(); // Resize takes into account header and metadata size 00146 artdaq_Fragment_.resizeBytesWithCushion(bytes + currSize, 1.3); 00147 reset_index_ptr_(); // Must reset index_ptr after resize operation! 00148 TLOG(TLVL_TRACE,"ContainerFragmentLoader") << "addSpace_: dataEnd_ is now at " << (void*)dataEnd_() << " (oldSizeBytes/deltaBytes: " << currSize << "/" << bytes << ")"; 00149 } 00150 00151 inline void artdaq::ContainerFragmentLoader::addFragment(artdaq::Fragment& frag) 00152 { 00153 TLOG(TLVL_TRACE,"ContainerFragmentLoader") << "addFragment: Adding Fragment with payload size " << frag.dataSizeBytes() << " to Container"; 00154 if (metadata()->fragment_type == Fragment::EmptyFragmentType) metadata()->fragment_type = frag.type(); 00155 else if (frag.type() != metadata()->fragment_type) 00156 { 00157 TLOG(TLVL_ERROR,"ContainerFragmentLoader") << "addFragment: Trying to add a fragment of different type than what's already been added!" ; 00158 throw cet::exception("WrongFragmentType") << "ContainerFragmentLoader::addFragment: Trying to add a fragment of different type than what's already been added!"; 00159 } 00160 00161 TLOG(TLVL_TRACE,"ContainerFragmentLoader") << "addFragment: Payload Size is " << artdaq_Fragment_.dataSizeBytes() << ", lastFragmentIndex is " << lastFragmentIndex() << ", and frag.size is " << frag.sizeBytes(); 00162 if (artdaq_Fragment_.dataSizeBytes() < (lastFragmentIndex() + frag.sizeBytes() + sizeof(size_t) * (metadata()->block_count + 2))) 00163 { 00164 addSpace_((lastFragmentIndex() + frag.sizeBytes() + sizeof(size_t) * (metadata()->block_count + 2)) - artdaq_Fragment_.dataSizeBytes()); 00165 } 00166 frag.setSequenceID(artdaq_Fragment_.sequenceID()); 00167 TLOG(TLVL_TRACE,"ContainerFragmentLoader") << "addFragment, copying " << frag.sizeBytes() << " bytes from " << (void*)frag.headerAddress() << " to " << (void*)dataEnd_(); 00168 memcpy(dataEnd_(), frag.headerAddress(), frag.sizeBytes()); 00169 metadata()->has_index = 0; 00170 00171 metadata()->block_count++; 00172 00173 auto index = create_index_(); 00174 metadata()->index_offset = index[metadata()->block_count - 1]; 00175 memcpy(dataBegin_() + metadata()->index_offset, index, sizeof(size_t) * (metadata()->block_count + 1)); 00176 delete[] index; 00177 metadata()->has_index = 1; 00178 reset_index_ptr_(); 00179 } 00180 00181 inline void artdaq::ContainerFragmentLoader::addFragment(artdaq::FragmentPtr& frag) 00182 { 00183 addFragment(*frag); 00184 } 00185 00186 inline void artdaq::ContainerFragmentLoader::addFragments(artdaq::FragmentPtrs& frags) 00187 { 00188 for (auto& frag : frags) 00189 { 00190 addFragment((*frag)); 00191 } 00192 } 00193 00194 #endif /* artdaq_core_Data_ContainerFragmentLoader_hh */