artdaq_core  3.10.01
Fragment.hh
1 #ifndef artdaq_core_Data_Fragment_hh
2 #define artdaq_core_Data_Fragment_hh
3 
4 #include <algorithm>
5 // #include <cassert>
6 #include <cmath>
7 #include <cstddef>
8 #include <cstdint>
9 #include <cstring>
10 #include <iosfwd>
11 #include <iterator>
12 #include <list>
13 #include <map>
14 #include <memory>
15 #include <vector>
16 
17 #include <iostream>
18 #include "artdaq-core/Core/QuickVec.hh"
19 #include "artdaq-core/Data/detail/RawFragmentHeader.hh"
20 #include "artdaq-core/Data/detail/RawFragmentHeaderV0.hh"
21 #include "artdaq-core/Data/detail/RawFragmentHeaderV1.hh"
22 #include "artdaq-core/Data/dictionarycontrol.hh"
23 #if HIDE_FROM_ROOT
24 #include "TRACE/trace.h" // TRACE
25 #endif
26 
30 namespace artdaq {
31 #define DATAVEC_T QuickVec<RawDataType>
32 // #define DATAVEC_T std::vector<RawDataType>
33 
41 
42 class Fragment;
46 typedef std::vector<Fragment> Fragments;
47 
54 typedef std::unique_ptr<Fragment> FragmentPtr;
55 
59 typedef std::list<FragmentPtr> FragmentPtrs;
60 
67 bool fragmentSequenceIDCompare(const Fragment& i, const Fragment& j);
68 
75 std::ostream& operator<<(std::ostream& os, Fragment const& f);
76 } // namespace artdaq
77 
86 {
87 public:
91  Fragment();
92 
100  typedef uint8_t byte_t;
101 
102  // Hide most things from ROOT.
103 #if HIDE_FROM_ROOT
104 
105  // http://stackoverflow.com/questions/33939687
106  // This should generate an exception if artdaq::Fragment is not move-constructible
111  Fragment(const Fragment&);
119  Fragment(Fragment&&) noexcept;
125  Fragment& operator=(const Fragment&);
134  Fragment& operator=(Fragment&&) noexcept;
135 
136  typedef detail::RawFragmentHeader::version_t version_t;
137  typedef detail::RawFragmentHeader::type_t type_t;
138  typedef detail::RawFragmentHeader::sequence_id_t sequence_id_t;
139  typedef detail::RawFragmentHeader::fragment_id_t fragment_id_t;
140  typedef detail::RawFragmentHeader::timestamp_t timestamp_t;
141 
142  static constexpr version_t InvalidVersion = detail::RawFragmentHeader::InvalidVersion;
143  static constexpr sequence_id_t InvalidSequenceID = detail::RawFragmentHeader::InvalidSequenceID;
144  static constexpr fragment_id_t InvalidFragmentID = detail::RawFragmentHeader::InvalidFragmentID;
145  static constexpr timestamp_t InvalidTimestamp = detail::RawFragmentHeader::InvalidTimestamp;
146 
147  static constexpr type_t InvalidFragmentType = detail::RawFragmentHeader::InvalidFragmentType;
148  static constexpr type_t EndOfDataFragmentType = detail::RawFragmentHeader::EndOfDataFragmentType;
149  static constexpr type_t DataFragmentType = detail::RawFragmentHeader::DataFragmentType;
150  static constexpr type_t InitFragmentType = detail::RawFragmentHeader::InitFragmentType;
151  static constexpr type_t EndOfRunFragmentType = detail::RawFragmentHeader::EndOfRunFragmentType;
152  static constexpr type_t EndOfSubrunFragmentType = detail::RawFragmentHeader::EndOfSubrunFragmentType;
153  static constexpr type_t ShutdownFragmentType = detail::RawFragmentHeader::ShutdownFragmentType;
154  static constexpr type_t FirstUserFragmentType = detail::RawFragmentHeader::FIRST_USER_TYPE;
155  static constexpr type_t EmptyFragmentType = detail::RawFragmentHeader::EmptyFragmentType;
156  static constexpr type_t ContainerFragmentType = detail::RawFragmentHeader::ContainerFragmentType;
157  static constexpr type_t ErrorFragmentType = detail::RawFragmentHeader::ErrorFragmentType;
158 
164  static constexpr bool isUserFragmentType(type_t fragmentType);
165 
171  static constexpr bool isSystemFragmentType(type_t fragmentType);
172 
177  static std::map<type_t, std::string> MakeSystemTypeMap()
178  {
180  }
181 
182  typedef DATAVEC_T::reference reference;
183  typedef DATAVEC_T::iterator iterator;
184  typedef DATAVEC_T::const_iterator const_iterator;
185  typedef DATAVEC_T::value_type value_type;
186  typedef DATAVEC_T::difference_type difference_type;
187  typedef DATAVEC_T::size_type size_type;
188 
194  explicit Fragment(std::size_t n);
195 
202  static FragmentPtr FragmentBytes(std::size_t nbytes)
203  {
204  RawDataType nwords = ceil(nbytes / static_cast<double>(sizeof(RawDataType)));
205  return std::make_unique<Fragment>(nwords);
206  }
207 
218  template<class T>
219  Fragment(std::size_t payload_size, sequence_id_t sequence_id,
220  fragment_id_t fragment_id, type_t type, const T& metadata,
222 
236  template<class T>
237  static FragmentPtr FragmentBytes(std::size_t payload_size_in_bytes,
238  sequence_id_t sequence_id,
239  fragment_id_t fragment_id,
240  type_t type, const T& metadata,
242  {
243  RawDataType nwords = ceil(payload_size_in_bytes /
244  static_cast<double>(sizeof(RawDataType)));
245  return std::make_unique<Fragment>(nwords, sequence_id, fragment_id, type, metadata, timestamp);
246  }
247 
256  fragment_id_t fragID,
259 
264  void print(std::ostream& os) const;
265 
270  std::size_t size() const;
271 
276  version_t version() const;
277 
282  type_t type() const;
283 
288  std::string typeString() const;
289 
294  sequence_id_t sequenceID() const;
295 
300  fragment_id_t fragmentID() const;
301 
306  timestamp_t timestamp() const;
307 
312  void setUserType(type_t utype);
313 
318  void setSystemType(type_t stype);
319 
324  void setSequenceID(sequence_id_t sequence_id);
325 
330  void setFragmentID(fragment_id_t fragment_id);
331 
337 
341  void touch();
342 
347  struct timespec atime() const;
348 
354  struct timespec getLatency(bool touch);
355 
360  std::size_t sizeBytes() const { return sizeof(RawDataType) * size(); }
361 
367  std::size_t dataSize() const;
368 
374  std::size_t dataSizeBytes() const
375  {
376  return sizeof(RawDataType) * dataSize();
377  }
378 
383  bool hasMetadata() const;
384 
392  template<class T>
393  T* metadata();
394 
402  template<class T>
403  T const* metadata() const;
404 
413  template<class T>
414  void setMetadata(const T& metadata);
415 
423  template<class T>
424  void updateMetadata(const T& metadata);
425 
430  void resize(std::size_t sz);
431 
437  void resize(std::size_t sz, RawDataType val);
438 
445  void resizeBytes(std::size_t szbytes);
446 
455  void resizeBytesWithCushion(std::size_t szbytes, double growthFactor = 1.3);
456 
464  void resizeBytes(std::size_t szbytes, byte_t val);
465 
469  void autoResize();
470 
476 
481  iterator dataEnd();
482 
502  template<typename T>
504  {
505  T newpointer = reinterpret_cast<T>(in); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
506 
507  if (static_cast<const void*>(newpointer) != static_cast<const void*>(in))
508  {
509  throw cet::exception("Error in Fragment.hh: reinterpret_cast failed to return expected address-- please contact John Freeman at jcfree@fnal.gov");
510  }
511 
512  return newpointer;
513  }
514 
530  template<typename T>
532  {
533  T newpointer = reinterpret_cast<T>(in); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
534 
535  if (static_cast<void*>(newpointer) != static_cast<void*>(in))
536  {
537  throw cet::exception("Error in Fragment.hh: reinterpret_cast failed to return expected address-- please contact John Freeman at jcfree@fnal.gov");
538  }
539 
540  return newpointer;
541  }
542 
551  byte_t* dataBeginBytes() { return reinterpret_cast_checked<byte_t*>(&*dataBegin()); }
552 
561  byte_t* dataEndBytes() { return reinterpret_cast_checked<byte_t*>(&*dataEnd()); }
562 
569 
574  byte_t* headerBeginBytes() { return reinterpret_cast_checked<byte_t*>(&*headerBegin()); }
575 
580  const_iterator dataBegin() const;
581 
586  const_iterator dataEnd() const;
587 
596  const byte_t* dataBeginBytes() const
597  {
598  return reinterpret_cast_checked<const byte_t*>(&*dataBegin());
599  }
600 
609  const byte_t* dataEndBytes() const
610  {
611  return reinterpret_cast_checked<const byte_t*>(&*dataEnd());
612  }
613 
619  const_iterator headerBegin() const; // See note for non-const, above.
620 
625  const byte_t* headerBeginBytes() const
626  {
627  return reinterpret_cast_checked<const byte_t*>(&*headerBegin());
628  }
629 
634  size_t headerSizeWords() const;
635 
640  size_t headerSizeBytes() const { return sizeof(RawDataType) * headerSizeWords(); }
641 
645  void clear();
646 
651  bool empty();
652 
657  void reserve(std::size_t cap);
658 
663  void swap(Fragment& other) noexcept;
664 
671  void swap(DATAVEC_T& other) noexcept { vals_.swap(other); };
672 
678 
691 
697  static FragmentPtr eodFrag(size_t nFragsToExpect);
698 
710  template<class InputIterator>
712  fragment_id_t fragID,
713  InputIterator i,
714  InputIterator e)
715  {
716  FragmentPtr result(new Fragment(sequenceID, fragID));
717  result->vals_.reserve(std::distance(i, e) + detail::RawFragmentHeader::num_words());
718  std::copy(i, e, std::back_inserter(result->vals_));
719  result->updateFragmentHeaderWC_();
720  return result;
721  }
722 
733  fragment_id_t fragID,
734  RawDataType const* dataPtr,
735  size_t dataSize,
737 
743 
744  ~Fragment()
745  {
746  if (upgraded_header_ != nullptr) delete upgraded_header_;
747  }
748 #endif
749 
750 private:
751  template<typename T>
752  static std::size_t validatedMetadataSize_();
753 
754  void updateFragmentHeaderWC_();
755 
756  DATAVEC_T vals_;
757 
758 #if HIDE_FROM_ROOT
759 
760  mutable detail::RawFragmentHeader* upgraded_header_{nullptr};
761 
762  detail::RawFragmentHeader* fragmentHeaderPtr() const;
763 
764 #endif
765 };
766 
767 #if HIDE_FROM_ROOT
768 
769 // http://stackoverflow.com/questions/33939687
770 // This should generate an exception if artdaq::Fragment is not move-constructible
771 inline artdaq::Fragment::Fragment(artdaq::Fragment&& of) noexcept : vals_(std::move(of.vals_)), upgraded_header_(of.upgraded_header_) {
772  of.upgraded_header_ = nullptr;
773 }
775 {
776  vals_ = std::move(of.vals_);
777  upgraded_header_ = of.upgraded_header_;
778  of.upgraded_header_ = nullptr;
779  return *this;
780 }
781 
782 
783 inline artdaq::Fragment::Fragment(const artdaq::Fragment& f) : vals_(f.vals_), upgraded_header_(nullptr) {}
785  vals_ = f.vals_;
786  upgraded_header_ = nullptr;
787  return *this;
788 }
789 
790 inline bool constexpr artdaq::Fragment::
792 {
793  return fragmentType >= detail::RawFragmentHeader::FIRST_USER_TYPE &&
795 }
796 
797 inline bool constexpr artdaq::Fragment::
799 {
800  return fragmentType >= detail::RawFragmentHeader::FIRST_SYSTEM_TYPE;
801 }
802 
803 template<typename T>
804 std::size_t
805 artdaq::Fragment::
806  validatedMetadataSize_()
807 {
808  // Make sure a size_t is big enough to hold the maximum metadata
809  // size. This *should* always be true, but it is a compile-time check
810  // and therefore cheap.
811  static_assert(sizeof(size_t) >=
812  sizeof(decltype(std::numeric_limits<detail::RawFragmentHeader::metadata_word_count_t>::max())),
813  "metadata_word_count_t is too big!");
814 
815  static size_t constexpr max_md_wc =
816  std::numeric_limits<detail::RawFragmentHeader::metadata_word_count_t>::max();
817  size_t requested_md_wc =
818  std::ceil(sizeof(T) / static_cast<double>(sizeof(artdaq::RawDataType)));
819  if (requested_md_wc > max_md_wc)
820  {
821  throw cet::exception("InvalidRequest") // NOLINT(cert-err60-cpp)
822  << "The requested metadata structure is too large: "
823  << "requested word count = " << requested_md_wc
824  << ", maximum word count = " << max_md_wc;
825  }
826  return requested_md_wc;
827 }
828 
829 template<class T>
831  Fragment(std::size_t payload_size, sequence_id_t sequence_id,
832  fragment_id_t fragment_id,
833  type_t type, const T& metadata, timestamp_t timestamp)
834  : vals_((artdaq::detail::RawFragmentHeader::num_words() + // Header
835  validatedMetadataSize_<T>() + // Metadata
836  payload_size) // User data
837  )
838 {
839  TRACEN("Fragment", 50, "Fragment ctor num_word()=%zu MetadataSize_=%zu payload_size=%zu", artdaq::detail::RawFragmentHeader::num_words(), validatedMetadataSize_<T>(), payload_size); // NOLINT
840  // vals ctor w/o init val is used; make sure header is ALL initialized.
841  for (iterator ii = vals_.begin();
842  ii != (vals_.begin() + detail::RawFragmentHeader::num_words()); ++ii)
843  {
844  *ii = -1;
845  }
846  fragmentHeaderPtr()->version = detail::RawFragmentHeader::CurrentVersion;
847  updateFragmentHeaderWC_();
848  fragmentHeaderPtr()->sequence_id = sequence_id;
849  fragmentHeaderPtr()->fragment_id = fragment_id;
850  fragmentHeaderPtr()->timestamp = timestamp;
851  fragmentHeaderPtr()->type = type;
852 
853  fragmentHeaderPtr()->touch();
854 
855  fragmentHeaderPtr()->metadata_word_count =
856  vals_.size() -
857  (headerSizeWords() + payload_size);
858 
859  memcpy(metadataAddress(), &metadata, sizeof(T));
860 }
861 
862 inline std::size_t
864 {
865  return fragmentHeader().word_count;
866 }
867 
870 {
871  auto hdr = reinterpret_cast_checked<detail::RawFragmentHeader const*>(&vals_[0]);
872  return hdr->version;
873 }
874 
877 {
878  return static_cast<type_t>(fragmentHeader().type);
879 }
880 
881 inline std::string
883 {
884  return std::to_string(type()) + (isSystemFragmentType(type()) ? " (" + detail::RawFragmentHeader::SystemTypeToString(type()) + ")" : "");
885 }
886 
889 {
890  return fragmentHeader().sequence_id;
891 }
892 
895 {
896  return fragmentHeader().fragment_id;
897 }
898 
901 {
902  return fragmentHeader().timestamp;
903 }
904 
905 inline void
907 {
908  fragmentHeaderPtr()->setUserType(static_cast<uint8_t>(type));
909 }
910 
911 inline void
913 {
914  fragmentHeaderPtr()->setSystemType(static_cast<uint8_t>(type));
915 }
916 
917 inline void
919 {
920  assert(sequence_id <= detail::RawFragmentHeader::InvalidSequenceID);
921  fragmentHeaderPtr()->sequence_id = sequence_id;
922 }
923 
924 inline void
926 {
927  fragmentHeaderPtr()->fragment_id = fragment_id;
928 }
929 
930 inline void
932 {
933  fragmentHeaderPtr()->timestamp = timestamp;
934 }
935 
937 {
938  fragmentHeaderPtr()->touch();
939 }
940 
941 inline struct timespec artdaq::Fragment::atime() const
942 {
943  return fragmentHeader().atime();
944 }
945 
946 inline struct timespec artdaq::Fragment::getLatency(bool touch)
947 {
948  return fragmentHeaderPtr()->getLatency(touch);
949 }
950 
951 inline void
952 artdaq::Fragment::updateFragmentHeaderWC_()
953 {
954  // Make sure vals_.size() fits inside 32 bits. Left-shift here should
955  // match bitfield size of word_count in RawFragmentHeader.
956  assert(vals_.size() < (1ULL << 32));
957  TRACEN("Fragment", 50, "Fragment::updateFragmentHeaderWC_ adjusting fragmentHeader()->word_count from %u to %zu", (unsigned)(fragmentHeaderPtr()->word_count), vals_.size()); // NOLINT
958  fragmentHeaderPtr()->word_count = vals_.size();
959 }
960 
961 inline std::size_t
963 {
964  return vals_.size() - headerSizeWords() -
965  fragmentHeader().metadata_word_count;
966 }
967 
968 inline bool
970 {
971  return fragmentHeader().metadata_word_count != 0;
972 }
973 
974 template<class T>
976 {
977  if (fragmentHeader().metadata_word_count == 0)
978  {
979  throw cet::exception("InvalidRequest") // NOLINT(cert-err60-cpp)
980  << "No metadata has been stored in this Fragment.";
981  }
982 
983  return reinterpret_cast_checked<T*>(&vals_[headerSizeWords()]);
984 }
985 
986 template<class T>
987 T const*
989 {
990  if (fragmentHeader().metadata_word_count == 0)
991  {
992  throw cet::exception("InvalidRequest") // NOLINT(cert-err60-cpp)
993  << "No metadata has been stored in this Fragment.";
994  }
995  return reinterpret_cast_checked<T const*>(&vals_[headerSizeWords()]);
996 }
997 
998 template<class T>
999 void artdaq::Fragment::setMetadata(const T& metadata)
1000 {
1001  if (fragmentHeader().metadata_word_count != 0)
1002  {
1003  throw cet::exception("InvalidRequest") // NOLINT(cert-err60-cpp)
1004  << "Metadata has already been stored in this Fragment.";
1005  }
1006  auto const mdSize = validatedMetadataSize_<T>();
1007  vals_.insert(dataBegin(), mdSize, 0);
1008  updateFragmentHeaderWC_();
1009  fragmentHeaderPtr()->metadata_word_count = mdSize;
1010 
1011  memcpy(metadataAddress(), &metadata, sizeof(T));
1012 }
1013 
1014 template<class T>
1015 void artdaq::Fragment::updateMetadata(const T& metadata)
1016 {
1017  if (fragmentHeader().metadata_word_count == 0)
1018  {
1019  throw cet::exception("InvalidRequest") // NOLINT(cert-err60-cpp)
1020  << "No metadata in fragment; please use Fragment::setMetadata instead of Fragment::updateMetadata";
1021  }
1022 
1023  auto const mdSize = validatedMetadataSize_<T>();
1024 
1025  if (fragmentHeader().metadata_word_count != mdSize)
1026  {
1027  throw cet::exception("InvalidRequest") // NOLINT(cert-err60-cpp)
1028  << "Mismatch between type of metadata struct passed to updateMetadata and existing metadata struct";
1029  }
1030 
1031  memcpy(metadataAddress(), &metadata, sizeof(T));
1032 }
1033 
1034 inline void
1036 {
1037  vals_.resize(sz + fragmentHeaderPtr()->metadata_word_count +
1038  headerSizeWords());
1039  updateFragmentHeaderWC_();
1040 }
1041 
1042 inline void
1044 {
1045  vals_.resize(sz + fragmentHeaderPtr()->metadata_word_count +
1046  headerSizeWords(),
1047  v);
1048  updateFragmentHeaderWC_();
1049 }
1050 
1051 inline void
1052 artdaq::Fragment::resizeBytes(std::size_t szbytes)
1053 {
1054  RawDataType nwords = ceil(szbytes / static_cast<double>(sizeof(RawDataType)));
1055  resize(nwords);
1056 }
1057 
1058 inline void
1059 artdaq::Fragment::resizeBytesWithCushion(std::size_t szbytes, double growthFactor)
1060 {
1061  RawDataType nwords = ceil(szbytes / static_cast<double>(sizeof(RawDataType)));
1062  vals_.resizeWithCushion(nwords + fragmentHeaderPtr()->metadata_word_count +
1063  headerSizeWords(),
1064  growthFactor);
1065  updateFragmentHeaderWC_();
1066 }
1067 
1068 inline void
1069 artdaq::Fragment::resizeBytes(std::size_t szbytes, byte_t v)
1070 {
1071  RawDataType defaultval;
1072  auto ptr = reinterpret_cast_checked<byte_t*>(&defaultval);
1073 
1074  for (uint8_t i = 0; i < sizeof(RawDataType); ++i)
1075  {
1076  *ptr = v;
1077  ptr++; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
1078  }
1079 
1080  RawDataType nwords = ceil(szbytes / static_cast<double>(sizeof(RawDataType)));
1081 
1082  resize(nwords, defaultval);
1083 }
1084 
1085 inline void
1087 {
1088  vals_.resize(fragmentHeaderPtr()->word_count);
1089  updateFragmentHeaderWC_();
1090 }
1091 
1094 {
1095  return vals_.begin() + headerSizeWords() +
1096  fragmentHeader().metadata_word_count;
1097 }
1098 
1101 {
1102  return vals_.end();
1103 }
1104 
1107 {
1108  return vals_.begin();
1109 }
1110 
1113 {
1114  return vals_.begin() + headerSizeWords() +
1115  fragmentHeader().metadata_word_count;
1116 }
1117 
1120 {
1121  return vals_.end();
1122 }
1123 
1126 {
1127  return vals_.begin();
1128 }
1129 
1130 inline void
1132 {
1133  vals_.erase(dataBegin(), dataEnd());
1134  updateFragmentHeaderWC_();
1135 }
1136 
1137 inline bool
1139 {
1140  return (vals_.size() - headerSizeWords() -
1141  fragmentHeader().metadata_word_count) == 0;
1142 }
1143 
1144 inline void
1146 {
1147  vals_.reserve(cap + headerSizeWords() +
1148  fragmentHeader().metadata_word_count);
1149 }
1150 
1151 inline void
1153 {
1154  vals_.swap(other.vals_);
1155 }
1156 
1157 inline artdaq::RawDataType*
1159 {
1160  return &vals_[0] + headerSizeWords() + // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
1161  fragmentHeader().metadata_word_count;
1162 }
1163 
1164 inline artdaq::RawDataType*
1166 {
1167  if (fragmentHeader().metadata_word_count == 0)
1168  {
1169  throw cet::exception("InvalidRequest") // NOLINT(cert-err60-cpp)
1170  << "No metadata has been stored in this Fragment.";
1171  }
1172  return &vals_[0] + headerSizeWords(); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
1173 }
1174 
1175 inline artdaq::RawDataType*
1177 {
1178  return &vals_[0];
1179 }
1180 
1181 inline size_t
1183 {
1184  auto hdr = reinterpret_cast_checked<detail::RawFragmentHeader const*>(&vals_[0]);
1185  if (hdr->version != detail::RawFragmentHeader::CurrentVersion)
1186  {
1187  switch (hdr->version)
1188  {
1189  case 0xFFFF:
1190  TLOG(51, "Fragment") << "Cannot get header size of InvalidVersion Fragment";
1191  break;
1192  case 0: {
1193  TLOG(52, "Fragment") << "Getting size of RawFragmentHeaderV0";
1195  break;
1196  }
1197  case 1: {
1198  TLOG(52, "Fragment") << "Getting size of RawFragmentHeaderV1";
1200  break;
1201  }
1202  default:
1203  throw cet::exception("Fragment") << "A Fragment with an unknown version (" << std::to_string(hdr->version) << ") was received!"; // NOLINT(cert-err60-cpp)
1204  break;
1205  }
1206  }
1207  return hdr->num_words();
1208 }
1209 
1211 artdaq::Fragment::fragmentHeaderPtr() const
1212 {
1213  if (upgraded_header_ != nullptr) return upgraded_header_;
1214  auto hdr = reinterpret_cast_checked<detail::RawFragmentHeader const*>(&vals_[0]);
1215  if (hdr->version != detail::RawFragmentHeader::CurrentVersion)
1216  {
1217  switch (hdr->version)
1218  {
1219  case 0xFFFF:
1220  TLOG(51, "Fragment") << "Not upgrading InvalidVersion Fragment";
1221  break;
1222  case 0: {
1223  TLOG(52, "Fragment") << "Upgrading RawFragmentHeaderV0 (non const)";
1224  auto old_hdr = reinterpret_cast_checked<detail::RawFragmentHeaderV0 const*>(&vals_[0]);
1225  upgraded_header_ = new detail::RawFragmentHeader(old_hdr->upgrade());
1226  return upgraded_header_;
1227  break;
1228  }
1229  case 1: {
1230  TLOG(52, "Fragment") << "Upgrading RawFragmentHeaderV1 (non const)";
1231  auto old_hdr = reinterpret_cast_checked<detail::RawFragmentHeaderV1 const*>(&vals_[0]);
1232  upgraded_header_ = new detail::RawFragmentHeader(old_hdr->upgrade());
1233  return upgraded_header_;
1234  break;
1235  }
1236  default:
1237  throw cet::exception("Fragment") << "A Fragment with an unknown version (" << std::to_string(hdr->version) << ") was received!"; // NOLINT(cert-err60-cpp)
1238  break;
1239  }
1240  }
1241  return const_cast<detail::RawFragmentHeader*>(hdr);
1242 }
1243 
1246 {
1247  return *fragmentHeaderPtr();
1248 }
1249 
1250 inline void
1251 swap(artdaq::Fragment& x, artdaq::Fragment& y) noexcept
1252 {
1253  x.swap(y);
1254 }
1255 
1256 inline std::ostream&
1257 artdaq::operator<<(std::ostream& os, artdaq::Fragment const& f)
1258 {
1259  f.print(os);
1260  return os;
1261 }
1262 #endif /* HIDE_FROM_ROOT */
1263 
1264 #endif /* artdaq_core_Data_Fragment_hh */
std::unique_ptr< Fragment > FragmentPtr
A std::unique_ptr to a Fragment object.
Definition: Fragment.hh:54
void reserve(std::size_t cap)
Reserves enough memory to hold cap RawDataType words in the Fragment payload.
Definition: Fragment.hh:1145
detail::RawFragmentHeader::timestamp_t timestamp_t
typedef for timestamp_t from RawFragmentHeader
Definition: Fragment.hh:140
RawDataType metadata_word_count
The number of RawDataType words in the user-defined metadata.
static const sequence_id_t InvalidSequenceID
The sequence_id field is currently 48-bits.
static constexpr type_t FIRST_SYSTEM_TYPE
The first system type.
std::size_t dataSizeBytes() const
Return the number of bytes in the data payload. This does not include the number of bytes in the head...
Definition: Fragment.hh:374
RawDataType type
The type of the fragment, either system or user-defined.
static constexpr type_t InvalidFragmentType
Copy InvalidFragmentType from RawFragmentHeader.
Definition: Fragment.hh:147
T reinterpret_cast_checked(const RawDataType *in) const
Wrapper around reinterpret_cast.
Definition: Fragment.hh:503
QuickVec< RawDataType >::difference_type difference_type
Alias difference_type type from QuickVec&lt;RawDataType&gt;
Definition: Fragment.hh:186
void setSequenceID(sequence_id_t sequence_id)
Sets the Sequence ID of the Fragment.
Definition: Fragment.hh:918
void setSystemType(type_t stype)
Sets the type of the Fragment, checking that it is a valid system type.
Definition: Fragment.hh:912
static std::map< type_t, std::string > MakeSystemTypeMap()
Returns a map of the most-commonly used system types.
std::vector< Fragment > Fragments
A std::vector of Fragment objects.
Definition: Fragment.hh:42
std::size_t size() const
Gets the size of the Fragment, from the Fragment header.
Definition: Fragment.hh:863
static constexpr std::size_t num_words()
Returns the number of RawDataType words present in the header.
static constexpr type_t EndOfDataFragmentType
Copy EndOfDataFragmentType from RawFragmentHeader.
Definition: Fragment.hh:148
static constexpr timestamp_t InvalidTimestamp
Copy InvalidTimestamp from RawFragmentHeader.
Definition: Fragment.hh:145
static constexpr type_t EmptyFragmentType
Copy EmptyFragmentType from RawFragmentHeader.
Definition: Fragment.hh:155
const byte_t * dataEndBytes() const
Return const Fragment::byte_t* pointing at the end of the payload.
Definition: Fragment.hh:609
struct timespec atime() const
Get the last access time of the Fragment.
Definition: Fragment.hh:941
static constexpr bool isUserFragmentType(type_t fragmentType)
Returns whether the given type is in the range of user types.
Definition: Fragment.hh:791
detail::RawFragmentHeader::fragment_id_t fragment_id_t
typedef for fragment_id_t from RawFragmentHeader
Definition: Fragment.hh:139
std::size_t sizeBytes() const
Size of vals_ vector ( header + (optional) metadata + payload) in bytes.
Definition: Fragment.hh:360
byte_t * dataBeginBytes()
Return Fragment::byte_t* pointing at the beginning of the payload.
Definition: Fragment.hh:551
static constexpr std::size_t num_words()
Returns the number of RawDataType words present in the header.
The RawFragmentHeader class contains the basic fields used by artdaq for routing Fragment objects thr...
detail::RawFragmentHeader::type_t type_t
typedef for type_t from RawFragmentHeader
Definition: Fragment.hh:137
void resizeBytes(std::size_t szbytes)
Resize the data payload to hold szbytes bytes (padded by the 8-byte RawDataTypes, so...
Definition: Fragment.hh:1052
static FragmentPtr dataFrag(sequence_id_t sequenceID, fragment_id_t fragID, InputIterator i, InputIterator e)
Creates a Fragment, copying data from given location. 12-Apr-2013, KAB - this method is deprecated...
Definition: Fragment.hh:711
RawDataType timestamp
The 64-bit timestamp field is the output of a user-defined clock used for building time-correlated ev...
RawDataType sequence_id
The 48-bit sequence_id uniquely identifies events within the artdaq system.
sequence_id_t sequenceID() const
Sequence ID of the Fragment, from the Fragment header.
Definition: Fragment.hh:888
timestamp_t timestamp() const
Timestamp of the Fragment, from the Fragment header.
Definition: Fragment.hh:900
static constexpr type_t DataFragmentType
Copy DataFragmentType from RawFragmentHeader.
Definition: Fragment.hh:149
QuickVec< RawDataType >::const_iterator const_iterator
Alias const_iterator type from QuickVec&lt;RawDataType&gt;
Definition: Fragment.hh:184
uint8_t byte_t
For byte representation.
Definition: Fragment.hh:100
void resize(std::size_t sz)
Resize the data payload to hold sz RawDataType words.
Definition: Fragment.hh:1035
RawDataType version
The version of the fragment.
void autoResize()
Resize the fragment to hold the number of words indicated by the header.
Definition: Fragment.hh:1086
static constexpr type_t EndOfRunFragmentType
Copy EndOfRunFragmentType from RawFragmentHeader.
Definition: Fragment.hh:151
static constexpr fragment_id_t InvalidFragmentID
Copy InvalidFragmentID from RawFragmentHeader.
Definition: Fragment.hh:144
static constexpr type_t LAST_USER_TYPE
The last user-accessible type (types above this number are system types.
static constexpr std::size_t num_words()
Returns the number of RawDataType words present in the header.
RawDataType fragment_id
The fragment_id uniquely identifies a particular piece of hardware within the artdaq system...
size_t size() const
Accesses the current size of the QuickVec.
Definition: QuickVec.hh:392
static constexpr type_t InitFragmentType
Copy InitFragmentType from RawFragmentHeader.
Definition: Fragment.hh:150
QuickVec< RawDataType >::reference reference
Alias reference type from QuickVec&lt;RawDataType&gt;
Definition: Fragment.hh:182
byte_t * headerBeginBytes()
Return a Fragment::byte_t pointer pointing to the beginning of the header.
Definition: Fragment.hh:574
void setMetadata(const T &metadata)
Set the metadata in the Fragment to the contents of the specified structure. This throws an exception...
Definition: Fragment.hh:999
static FragmentPtr FragmentBytes(std::size_t payload_size_in_bytes, sequence_id_t sequence_id, fragment_id_t fragment_id, type_t type, const T &metadata, timestamp_t timestamp=Fragment::InvalidTimestamp)
Create a Fragment with the given header values. Uses static factory function instead of constructor t...
Definition: Fragment.hh:237
static constexpr type_t ErrorFragmentType
Copy ErrorFragmentType from RawFragmentHeader.
Definition: Fragment.hh:157
void touch()
Update the atime fields of the RawFragmentHeader to current time.
struct timespec getLatency(bool touch)
Get the difference between the current time and the last access time of the Fragment.
Definition: Fragment.hh:946
detail::RawFragmentHeader::version_t version_t
typedef for version_t from RawFragmentHeader
Definition: Fragment.hh:136
void setTimestamp(timestamp_t timestamp)
Sets the Timestamp of the Fragment.
Definition: Fragment.hh:931
iterator headerBegin()
Return an iterator to the beginning of the header (should be used for serialization only: use setters...
Definition: Fragment.hh:1106
T reinterpret_cast_checked(RawDataType *in)
Wrapper around reinterpret_cast.
Definition: Fragment.hh:531
byte_t * dataEndBytes()
Return Fragment::byte_t* pointing at the end of the payload.
Definition: Fragment.hh:561
static constexpr version_t InvalidVersion
Copy InvalidVersion from RawFragmentHeader.
Definition: Fragment.hh:142
iterator dataBegin()
Return an iterator to the beginning of the data payload (after header and metadata) ...
Definition: Fragment.hh:1093
bool empty()
Determines if the Fragment contains no data.
Definition: Fragment.hh:1138
static constexpr sequence_id_t InvalidSequenceID
Copy InvalidSequenceID from RawFragmentHeader.
Definition: Fragment.hh:143
QuickVec< RawDataType >::value_type value_type
Alias value_type type from QuickVec&lt;RawDataType&gt;
Definition: Fragment.hh:185
static FragmentPtr eodFrag(size_t nFragsToExpect)
Creates an EndOfData Fragment.
Definition: Fragment.cc:77
void setUserType(type_t utype)
Sets the type of the Fragment, checking that it is a valid user type.
Definition: Fragment.hh:906
void touch()
Update the access time of the Fragment.
Definition: Fragment.hh:936
static constexpr type_t ContainerFragmentType
Copy ContainerFragmentType from RawFragmentHeader.
Definition: Fragment.hh:156
static std::map< type_t, std::string > MakeSystemTypeMap()
Returns a map of the most commonly-used system types.
Definition: Fragment.hh:177
void updateMetadata(const T &metadata)
Updates existing metadata with a new metadata object.
Definition: Fragment.hh:1015
std::ostream & operator<<(std::ostream &os, Fragment const &f)
Prints the given Fragment to the stream.
Definition: Fragment.hh:1257
void swap(QuickVec &other) noexcept
Exchanges references to two QuickVec objects.
Definition: QuickVec.hh:541
const byte_t * dataBeginBytes() const
Return const Fragment::byte_t* pointing at the beginning of the payload.
Definition: Fragment.hh:596
static constexpr type_t FIRST_USER_TYPE
The first user-accessible type.
type_t type() const
Type of the Fragment, from the Fragment header.
Definition: Fragment.hh:876
RawDataType * dataAddress()
Returns a RawDataType pointer to the beginning of the payload.
Definition: Fragment.hh:1158
void print(std::ostream &os) const
Print out summary information for this Fragment to the given stream.
Definition: Fragment.cc:68
unsigned long long RawDataType
The RawDataType (currently an unsigned long long) is the basic unit of data representation within art...
T * metadata()
Return a pointer to the metadata. This throws an exception if the Fragment contains no metadata...
Definition: Fragment.hh:975
iterator dataEnd()
Return an iterator to the end of the data payload.
Definition: Fragment.hh:1100
static FragmentPtr FragmentBytes(std::size_t nbytes)
Create a Fragment using a static factory function rather than a constructor to allow for the function...
Definition: Fragment.hh:202
static constexpr type_t ShutdownFragmentType
Copy ShutdownFragmentType from RawFragmentHeader.
Definition: Fragment.hh:153
static constexpr type_t FirstUserFragmentType
Copy FIRST_USER_TYPE from RawFragmentHeader.
Definition: Fragment.hh:154
std::string typeString() const
Print the type of the Fragment.
Definition: Fragment.hh:882
detail::RawFragmentHeader::RawDataType RawDataType
The RawDataType (currently a 64-bit integer) is the basic unit of data representation within artdaq ...
Definition: Fragment.hh:40
RawDataType * metadataAddress()
Get the address of the metadata. For internal use only, use metadata() instead.
Definition: Fragment.hh:1165
size_t headerSizeBytes() const
Get the size of this Fragment&#39;s header, in bytes.
Definition: Fragment.hh:640
std::list< FragmentPtr > FragmentPtrs
A std::list of FragmentPtrs.
Definition: Fragment.hh:59
Fragment()
Create a Fragment with all header values zeroed.
Definition: Fragment.cc:13
size_t headerSizeWords() const
Get the size of this Fragment&#39;s header, in RawDataType words.
Definition: Fragment.hh:1182
void clear()
Removes all elements from the payload section of the Fragment.
Definition: Fragment.hh:1131
static constexpr bool isSystemFragmentType(type_t fragmentType)
Returns whether the given type is in the range of system types.
Definition: Fragment.hh:798
static const version_t CurrentVersion
The CurrentVersion field should be incremented whenever the RawFragmentHeader changes.
QuickVec< RawDataType >::iterator iterator
Alias iterator type from QuickVec&lt;RawDataType&gt;
Definition: Fragment.hh:183
bool hasMetadata() const
Test whether this Fragment has metadata.
Definition: Fragment.hh:969
QuickVec< RawDataType >::size_type size_type
Alias size_type type from QuickVec&lt;RawDataType&gt;
Definition: Fragment.hh:187
const byte_t * headerBeginBytes() const
Return a const Fragment::byte_t pointer pointing to the beginning of the header.
Definition: Fragment.hh:625
static std::string SystemTypeToString(type_t type)
Print a system type&#39;s string name.
void setFragmentID(fragment_id_t fragment_id)
Sets the Fragment ID of the Fragment.
Definition: Fragment.hh:925
Fragment & operator=(const Fragment &)
Default copy-assignment operator.
Definition: Fragment.hh:784
A Fragment contains the data from one piece of the DAQ system for one event The artdaq::Fragment is t...
Definition: Fragment.hh:85
void swap(Fragment &other) noexcept
Swaps two Fragment objects.
Definition: Fragment.hh:1152
static constexpr type_t EndOfSubrunFragmentType
Copy EndOfSubrunFragmentType from RawFragmentHeader.
Definition: Fragment.hh:152
bool fragmentSequenceIDCompare(const Fragment &i, const Fragment &j)
Comparator for Fragment objects, based on their sequence_id.
Definition: Fragment.cc:8
detail::RawFragmentHeader const fragmentHeader() const
Get a copy of the RawFragmentHeader from this Fragment.
Definition: Fragment.hh:1245
void resizeBytesWithCushion(std::size_t szbytes, double growthFactor=1.3)
Resize the data payload to hold szbytes bytes (padded by the 8-byte RawDataTypes, so...
Definition: Fragment.hh:1059
std::size_t dataSize() const
Return the number of RawDataType words in the data payload. This does not include the number of words...
Definition: Fragment.hh:962
iterator begin()
Gets an iterator to the beginning of the QuickVec.
Definition: QuickVec.hh:398
void swap(QuickVec< RawDataType > &other) noexcept
Swaps two Fragment data vectors.
Definition: Fragment.hh:671
detail::RawFragmentHeader::sequence_id_t sequence_id_t
typedef for sequence_id_t from RawFragmentHeader
Definition: Fragment.hh:138
fragment_id_t fragmentID() const
Fragment ID of the Fragment, from the Fragment header.
Definition: Fragment.hh:894
RawDataType * headerAddress()
Gets the address of the header.
Definition: Fragment.hh:1176
version_t version() const
Version of the Fragment, from the Fragment header.
Definition: Fragment.hh:869