fpmas 1.5
datapack.h
Go to the documentation of this file.
1#ifndef FPMAS_IO_DATAPACK_H
2#define FPMAS_IO_DATAPACK_H
3
8#include <string>
9#include <set>
10#include <list>
11#include <deque>
12
14#include "../api/utils/ptr_wrapper.h"
15
16namespace fpmas { namespace io { namespace datapack {
18 using api::utils::PtrWrapper;
19
54 template<typename T, typename Enable = void>
55 struct Serializer {
56 };
57
274 template<template<typename, typename Enable = void> class S>
278
279 private:
280 DataPack _data {0, 1};
281 std::size_t write_offset = 0;
282 mutable std::size_t read_offset = 0;
283
284 public:
285 BasicObjectPack() = default;
286
298 template<typename T>
299 BasicObjectPack(const T& item) {
300 std::size_t count = S<T>::size(*this, item);
301 this->allocate(count);
302 S<T>::to_datapack(*this, item);
303 write_offset+=count;
304 }
305
319 template<typename T>
321 this->allocate(S<T>::size(*this, item));
322 S<T>::to_datapack(*this, item);
323 return *this;
324 }
325
340 template<typename T>
341 std::size_t size() const {
342 return S<T>::size(*this);
343 }
344
355 template<typename T>
356 std::size_t size(const T& item) const {
357 return S<T>::size(*this, item);
358 }
359
364 const DataPack& data() const {
365 return _data;
366 }
367
375 std::size_t readOffset() const {
376 return read_offset;
377 }
378
387 void seekRead(std::size_t offset = 0) const {
388 read_offset = offset;
389 }
390
398 std::size_t writeOffset() const {
399 return write_offset;
400 }
401
410 void seekWrite(std::size_t offset = 0) {
411 write_offset = offset;
412 }
413
420 template<typename T>
421 void put(const T& item) {
422 S<T>::to_datapack(*this, item);
423 }
424
432 template<typename T>
433 T get() const {
434 T item = S<T>::from_datapack(*this);
435 return item;
436 }
437
444 void allocate(std::size_t size) {
445 _data = {size, 1};
446 }
447
478 void expand(std::size_t size) {
479 _data.resize(_data.size + size);
480 }
481
494 template<typename T>
495 void write(const T& item) {
496 std::size_t count = sizeof(T);
497 std::memcpy(&_data.buffer[write_offset], &item, count);
498 write_offset+=count;
499 }
500
515 void write(const void* input_data, std::size_t count) {
516 std::memcpy(&_data.buffer[write_offset], input_data, count);
517 write_offset+=count;
518 }
519
532 template<typename T>
533 void read(T& item) const {
534 std::size_t count = sizeof(T);
535 std::memcpy(&item, &_data.buffer[read_offset], count);
536 read_offset+=count;
537 }
538
553 void read(void* output_data, std::size_t count) const {
554 std::memcpy(output_data, &_data.buffer[read_offset], count);
555 read_offset+=count;
556 }
557
564 template<typename T>
565 T check() const {
566 T item;
567 check(item);
568 return item;
569 }
570
577 template<typename T>
578 void check(T& item) const {
579 std::size_t pos = readOffset();
580 read(item);
581 seekRead(pos);
582 }
583
593 write_offset = 0;
594 read_offset = 0;
595 return std::move(_data);
596 }
597
606 static BasicObjectPack<S> parse(DataPack&& data_pack) {
608 pack._data = std::move(data_pack);
609 return pack;
610 }
611
618 static BasicObjectPack<S> parse(const DataPack& data_pack) {
620 pack._data = data_pack;
621 return pack;
622 }
623
636 BasicObjectPack<S> extract(std::size_t size) const {
638 pack.allocate(size);
639 std::memcpy(
640 pack._data.buffer,
641 &this->_data.buffer[this->read_offset],
642 size
643 );
644 this->read_offset+=size;
645 return pack;
646 }
647 };
648
657 template<template<typename, typename> class S>
659
673 template<typename PackType>
674 static std::size_t size(
675 const PackType&, const BasicObjectPack<S>&) {
676 return sizeof(std::size_t);
677 }
678
685 template<typename PackType>
686 static void to_datapack(
687 PackType& parent, const BasicObjectPack<S>& child) {
688 parent.write(child._data.size);
689 parent.expand(child._data.size);
690 parent.write(child._data.buffer, child._data.size);
691 }
692
701 template<typename PackType>
702 static BasicObjectPack<S> from_datapack(const PackType& parent) {
703 std::size_t size;
704 parent.read(size);
705
706 BasicObjectPack<S> child;
707 child.allocate(size);
708 parent.read(child._data.buffer, size);
709 return child;
710 }
711 };
712
722 template<typename T>
723 struct Serializer<T, typename std::enable_if<std::is_fundamental<T>::value>::type> {
729 template<typename PackType>
730 static std::size_t size(const PackType&) {
731 return sizeof(T);
732 }
733
737 template<typename PackType>
738 static std::size_t size(const PackType&, const T&) {
739 return sizeof(T);
740 }
741
742
750 template<typename PackType>
751 static void to_datapack(PackType& pack, const T& item) {
752 pack.write(item);
753 }
754
762 template<typename PackType>
763 static T from_datapack(const PackType& pack) {
764 T item;
765 pack.read(item);
766 return item;
767 }
768 };
769
776 template<>
777 struct Serializer<std::string> {
786 template<typename PackType>
787 static std::size_t size(const PackType&, const std::string& str) {
788 return sizeof(std::size_t) + str.size();
789 }
790
797 template<typename PackType>
798 static void to_datapack(PackType& pack, const std::string& str) {
799 pack.write(str.size());
800 pack.write(str.data(), str.size());
801 }
802
809 template<typename PackType>
810 static std::string from_datapack(const PackType& pack) {
811 std::size_t size;
812 pack.read(size);
813
814 std::string str(&pack.data().buffer[pack.readOffset()], size);
815 pack.seekRead(pack.readOffset() + size);
816 return str;
817 }
818 };
819
827 template<typename T>
828 struct Serializer<std::vector<T>> {
832 template<typename PackType>
833 static std::size_t size(const PackType& p, const std::vector<T>& vec) {
834 std::size_t n = p.template size<std::size_t>();
835 for(const T& item : vec)
836 n += p.template size(item);
837 return n;
838 }
839
849 template<typename PackType>
850 static void to_datapack(PackType& pack, const std::vector<T>& vec) {
851 pack.template put(vec.size());
852 for(const T& item : vec)
853 pack.template put(item);
854 }
855
865 template<typename PackType>
866 static std::vector<T> from_datapack(const PackType& pack) {
867 std::size_t size = pack.template get<std::size_t>();
868 std::vector<T> data;
869 for(std::size_t i = 0; i < size; i++)
870 data.emplace_back(pack.template get<T>());
871 return data;
872 }
873 };
874
875
886 template<typename T>
887 struct Serializer<std::set<T>> {
891 template<typename PackType>
892 static std::size_t size(const PackType& p, const std::set<T>& set) {
893 std::size_t n = p.template size<std::size_t>();
894 for(auto item : set)
895 n += p.template size(item);
896 return n;
897 }
898
908 template<typename PackType>
909 static void to_datapack(PackType& pack, const std::set<T>& set) {
910 pack.template put(set.size());
911 // Items are written in order
912 for(auto item : set)
913 pack.template put(item);
914 }
915
928 template<typename PackType>
929 static std::set<T> from_datapack(const PackType& pack) {
930 std::size_t size = pack.template get<std::size_t>();
931 std::set<T> set;
932 auto current_hint = set.end();
933 for(std::size_t i = 0; i < size; i++) {
934 // Constant time insertion before end, since data is
935 // already sorted.
936 set.emplace_hint(current_hint, pack.template get<T>());
937 // Updates hint
938 current_hint = set.end();
939 }
940 return set;
941 }
942 };
943
951 template<typename T>
952 struct Serializer<std::list<T>> {
953
957 template<typename PackType>
958 static std::size_t size(const PackType& p, const std::list<T>& list) {
959 std::size_t n = p.template size<std::size_t>();
960 for(auto item : list)
961 n += p.template size(item);
962 return n;
963 }
964
974 template<typename PackType>
975 static void to_datapack(PackType& pack, const std::list<T>& list) {
976 pack.template put(list.size());
977 // Items are written in order
978 for(auto item : list)
979 pack. template put(item);
980 }
981
991 template<typename PackType>
992 static std::list<T> from_datapack(const PackType& pack) {
993 std::size_t size = pack.template get<std::size_t>();
994 std::list<T> data;
995 for(std::size_t i = 0; i < size; i++) {
996 data.emplace_back(pack.template get<T>());
997 }
998 return data;
999 }
1000 };
1001
1009 template<typename T>
1014 template<typename PackType>
1015 static std::size_t size(const PackType& p, const std::deque<T>& deque) {
1016 std::size_t n = p.template size<std::size_t>();
1017 for(auto item : deque)
1018 n += p.template size(item);
1019 return n;
1020 }
1021
1031 template<typename PackType>
1032 static void to_datapack(PackType& pack, const std::deque<T>& deque) {
1033 pack.template put(deque.size());
1034 // Items are written in order
1035 for(auto item : deque)
1036 pack.template put(item);
1037 }
1038
1048 template<typename PackType>
1049 static std::deque<T> from_datapack(const PackType& pack) {
1050 std::size_t size = pack.template get<std::size_t>();
1051 std::deque<T> deque;
1052 for(std::size_t i = 0; i < size; i++) {
1053 deque.emplace_back(pack.template get<std::size_t>());
1054 }
1055 return deque;
1056 }
1057 };
1058
1069 template<typename T1, typename T2>
1070 struct Serializer<std::pair<T1, T2>> {
1076 template<typename PackType>
1077 static std::size_t size(const PackType& p, const std::pair<T1, T2>& pair) {
1078 return p.template size(pair.first)
1079 + p.template size(pair.second);
1080 }
1081
1091 template<typename PackType>
1092 static void to_datapack(
1093 PackType& pack, const std::pair<T1, T2>& pair) {
1094 pack.template put(pair.first);
1095 pack.template put(pair.second);
1096 }
1097
1107 template<typename PackType>
1108 static std::pair<T1, T2> from_datapack(const PackType& pack) {
1109 return {
1110 pack.template get<T1>(),
1111 pack.template get<T2>()
1112 };
1113 }
1114 };
1115
1126 template<typename K, typename T, typename Comp, typename Alloc>
1127 struct Serializer<std::map<K, T, Comp, Alloc>> {
1133 template<typename PackType>
1134 static std::size_t size(
1135 const PackType& p,
1136 const std::map<K, T, Comp, Alloc>& map) {
1137 std::size_t n = p.template size<std::size_t>();
1138 for(auto& item : map)
1139 n += p.template size(item);
1140 return n;
1141 }
1142
1152 template<typename PackType>
1153 static void to_datapack(
1154 PackType& pack,
1155 const std::map<K, T, Comp, Alloc>& map) {
1156 pack.template put(map.size());
1157 // Items are written in order
1158 for(auto& item : map)
1159 pack.template put(item);
1160 }
1161
1171 template<typename PackType>
1172 static std::map<K, T, Comp, Alloc> from_datapack(
1173 const PackType& pack) {
1174 std::size_t size = pack.template get<std::size_t>();
1175 std::map<K, T> map;
1176 for(std::size_t i = 0; i < size; i++)
1177 map.emplace_hint(
1178 map.end(), pack.template get<std::pair<K, T>>());
1179 return map;
1180 }
1181 };
1182
1193 template<typename K, typename T, typename Hash, typename KeyEq, typename Alloc>
1194 struct Serializer<std::unordered_map<K, T, Hash, KeyEq, Alloc>> {
1200 template<typename PackType>
1201 static std::size_t size(
1202 const PackType& p,
1203 const std::unordered_map<K, T, Hash, KeyEq, Alloc>& map) {
1204 std::size_t n = p.template size<std::size_t>();
1205 for(auto& item : map)
1206 n += p.template size(item);
1207 return n;
1208 }
1209
1219 template<typename PackType>
1220 static void to_datapack(
1221 PackType& pack,
1222 const std::unordered_map<K, T, Hash, KeyEq, Alloc>& map) {
1223 pack.template put(map.size());
1224 // Items are written in order
1225 for(auto& item : map)
1226 pack.template put(item);
1227 }
1228
1238 template<typename PackType>
1239 static std::unordered_map<K, T, Hash, KeyEq, Alloc> from_datapack(
1240 const PackType& pack) {
1241 std::size_t size = pack.template get<std::size_t>();
1242 std::unordered_map<K, T> map;
1243 for(std::size_t i = 0; i < size; i++)
1244 map.emplace(pack.template get<std::pair<K, T>>());
1245 return map;
1246 }
1247 };
1248
1259 template<typename T, std::size_t N>
1260 struct Serializer<std::array<T, N>> {
1265 template<typename PackType>
1266 static std::size_t size(const PackType& p, const std::array<T, N>& array) {
1267 std::size_t n = 0;
1268 for(auto item : array)
1269 n += p.template size(item);
1270 return n;
1271 }
1272
1282 template<typename PackType>
1283 static void to_datapack(PackType& pack, const std::array<T, N>& array) {
1284 for(auto item : array)
1285 pack.template put(item);
1286 }
1287
1297 template<typename PackType>
1298 static std::array<T, N> from_datapack(const PackType& pack) {
1299 std::array<T, N> array;
1300 for(std::size_t i = 0; i < N; i++)
1301 array[i] = pack.template get<T>();
1302 return array;
1303 }
1304 };
1305
1312 template<>
1318 template<typename PackType>
1319 static std::size_t size(const PackType& p) {
1320 return
1321 p.template size<int>()
1322 + p.template size<FPMAS_ID_TYPE>();
1323 }
1324
1328 template<typename PackType>
1329 static std::size_t size(const PackType& p, const DistributedId&) {
1330 return size(p);
1331 }
1338 template<typename PackType>
1339 static void to_datapack(PackType& pack, const DistributedId& id) {
1340 pack.template put(id.rank());
1341 pack.template put(id.id());
1342 }
1349 template<typename PackType>
1350 static DistributedId from_datapack(const PackType& pack) {
1351 return {
1352 pack.template get<int>(), pack.template get<FPMAS_ID_TYPE>()
1353 };
1354 }
1355 };
1356
1365
1366 template<typename T, typename> struct LightSerializer;
1367
1374
1381 template<typename T, typename Enable = void>
1389 static std::size_t size(const LightObjectPack& p) {
1390 return Serializer<T>::size(p);
1391 }
1392
1398 static std::size_t size(const LightObjectPack& p, const T& item) {
1399 return Serializer<T>::size(p, item);
1400 }
1401
1409 static void to_datapack(LightObjectPack& pack, const T& item) {
1410 Serializer<T>::to_datapack(pack, item);
1411 }
1412
1422 static T from_datapack(const LightObjectPack& pack) {
1423 return Serializer<T>::from_datapack(pack);
1424 }
1425 };
1426
1432 template<template<typename, typename> class S>
1433 std::ostream& operator<<(std::ostream& o, const BasicObjectPack<S>& pack) {
1434 o.setf(std::ios_base::hex, std::ios_base::basefield);
1435 o.setf(std::ios_base::showbase);
1436 for(std::size_t i = 0; i < pack.data().size; i++)
1437 o << (unsigned short) pack.data().buffer[i] << " ";
1438 o.unsetf(std::ios_base::showbase);
1439 o.unsetf(std::ios_base::hex);
1440 return o;
1441 }
1442}}}
1443#endif
Definition: communication.h:16
std::size_t size
Definition: communication.h:23
char * buffer
Definition: communication.h:36
void resize(std::size_t count)
Definition: communication.h:130
Definition: distributed_id.h:89
Definition: datapack.h:275
std::size_t writeOffset() const
Definition: datapack.h:398
void seekRead(std::size_t offset=0) const
Definition: datapack.h:387
static BasicObjectPack< S > parse(DataPack &&data_pack)
Definition: datapack.h:606
std::size_t readOffset() const
Definition: datapack.h:375
BasicObjectPack< S > & operator=(const T &item)
Definition: datapack.h:320
T check() const
Definition: datapack.h:565
std::size_t size() const
Definition: datapack.h:341
void seekWrite(std::size_t offset=0)
Definition: datapack.h:410
void check(T &item) const
Definition: datapack.h:578
void write(const void *input_data, std::size_t count)
Definition: datapack.h:515
static BasicObjectPack< S > parse(const DataPack &data_pack)
Definition: datapack.h:618
DataPack dump()
Definition: datapack.h:592
void expand(std::size_t size)
Definition: datapack.h:478
void put(const T &item)
Definition: datapack.h:421
T get() const
Definition: datapack.h:433
void read(T &item) const
Definition: datapack.h:533
std::size_t size(const T &item) const
Definition: datapack.h:356
void read(void *output_data, std::size_t count) const
Definition: datapack.h:553
BasicObjectPack(const T &item)
Definition: datapack.h:299
void allocate(std::size_t size)
Definition: datapack.h:444
BasicObjectPack< S > extract(std::size_t size) const
Definition: datapack.h:636
const DataPack & data() const
Definition: datapack.h:364
void write(const T &item)
Definition: datapack.h:495
std::ostream & operator<<(std::ostream &o, const BasicObjectPack< S > &pack)
Definition: datapack.h:1433
BasicObjectPack< LightSerializer > LightObjectPack
Definition: datapack.h:1366
BasicObjectPack< Serializer > ObjectPack
Definition: datapack.h:1364
Definition: fpmas.cpp:3
Definition: datapack.h:1382
static void to_datapack(LightObjectPack &pack, const T &item)
Definition: datapack.h:1409
static std::size_t size(const LightObjectPack &p, const T &item)
Definition: datapack.h:1398
static std::size_t size(const LightObjectPack &p)
Definition: datapack.h:1389
static T from_datapack(const LightObjectPack &pack)
Definition: datapack.h:1422
static void to_datapack(PackType &parent, const BasicObjectPack< S > &child)
Definition: datapack.h:686
static std::size_t size(const PackType &, const BasicObjectPack< S > &)
Definition: datapack.h:674
static BasicObjectPack< S > from_datapack(const PackType &parent)
Definition: datapack.h:702
static DistributedId from_datapack(const PackType &pack)
Definition: datapack.h:1350
static std::size_t size(const PackType &p)
Definition: datapack.h:1319
static void to_datapack(PackType &pack, const DistributedId &id)
Definition: datapack.h:1339
static std::size_t size(const PackType &p, const DistributedId &)
Definition: datapack.h:1329
static std::size_t size(const PackType &, const T &)
Definition: datapack.h:738
static void to_datapack(PackType &pack, const T &item)
Definition: datapack.h:751
static std::array< T, N > from_datapack(const PackType &pack)
Definition: datapack.h:1298
static std::size_t size(const PackType &p, const std::array< T, N > &array)
Definition: datapack.h:1266
static void to_datapack(PackType &pack, const std::array< T, N > &array)
Definition: datapack.h:1283
static std::size_t size(const PackType &p, const std::deque< T > &deque)
Definition: datapack.h:1015
static void to_datapack(PackType &pack, const std::deque< T > &deque)
Definition: datapack.h:1032
static std::deque< T > from_datapack(const PackType &pack)
Definition: datapack.h:1049
static std::size_t size(const PackType &p, const std::list< T > &list)
Definition: datapack.h:958
static void to_datapack(PackType &pack, const std::list< T > &list)
Definition: datapack.h:975
static std::list< T > from_datapack(const PackType &pack)
Definition: datapack.h:992
static void to_datapack(PackType &pack, const std::map< K, T, Comp, Alloc > &map)
Definition: datapack.h:1153
static std::map< K, T, Comp, Alloc > from_datapack(const PackType &pack)
Definition: datapack.h:1172
static std::size_t size(const PackType &p, const std::map< K, T, Comp, Alloc > &map)
Definition: datapack.h:1134
static std::size_t size(const PackType &p, const std::pair< T1, T2 > &pair)
Definition: datapack.h:1077
static std::pair< T1, T2 > from_datapack(const PackType &pack)
Definition: datapack.h:1108
static void to_datapack(PackType &pack, const std::pair< T1, T2 > &pair)
Definition: datapack.h:1092
static std::size_t size(const PackType &p, const std::set< T > &set)
Definition: datapack.h:892
static void to_datapack(PackType &pack, const std::set< T > &set)
Definition: datapack.h:909
static std::set< T > from_datapack(const PackType &pack)
Definition: datapack.h:929
static void to_datapack(PackType &pack, const std::string &str)
Definition: datapack.h:798
static std::size_t size(const PackType &, const std::string &str)
Definition: datapack.h:787
static std::string from_datapack(const PackType &pack)
Definition: datapack.h:810
static std::size_t size(const PackType &p, const std::unordered_map< K, T, Hash, KeyEq, Alloc > &map)
Definition: datapack.h:1201
static void to_datapack(PackType &pack, const std::unordered_map< K, T, Hash, KeyEq, Alloc > &map)
Definition: datapack.h:1220
static std::unordered_map< K, T, Hash, KeyEq, Alloc > from_datapack(const PackType &pack)
Definition: datapack.h:1239
static std::vector< T > from_datapack(const PackType &pack)
Definition: datapack.h:866
static std::size_t size(const PackType &p, const std::vector< T > &vec)
Definition: datapack.h:833
static void to_datapack(PackType &pack, const std::vector< T > &vec)
Definition: datapack.h:850
Definition: datapack.h:55