artdaq_core  v3_05_03
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  TRACEN("Fragment", 4, "Upgrading RawFragmentHeaderV0 (non const)");
1198  auto old_hdr = reinterpret_cast_checked<detail::RawFragmentHeaderV0 *>(&vals_[0]);
1199  auto new_hdr = old_hdr->upgrade();
1200 
1201  auto szDiff = hdr->num_words() - old_hdr->num_words();
1202  if (szDiff > 0) vals_.insert(vals_.begin(), szDiff, 0);
1203  memcpy(&vals_[0], &new_hdr, hdr->num_words() * sizeof(RawDataType));
1204  hdr = reinterpret_cast_checked<detail::RawFragmentHeader*>(&vals_[0]); // Update hdr in case vals_->insert call invalidated pointers
1205  break;
1206  }
1207  case 1:
1208  {
1209  //std::cout << "Upgrading RawFragmentHeaderV1 (non const)" << std::endl;
1210  TRACEN("Fragment", 4, "Upgrading RawFragmentHeaderV1 (non const)");
1211  auto old_hdr = reinterpret_cast_checked<detail::RawFragmentHeaderV1 *>(&vals_[0]);
1212  auto new_hdr = old_hdr->upgrade();
1213 
1214  auto szDiff = hdr->num_words() - old_hdr->num_words();
1215  if (szDiff > 0) vals_.insert(vals_.begin(), szDiff, 0);
1216  memcpy(&vals_[0], &new_hdr, hdr->num_words() * sizeof(RawDataType));
1217  hdr = reinterpret_cast_checked<detail::RawFragmentHeader*>(&vals_[0]); // Update hdr in case vals_->insert call invalidated pointers
1218  break;
1219  }
1220  default:
1221  throw cet::exception("Fragment") << "A Fragment with an unknown version (" << std::to_string(hdr->version) << ") was received!";
1222  break;
1223  }
1224  }
1225  return hdr;
1226 }
1227 
1228 inline
1230 artdaq::Fragment::fragmentHeader() const
1231 {
1232  auto hdr = reinterpret_cast_checked<detail::RawFragmentHeader const*>(&vals_[0]);
1233  if (hdr->version != detail::RawFragmentHeader::CurrentVersion)
1234  {
1235  switch (hdr->version)
1236  {
1237  case 0xFFFF:
1238  //std::cout << "Not upgrading InvalidVersion Fragment" << std::endl;
1239  break;
1240  case 0:
1241  {
1242  //std::cout << "Upgrading RawFragmentHeaderV0 (const)" << std::endl;
1243  TRACEN("Fragment", 4, "Upgrading RawFragmentHeaderV0 (const)");
1244  auto old_hdr = reinterpret_cast_checked<detail::RawFragmentHeaderV0 const*>(&vals_[0]);
1245  auto new_hdr = old_hdr->upgrade();
1246 
1247  auto szDiff = hdr->num_words() - old_hdr->num_words();
1248  auto vals_nc = const_cast<DATAVEC_T*>(&vals_);
1249  if (szDiff > 0) vals_nc->insert(vals_nc->begin(), szDiff, 0);
1250  memcpy(&(*vals_nc)[0], &new_hdr, hdr->num_words() * sizeof(RawDataType));
1251  hdr = reinterpret_cast_checked<detail::RawFragmentHeader const*>(&vals_[0]); // Update hdr in case vals_nc->insert call invalidated pointers
1252  break;
1253  }
1254  case 1:
1255  {
1256  //std::cout << "Upgrading RawFragmentHeaderV1 (const)" << std::endl;
1257  TRACEN("Fragment", 4, "Upgrading RawFragmentHeaderV1 (const)");
1258  auto old_hdr = reinterpret_cast_checked<detail::RawFragmentHeaderV1 const*>(&vals_[0]);
1259  auto new_hdr = old_hdr->upgrade();
1260 
1261  auto szDiff = hdr->num_words() - old_hdr->num_words();
1262  auto vals_nc = const_cast<DATAVEC_T*>(&vals_);
1263  if (szDiff > 0) vals_nc->insert(vals_nc->begin(), szDiff, 0);
1264  memcpy(&(*vals_nc)[0], &new_hdr, hdr->num_words() * sizeof(RawDataType));
1265  hdr = reinterpret_cast_checked<detail::RawFragmentHeader const*>(&vals_[0]); // Update hdr in case vals_nc->insert call invalidated pointers
1266  break;
1267  }
1268  default:
1269  throw cet::exception("Fragment") << "A Fragment with an unknown version (" << std::to_string(hdr->version) << ") was received!";
1270  break;
1271  }
1272  }
1273  return hdr;
1274 }
1275 
1276 inline
1277 void
1278 swap(artdaq::Fragment& x, artdaq::Fragment& y) noexcept
1279 {
1280  x.swap(y);
1281 }
1282 
1283 inline
1284 std::ostream&
1285 artdaq::operator<<(std::ostream& os, artdaq::Fragment const& f)
1286 {
1287  f.print(os);
1288  return os;
1289 }
1290 #endif/* HIDE_FROM_ROOT */
1291 
1292 #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:394
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
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: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:1285
void swap(QuickVec &other) noexcept
Exchanges references to two QuickVec objects.
Definition: QuickVec.hh:530
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:400
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