artdaq_core  v3_05_00
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 <cstddef>
7 #include <iosfwd>
8 #include <iterator>
9 #include <vector>
10 #include <list>
11 #include <memory>
12 #include <map>
13 #include <cmath>
14 #include <stdint.h>
15 #include <string.h>
16 
17 #include "artdaq-core/Data/detail/RawFragmentHeader.hh"
18 #include "artdaq-core/Data/detail/RawFragmentHeaderV0.hh"
19 #include "artdaq-core/Data/detail/RawFragmentHeaderV1.hh"
20 #include "artdaq-core/Data/dictionarycontrol.hh"
21 #include "artdaq-core/Core/QuickVec.hh"
22 #include <iostream>
23 #if HIDE_FROM_ROOT
24 #include "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 
68 
75  std::ostream& operator<<(std::ostream& os, Fragment const& f);
76 }
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&) = default;
119  Fragment(Fragment&&) noexcept;
125  Fragment& operator=(const Fragment&) = default;
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 FragmentPtr(new 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 FragmentPtr(new 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();
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 
369 
375  std::size_t dataSizeBytes() const
376  {
377  return sizeof(RawDataType) * dataSize();
378  }
379 
384  bool hasMetadata() const;
385 
393  template <class T>
394  T* metadata();
395 
403  template <class T>
404  T const* metadata() const;
405 
414  template <class T>
415  void setMetadata(const T& md);
416 
424  template <class T>
425  void updateMetadata(const T& md);
426 
431  void resize(std::size_t sz);
432 
438  void resize(std::size_t sz, RawDataType val);
439 
446  void resizeBytes(std::size_t szbytes);
447 
456  void resizeBytesWithCushion(std::size_t szbytes, double growthFactor=1.3);
457 
465  void resizeBytes(std::size_t szbytes, byte_t val);
466 
470  void autoResize();
471 
477 
482  iterator dataEnd();
483 
503  template <typename T>
505  {
506  T newpointer = reinterpret_cast<T>(in);
507 
508  if (static_cast<const void*>(newpointer) != static_cast<const void*>(in))
509  {
510  throw cet::exception("Error in Fragment.hh: reinterpret_cast failed to return expected address-- please contact John Freeman at jcfree@fnal.gov");
511  }
512 
513  return newpointer;
514  }
515 
531  template <typename T>
533  {
534  T newpointer = reinterpret_cast<T>(in);
535 
536  if (static_cast<void*>(newpointer) != static_cast<void*>(in))
537  {
538  throw cet::exception("Error in Fragment.hh: reinterpret_cast failed to return expected address-- please contact John Freeman at jcfree@fnal.gov");
539  }
540 
541  return newpointer;
542  }
543 
552  byte_t* dataBeginBytes() { return reinterpret_cast_checked<byte_t*>(&* dataBegin()); }
553 
562  byte_t* dataEndBytes() { return reinterpret_cast_checked<byte_t*>(&* dataEnd()); }
563 
570 
575  byte_t* headerBeginBytes() { return reinterpret_cast_checked<byte_t*>(&* headerBegin()); }
576 
581  const_iterator dataBegin() const;
582 
587  const_iterator dataEnd() const;
588 
597  const byte_t* dataBeginBytes() const
598  {
599  return reinterpret_cast_checked<const byte_t*>(&* dataBegin());
600  }
601 
610  const byte_t* dataEndBytes() const
611  {
612  return reinterpret_cast_checked<const byte_t*>(&* dataEnd());
613  }
614 
620  const_iterator headerBegin() const; // See note for non-const, above.
621 
626  const byte_t* headerBeginBytes() const
627  {
628  return reinterpret_cast_checked<const byte_t*>(&* headerBegin());
629  }
630 
634  void clear();
635 
640  bool empty();
641 
646  void reserve(std::size_t cap);
647 
652  void swap(Fragment& other) noexcept;
653 
660  void swap(DATAVEC_T& other) noexcept { vals_.swap(other); };
661 
667 
680 
686  static FragmentPtr eodFrag(size_t nFragsToExpect);
687 
699  template<class InputIterator> static FragmentPtr dataFrag(sequence_id_t sequenceID,
700  fragment_id_t fragID,
701  InputIterator i,
702  InputIterator e)
703  {
704  FragmentPtr result(new Fragment(sequenceID, fragID));
705  result->vals_.reserve(std::distance(i, e) + detail::RawFragmentHeader::num_words());
706  std::copy(i, e, std::back_inserter(result->vals_));
707  result->updateFragmentHeaderWC_();
708  return result;
709  }
710 
721  fragment_id_t fragID,
722  RawDataType const* dataPtr,
723  size_t dataSize,
725 #endif
726 
727 private:
728  template <typename T>
729  static std::size_t validatedMetadataSize_();
730 
731  void updateFragmentHeaderWC_();
732 
733  DATAVEC_T vals_;
734 
735 #if HIDE_FROM_ROOT
736  detail::RawFragmentHeader* fragmentHeader();
737 
738  detail::RawFragmentHeader const* fragmentHeader() const;
739 #endif
740 };
741 
742 #if HIDE_FROM_ROOT
743 
744 
745 // http://stackoverflow.com/questions/33939687
746 // This should generate an exception if artdaq::Fragment is not move-constructible
747 inline artdaq::Fragment::Fragment(artdaq::Fragment&&) noexcept = default;
748 inline artdaq::Fragment& artdaq::Fragment::operator=(artdaq::Fragment&&) noexcept = default;
749 
750 inline
751 bool
752 constexpr
753 artdaq::Fragment::
754 isUserFragmentType(type_t fragmentType)
755 {
756  return fragmentType >= detail::RawFragmentHeader::FIRST_USER_TYPE &&
757  fragmentType <= detail::RawFragmentHeader::LAST_USER_TYPE;
758 }
759 
760 inline
761 bool
762 constexpr
765 {
766  return fragmentType >= detail::RawFragmentHeader::FIRST_SYSTEM_TYPE;
767 }
768 
769 template <typename T>
770 std::size_t
771 artdaq::Fragment::
772 validatedMetadataSize_()
773 {
774  // Make sure a size_t is big enough to hold the maximum metadata
775  // size. This *should* always be true, but it is a compile-time check
776  // and therefore cheap.
777  static_assert(sizeof(size_t) >=
778  sizeof(decltype(std::numeric_limits<detail::RawFragmentHeader::metadata_word_count_t>::max())),
779  "metadata_word_count_t is too big!");
780 
781  static size_t constexpr max_md_wc =
782  std::numeric_limits<detail::RawFragmentHeader::metadata_word_count_t>::max();
783  size_t requested_md_wc =
784  std::ceil(sizeof(T) / static_cast<double>(sizeof(artdaq::RawDataType)));
785  if (requested_md_wc > max_md_wc)
786  {
787  throw cet::exception("InvalidRequest")
788  << "The requested metadata structure is too large: "
789  << "requested word count = " << requested_md_wc
790  << ", maximum word count = " << max_md_wc;
791  }
792  return requested_md_wc;
793 }
794 
795 template <class T>
797 Fragment(std::size_t payload_size, sequence_id_t sequence_id,
798  fragment_id_t fragment_id,
799  type_t type, const T& metadata, timestamp_t timestamp) :
800  vals_((artdaq::detail::RawFragmentHeader::num_words() + // Header
801  validatedMetadataSize_<T>() + // Metadata
802  payload_size) // User data
803  )
804 {
805  TRACEN( "Fragment", 50, "Fragment ctor num_word()=%zu MetadataSize_=%zu payload_size=%zu"
806  ,artdaq::detail::RawFragmentHeader::num_words(), validatedMetadataSize_<T>(), payload_size );
807  // vals ctor w/o init val is used; make sure header is ALL initialized.
808  for (iterator ii = vals_.begin();
809  ii != (vals_.begin() + detail::RawFragmentHeader::num_words()); ++ii) {
810  *ii = -1;
811  }
813  updateFragmentHeaderWC_();
814  fragmentHeader()->sequence_id = sequence_id;
815  fragmentHeader()->fragment_id = fragment_id;
816  fragmentHeader()->timestamp = timestamp;
817  fragmentHeader()->type = type;
818 
819  fragmentHeader()->touch();
820 
821  fragmentHeader()->metadata_word_count =
822  vals_.size() -
823  (fragmentHeader()->num_words() + payload_size);
824 
825  memcpy(metadataAddress(), &metadata, sizeof(T));
826 }
827 
828 inline
829 std::size_t
831 {
832  return fragmentHeader()->word_count;
833 }
834 
835 inline
838 {
839  return fragmentHeader()->version;
840 }
841 
842 inline
845 {
846  return static_cast<type_t>(fragmentHeader()->type);
847 }
848 
849 inline
850 std::string
852 {
853  return std::to_string(type()) + (isSystemFragmentType(type()) ? " (" + detail::RawFragmentHeader::SystemTypeToString(type()) + ")" : "");
854 }
855 
856 inline
859 {
860  return fragmentHeader()->sequence_id;
861 }
862 
863 inline
866 {
867  return fragmentHeader()->fragment_id;
868 }
869 
870 inline
873 {
874  return fragmentHeader()->timestamp;
875 }
876 
877 inline
878 void
880 {
881  fragmentHeader()->setUserType(static_cast<uint8_t>(type));
882 }
883 
884 inline
885 void
887 {
888  fragmentHeader()->setSystemType(static_cast<uint8_t>(type));
889 }
890 
891 inline
892 void
894 {
895  assert(sequence_id <= detail::RawFragmentHeader::InvalidSequenceID);
896  fragmentHeader()->sequence_id = sequence_id;
897 }
898 
899 inline
900 void
902 {
903  fragmentHeader()->fragment_id = fragment_id;
904 }
905 
906 inline
907 void
909 {
910  fragmentHeader()->timestamp = timestamp;
911 }
912 
913 
915 {
916  fragmentHeader()->touch();
917 }
918 
919 inline struct timespec artdaq::Fragment::atime()
920 {
921  return fragmentHeader()->atime();
922 }
923 
924 inline struct timespec artdaq::Fragment::getLatency(bool touch) {
925  return fragmentHeader()->getLatency(touch);
926 }
927 
928 inline
929 void
930 artdaq::Fragment::updateFragmentHeaderWC_()
931 {
932  // Make sure vals_.size() fits inside 32 bits. Left-shift here should
933  // match bitfield size of word_count in RawFragmentHeader.
934  assert(vals_.size() < (1ULL << 32));
935  TRACEN( "Fragment", 50, "Fragment::updateFragmentHeaderWC_ adjusting fragmentHeader()->word_count from %u to %zu", (unsigned)(fragmentHeader()->word_count), vals_.size() );
936  fragmentHeader()->word_count = vals_.size();
937 }
938 
939 inline
940 std::size_t
942 {
943  return vals_.size() - fragmentHeader()->num_words() -
944  fragmentHeader()->metadata_word_count;
945 }
946 
947 inline
948 bool
950 {
951  return fragmentHeader()->metadata_word_count != 0;
952 }
953 
954 template <class T>
955 T*
957 {
958  if (fragmentHeader()->metadata_word_count == 0)
959  {
960  throw cet::exception("InvalidRequest")
961  << "No metadata has been stored in this Fragment.";
962  }
963 
964  return reinterpret_cast_checked<T *>
965  (&vals_[fragmentHeader()->num_words()]);
966 }
967 
968 template <class T>
969 T const*
971 {
972  if (fragmentHeader()->metadata_word_count == 0)
973  {
974  throw cet::exception("InvalidRequest")
975  << "No metadata has been stored in this Fragment.";
976  }
977  return reinterpret_cast_checked<T const *>
978  (&vals_[fragmentHeader()->num_words()]);
979 }
980 
981 template <class T>
982 void
984 {
985  if (fragmentHeader()->metadata_word_count != 0)
986  {
987  throw cet::exception("InvalidRequest")
988  << "Metadata has already been stored in this Fragment.";
989  }
990  auto const mdSize = validatedMetadataSize_<T>();
991  vals_.insert(dataBegin(), mdSize, 0);
992  updateFragmentHeaderWC_();
993  fragmentHeader()->metadata_word_count = mdSize;
994 
995  memcpy(metadataAddress(), &metadata, sizeof(T));
996 }
997 
998 template <class T>
999 void
1001 {
1002  if (fragmentHeader()->metadata_word_count == 0)
1003  {
1004  throw cet::exception("InvalidRequest")
1005  << "No metadata in fragment; please use Fragment::setMetadata instead of Fragment::updateMetadata";
1006  }
1007 
1008  auto const mdSize = validatedMetadataSize_<T>();
1009 
1010  if (fragmentHeader()->metadata_word_count != mdSize)
1011  {
1012  throw cet::exception("InvalidRequest")
1013  << "Mismatch between type of metadata struct passed to updateMetadata and existing metadata struct";
1014  }
1015 
1016  memcpy(metadataAddress(), &metadata, sizeof(T));
1017 }
1018 
1019 inline void
1021 {
1022  vals_.resize(sz + fragmentHeader()->metadata_word_count +
1023  fragmentHeader()->num_words());
1024  updateFragmentHeaderWC_();
1025 }
1026 
1027 inline
1028 void
1030 {
1031  vals_.resize(sz + fragmentHeader()->metadata_word_count +
1032  fragmentHeader()->num_words(), v);
1033  updateFragmentHeaderWC_();
1034 }
1035 
1036 inline void
1037 artdaq::Fragment::resizeBytes(std::size_t szbytes)
1038 {
1039  RawDataType nwords = ceil(szbytes / static_cast<double>(sizeof(RawDataType)));
1040  resize(nwords);
1041 }
1042 
1043 inline void
1044 artdaq::Fragment::resizeBytesWithCushion(std::size_t szbytes, double growthFactor)
1045 {
1046  RawDataType nwords = ceil(szbytes / static_cast<double>(sizeof(RawDataType)));
1047  vals_.resizeWithCushion(nwords + fragmentHeader()->metadata_word_count +
1048  fragmentHeader()->num_words(), growthFactor);
1049  updateFragmentHeaderWC_();
1050 }
1051 
1052 inline
1053 void
1054 artdaq::Fragment::resizeBytes(std::size_t szbytes, byte_t v)
1055 {
1056  RawDataType defaultval;
1057  byte_t* ptr = reinterpret_cast_checked<byte_t*>(&defaultval);
1058 
1059  for (uint8_t i = 0; i < sizeof(RawDataType); ++i)
1060  {
1061  *ptr = v;
1062  ptr++;
1063  }
1064 
1065  RawDataType nwords = ceil(szbytes / static_cast<double>(sizeof(RawDataType)));
1066 
1067  resize(nwords, defaultval);
1068 }
1069 
1070 
1071 inline
1072 void
1074 {
1075  vals_.resize(fragmentHeader()->word_count);
1076  updateFragmentHeaderWC_();
1077 }
1078 
1079 inline
1082 {
1083  return vals_.begin() + fragmentHeader()->num_words() +
1084  fragmentHeader()->metadata_word_count;
1085 }
1086 
1087 inline
1090 {
1091  return vals_.end();
1092 }
1093 
1094 inline
1097 {
1098  return vals_.begin();
1099 }
1100 
1101 inline
1104 {
1105  return vals_.begin() + fragmentHeader()->num_words() +
1106  fragmentHeader()->metadata_word_count;
1107 }
1108 
1109 inline
1112 {
1113  return vals_.end();
1114 }
1115 
1116 inline
1119 {
1120  return vals_.begin();
1121 }
1122 
1123 
1124 inline
1125 void
1127 {
1128  vals_.erase(dataBegin(), dataEnd());
1129  updateFragmentHeaderWC_();
1130 }
1131 
1132 inline
1133 bool
1135 {
1136  return (vals_.size() - fragmentHeader()->num_words() -
1137  fragmentHeader()->metadata_word_count) == 0;
1138 }
1139 
1140 inline
1141 void
1143 {
1144  vals_.reserve(cap + fragmentHeader()->num_words() +
1145  fragmentHeader()->metadata_word_count);
1146 }
1147 
1148 inline
1149 void
1151 {
1152  vals_.swap(other.vals_);
1153 }
1154 
1155 inline
1158 {
1159  return &vals_[0] + fragmentHeader()->num_words() +
1160  fragmentHeader()->metadata_word_count;
1161 }
1162 
1163 inline
1166 {
1167  if (fragmentHeader()->metadata_word_count == 0)
1168  {
1169  throw cet::exception("InvalidRequest")
1170  << "No metadata has been stored in this Fragment.";
1171  }
1172  return &vals_[0] + fragmentHeader()->num_words();
1173 }
1174 
1175 inline
1178 {
1179  return &vals_[0];
1180 }
1181 
1182 inline
1184 artdaq::Fragment::fragmentHeader()
1185 {
1186  auto hdr = reinterpret_cast_checked<detail::RawFragmentHeader *>(&vals_[0]);
1187  if (hdr->version != detail::RawFragmentHeader::CurrentVersion)
1188  {
1189  switch (hdr->version)
1190  {
1191  case 0xFFFF:
1192  //std::cout << "Not upgrading InvalidVersion Fragment" << std::endl;
1193  break;
1194  case 0:
1195  {
1196  std::cout << "Upgrading RawFragmentHeaderV0 (non const)" << std::endl;
1197  auto old_hdr = reinterpret_cast_checked<detail::RawFragmentHeaderV0 *>(&vals_[0]);
1198  auto new_hdr = old_hdr->upgrade();
1199 
1200  auto szDiff = hdr->num_words() - old_hdr->num_words();
1201  if (szDiff > 0) vals_.insert(vals_.begin(), szDiff, 0);
1202  memcpy(&vals_[0], &new_hdr, hdr->num_words() * sizeof(RawDataType));
1203  break;
1204  }
1205  case 1:
1206  {
1207  std::cout << "Upgrading RawFragmentHeaderV1 (non const)" << std::endl;
1208  auto old_hdr = reinterpret_cast_checked<detail::RawFragmentHeaderV1 *>(&vals_[0]);
1209  auto new_hdr = old_hdr->upgrade();
1210 
1211  auto szDiff = hdr->num_words() - old_hdr->num_words();
1212  if (szDiff > 0) vals_.insert(vals_.begin(), szDiff, 0);
1213  memcpy(&vals_[0], &new_hdr, hdr->num_words() * sizeof(RawDataType));
1214  break;
1215  }
1216  default:
1217  throw cet::exception("Fragment") << "A Fragment with an unknown version (" << std::to_string(hdr->version) << ") was received!";
1218  break;
1219  }
1220  }
1221  return hdr;
1222 }
1223 
1224 inline
1226 artdaq::Fragment::fragmentHeader() const
1227 {
1228  auto hdr = reinterpret_cast_checked<detail::RawFragmentHeader const*>(&vals_[0]);
1229  if (hdr->version != detail::RawFragmentHeader::CurrentVersion)
1230  {
1231  switch (hdr->version)
1232  {
1233  case 0xFFFF:
1234  //std::cout << "Not upgrading InvalidVersion Fragment" << std::endl;
1235  break;
1236  case 0:
1237  {
1238  std::cout << "Upgrading RawFragmentHeaderV0 (const)" << std::endl;
1239  auto old_hdr = reinterpret_cast_checked<detail::RawFragmentHeaderV0 const*>(&vals_[0]);
1240  auto new_hdr = old_hdr->upgrade();
1241 
1242  auto szDiff = hdr->num_words() - old_hdr->num_words();
1243  auto vals_nc = const_cast<DATAVEC_T*>(&vals_);
1244  if (szDiff > 0) vals_nc->insert(vals_nc->begin(), szDiff, 0);
1245  memcpy(&(*vals_nc)[0], &new_hdr, hdr->num_words() * sizeof(RawDataType));
1246  break;
1247  }
1248  case 1:
1249  {
1250  std::cout << "Upgrading RawFragmentHeaderV1 (const)" << std::endl;
1251  auto old_hdr = reinterpret_cast_checked<detail::RawFragmentHeaderV1 const*>(&vals_[0]);
1252  auto new_hdr = old_hdr->upgrade();
1253 
1254  auto szDiff = hdr->num_words() - old_hdr->num_words();
1255  auto vals_nc = const_cast<DATAVEC_T*>(&vals_);
1256  if (szDiff > 0) vals_nc->insert(vals_nc->begin(), szDiff, 0);
1257  memcpy(&(*vals_nc)[0], &new_hdr, hdr->num_words() * sizeof(RawDataType));
1258  break;
1259  }
1260  default:
1261  throw cet::exception("Fragment") << "A Fragment with an unknown version (" << std::to_string(hdr->version) << ") was received!";
1262  break;
1263  }
1264  }
1265  return hdr;
1266 }
1267 
1268 inline
1269 void
1270 swap(artdaq::Fragment& x, artdaq::Fragment& y) noexcept
1271 {
1272  x.swap(y);
1273 }
1274 
1275 inline
1276 std::ostream&
1277 artdaq::operator<<(std::ostream& os, artdaq::Fragment const& f)
1278 {
1279  f.print(os);
1280  return os;
1281 }
1282 #endif/* HIDE_FROM_ROOT */
1283 
1284 #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:1142
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.
struct timespec atime()
Get the last access time of the Fragment.
Definition: Fragment.hh:919
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:375
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:504
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:893
void setSystemType(type_t stype)
Sets the type of the Fragment, checking that it is a valid system type.
Definition: Fragment.hh:886
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:830
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
void updateMetadata(const T &md)
Updates existing metadata with a new metadata object.
Definition: Fragment.hh:1000
static constexpr type_t EmptyFragmentType
Copy EmptyFragmentType from RawFragmentHeader.
Definition: Fragment.hh:155
bool fragmentSequenceIDCompare(Fragment i, Fragment j)
Comparator for Fragment objects, based on their sequence_id.
Definition: Fragment.cc:8
const byte_t * dataEndBytes() const
Return const Fragment::byte_t* pointing at the end of the payload.
Definition: Fragment.hh:610
static constexpr bool isUserFragmentType(type_t fragmentType)
Returns whether the given type is in the range of user types.
Definition: Fragment.hh:754
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:552
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:1037
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:699
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:858
timestamp_t timestamp() const
Timestamp of the Fragment, from the Fragment header.
Definition: Fragment.hh:872
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:1020
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:1073
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
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:393
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:575
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
struct timespec getLatency(bool touch)
Get the difference between the current time and the last access time of the Fragment.
Definition: Fragment.hh:924
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:908
iterator headerBegin()
Return an iterator to the beginning of the header (should be used for serialization only: use setters...
Definition: Fragment.hh:1096
T reinterpret_cast_checked(RawDataType *in)
Wrapper around reinterpret_cast.
Definition: Fragment.hh:532
byte_t * dataEndBytes()
Return Fragment::byte_t* pointing at the end of the payload.
Definition: Fragment.hh:562
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:1081
bool empty()
Determines if the Fragment contains no data.
Definition: Fragment.hh:1134
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:879
void touch()
Update the access time of the Fragment.
Definition: Fragment.hh:914
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
std::ostream & operator<<(std::ostream &os, Fragment const &f)
Prints the given Fragment to the stream.
Definition: Fragment.hh:1277
void swap(QuickVec &other) noexcept
Exchanges references to two QuickVec objects.
Definition: QuickVec.hh:529
void setMetadata(const T &md)
Set the metadata in the Fragment to the contents of the specified structure. This throws an exception...
Definition: Fragment.hh:983
const byte_t * dataBeginBytes() const
Return const Fragment::byte_t* pointing at the beginning of the payload.
Definition: Fragment.hh:597
type_t type() const
Type of the Fragment, from the Fragment header.
Definition: Fragment.hh:844
RawDataType * dataAddress()
Returns a RawDataType pointer to the beginning of the payload.
Definition: Fragment.hh:1157
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 a 64-bit integer) is the basic unit of data representation within artdaq ...
T * metadata()
Return a pointer to the metadata. This throws an exception if the Fragment contains no metadata...
Definition: Fragment.hh:956
iterator dataEnd()
Return an iterator to the end of the data payload.
Definition: Fragment.hh:1089
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:851
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
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
void clear()
Removes all elements from the payload section of the Fragment.
Definition: Fragment.hh:1126
static constexpr bool isSystemFragmentType(type_t fragmentType)
Returns whether the given type is in the range of system types.
Definition: Fragment.hh:764
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:949
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:626
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:901
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:1150
static constexpr type_t EndOfSubrunFragmentType
Copy EndOfSubrunFragmentType from RawFragmentHeader.
Definition: Fragment.hh:152
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:1044
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:941
iterator begin()
Gets an iterator to the beginning of the QuickVec.
Definition: QuickVec.hh:399
void swap(QuickVec< RawDataType > &other) noexcept
Swaps two Fragment data vectors.
Definition: Fragment.hh:660
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:865
RawDataType * headerAddress()
Gets the address of the header.
Definition: Fragment.hh:1177
version_t version() const
Version of the Fragment, from the Fragment header.
Definition: Fragment.hh:837