fpmas 1.6
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
300 template<template<typename, typename Enable = void> class S>
304
305 private:
306 DataPack _data {0, 1};
307 std::size_t write_offset = 0;
308 mutable std::size_t read_offset = 0;
309
310 public:
311 BasicObjectPack() = default;
312
324 template<typename T>
325 BasicObjectPack(const T& item) {
326 std::size_t count = S<T>::size(*this, item);
327 this->allocate(count);
328 S<T>::to_datapack(*this, item);
329 write_offset+=count;
330 }
331
345 template<typename T>
347 this->allocate(S<T>::size(*this, item));
348 S<T>::to_datapack(*this, item);
349 return *this;
350 }
351
366 template<typename T>
367 std::size_t size() const {
368 return S<T>::size(*this);
369 }
370
381 template<typename T>
382 std::size_t size(const T& item) const {
383 return S<T>::size(*this, item);
384 }
385
390 const DataPack& data() const {
391 return _data;
392 }
393
401 std::size_t readOffset() const {
402 return read_offset;
403 }
404
413 void seekRead(std::size_t offset = 0) const {
414 read_offset = offset;
415 }
416
424 std::size_t writeOffset() const {
425 return write_offset;
426 }
427
436 void seekWrite(std::size_t offset = 0) {
437 write_offset = offset;
438 }
439
446 template<typename T>
447 void put(const T& item) {
448 S<T>::to_datapack(*this, item);
449 }
450
458 template<typename T>
459 T get() const {
460 T item = S<T>::from_datapack(*this);
461 return item;
462 }
463
470 void allocate(std::size_t size) {
471 _data = {size, 1};
472 }
473
504 void expand(std::size_t size) {
505 _data.resize(_data.size + size);
506 }
507
520 template<typename T>
521 void write(const T& item) {
522 std::size_t count = sizeof(T);
523 std::memcpy(&_data.buffer[write_offset], &item, count);
524 write_offset+=count;
525 }
526
541 void write(const void* input_data, std::size_t count) {
542 std::memcpy(&_data.buffer[write_offset], input_data, count);
543 write_offset+=count;
544 }
545
558 template<typename T>
559 void read(T& item) const {
560 std::size_t count = sizeof(T);
561 std::memcpy(&item, &_data.buffer[read_offset], count);
562 read_offset+=count;
563 }
564
579 void read(void* output_data, std::size_t count) const {
580 std::memcpy(output_data, &_data.buffer[read_offset], count);
581 read_offset+=count;
582 }
583
590 template<typename T>
591 T check() const {
592 T item;
593 check(item);
594 return item;
595 }
596
603 template<typename T>
604 void check(T& item) const {
605 std::size_t pos = readOffset();
606 read(item);
607 seekRead(pos);
608 }
609
619 write_offset = 0;
620 read_offset = 0;
621 return std::move(_data);
622 }
623
632 static BasicObjectPack<S> parse(DataPack&& data_pack) {
634 pack._data = std::move(data_pack);
635 return pack;
636 }
637
644 static BasicObjectPack<S> parse(const DataPack& data_pack) {
646 pack._data = data_pack;
647 return pack;
648 }
649
662 BasicObjectPack<S> extract(std::size_t size) const {
664 pack.allocate(size);
665 std::memcpy(
666 pack._data.buffer,
667 &this->_data.buffer[this->read_offset],
668 size
669 );
670 this->read_offset+=size;
671 return pack;
672 }
673 };
674
683 template<template<typename, typename> class S>
685
699 template<typename PackType>
700 static std::size_t size(
701 const PackType&, const BasicObjectPack<S>&) {
702 return sizeof(std::size_t);
703 }
704
711 template<typename PackType>
712 static void to_datapack(
713 PackType& parent, const BasicObjectPack<S>& child) {
714 parent.write(child._data.size);
715 parent.expand(child._data.size);
716 parent.write(child._data.buffer, child._data.size);
717 }
718
727 template<typename PackType>
728 static BasicObjectPack<S> from_datapack(const PackType& parent) {
729 std::size_t size;
730 parent.read(size);
731
732 BasicObjectPack<S> child;
733 child.allocate(size);
734 parent.read(child._data.buffer, size);
735 return child;
736 }
737 };
738
748 template<typename T>
749 struct Serializer<T, typename std::enable_if<std::is_fundamental<T>::value>::type> {
755 template<typename PackType>
756 static std::size_t size(const PackType&) {
757 return sizeof(T);
758 }
759
763 template<typename PackType>
764 static std::size_t size(const PackType&, const T&) {
765 return sizeof(T);
766 }
767
768
776 template<typename PackType>
777 static void to_datapack(PackType& pack, const T& item) {
778 pack.write(item);
779 }
780
788 template<typename PackType>
789 static T from_datapack(const PackType& pack) {
790 T item;
791 pack.read(item);
792 return item;
793 }
794 };
795
802 template<>
803 struct Serializer<std::string> {
812 template<typename PackType>
813 static std::size_t size(const PackType&, const std::string& str) {
814 return sizeof(std::size_t) + str.size();
815 }
816
823 template<typename PackType>
824 static void to_datapack(PackType& pack, const std::string& str) {
825 pack.write(str.size());
826 pack.write(str.data(), str.size());
827 }
828
835 template<typename PackType>
836 static std::string from_datapack(const PackType& pack) {
837 std::size_t size;
838 pack.read(size);
839
840 std::string str(&pack.data().buffer[pack.readOffset()], size);
841 pack.seekRead(pack.readOffset() + size);
842 return str;
843 }
844 };
845
853 template<typename T>
854 struct Serializer<std::vector<T>> {
858 template<typename PackType>
859 static std::size_t size(const PackType& p, const std::vector<T>& vec) {
860 std::size_t n = p.template size<std::size_t>();
861 for(const T& item : vec)
862 n += p.template size(item);
863 return n;
864 }
865
875 template<typename PackType>
876 static void to_datapack(PackType& pack, const std::vector<T>& vec) {
877 pack.template put(vec.size());
878 for(const T& item : vec)
879 pack.template put(item);
880 }
881
891 template<typename PackType>
892 static std::vector<T> from_datapack(const PackType& pack) {
893 std::size_t size = pack.template get<std::size_t>();
894 std::vector<T> data;
895 data.reserve(size);
896 for(std::size_t i = 0; i < size; i++)
897 data.emplace_back(pack.template get<T>());
898 return data;
899 }
900 };
901
902
913 template<typename T>
914 struct Serializer<std::set<T>> {
918 template<typename PackType>
919 static std::size_t size(const PackType& p, const std::set<T>& set) {
920 std::size_t n = p.template size<std::size_t>();
921 for(const T& item : set)
922 n += p.template size(item);
923 return n;
924 }
925
935 template<typename PackType>
936 static void to_datapack(PackType& pack, const std::set<T>& set) {
937 pack.template put(set.size());
938 // Items are written in order
939 for(const T& item : set)
940 pack.template put(item);
941 }
942
955 template<typename PackType>
956 static std::set<T> from_datapack(const PackType& pack) {
957 std::size_t size = pack.template get<std::size_t>();
958 std::set<T> set;
959 auto current_hint = set.end();
960 for(std::size_t i = 0; i < size; i++) {
961 // Constant time insertion before end, since data is
962 // already sorted.
963 set.emplace_hint(current_hint, pack.template get<T>());
964 // Updates hint
965 current_hint = set.end();
966 }
967 return set;
968 }
969 };
970
978 template<typename T>
979 struct Serializer<std::list<T>> {
980
984 template<typename PackType>
985 static std::size_t size(const PackType& p, const std::list<T>& list) {
986 std::size_t n = p.template size<std::size_t>();
987 for(const T& item : list)
988 n += p.template size(item);
989 return n;
990 }
991
1001 template<typename PackType>
1002 static void to_datapack(PackType& pack, const std::list<T>& list) {
1003 pack.template put(list.size());
1004 // Items are written in order
1005 for(const T& item : list)
1006 pack. template put(item);
1007 }
1008
1018 template<typename PackType>
1019 static std::list<T> from_datapack(const PackType& pack) {
1020 std::size_t size = pack.template get<std::size_t>();
1021 std::list<T> data;
1022 for(std::size_t i = 0; i < size; i++) {
1023 data.emplace_back(pack.template get<T>());
1024 }
1025 return data;
1026 }
1027 };
1028
1036 template<typename T>
1041 template<typename PackType>
1042 static std::size_t size(const PackType& p, const std::deque<T>& deque) {
1043 std::size_t n = p.template size<std::size_t>();
1044 for(auto item : deque)
1045 n += p.template size(item);
1046 return n;
1047 }
1048
1058 template<typename PackType>
1059 static void to_datapack(PackType& pack, const std::deque<T>& deque) {
1060 pack.template put(deque.size());
1061 // Items are written in order
1062 for(const T& item : deque)
1063 pack.template put(item);
1064 }
1065
1075 template<typename PackType>
1076 static std::deque<T> from_datapack(const PackType& pack) {
1077 std::size_t size = pack.template get<std::size_t>();
1078 std::deque<T> deque;
1079 for(std::size_t i = 0; i < size; i++) {
1080 deque.emplace_back(pack.template get<T>());
1081 }
1082 return deque;
1083 }
1084 };
1085
1096 template<typename T1, typename T2>
1097 struct Serializer<std::pair<T1, T2>> {
1103 template<typename PackType>
1104 static std::size_t size(const PackType& p, const std::pair<T1, T2>& pair) {
1105 return p.template size(pair.first)
1106 + p.template size(pair.second);
1107 }
1108
1118 template<typename PackType>
1119 static void to_datapack(
1120 PackType& pack, const std::pair<T1, T2>& pair) {
1121 pack.template put(pair.first);
1122 pack.template put(pair.second);
1123 }
1124
1134 template<typename PackType>
1135 static std::pair<T1, T2> from_datapack(const PackType& pack) {
1136 // Call order guaranteed, DO NOT CALL gets FROM THE CONSTRUCTOR
1137 T1 first = pack.template get<T1>();
1138 T2 second = pack.template get<T2>();
1139 return {std::move(first), std::move(second)};
1140 }
1141 };
1142
1153 template<typename K, typename T, typename Comp, typename Alloc>
1154 struct Serializer<std::map<K, T, Comp, Alloc>> {
1160 template<typename PackType>
1161 static std::size_t size(
1162 const PackType& p,
1163 const std::map<K, T, Comp, Alloc>& map) {
1164 std::size_t n = p.template size<std::size_t>();
1165 for(const auto& item : map)
1166 n += p.template size(item);
1167 return n;
1168 }
1169
1179 template<typename PackType>
1180 static void to_datapack(
1181 PackType& pack,
1182 const std::map<K, T, Comp, Alloc>& map) {
1183 pack.template put(map.size());
1184 // Items are written in order
1185 for(const auto& item : map)
1186 pack.template put(item);
1187 }
1188
1198 template<typename PackType>
1199 static std::map<K, T, Comp, Alloc> from_datapack(
1200 const PackType& pack) {
1201 std::size_t size = pack.template get<std::size_t>();
1202 std::map<K, T> map;
1203 for(std::size_t i = 0; i < size; i++)
1204 map.emplace_hint(
1205 map.end(), pack.template get<std::pair<K, T>>());
1206 return map;
1207 }
1208 };
1209
1220 template<typename K, typename T, typename Hash, typename KeyEq, typename Alloc>
1221 struct Serializer<std::unordered_map<K, T, Hash, KeyEq, Alloc>> {
1227 template<typename PackType>
1228 static std::size_t size(
1229 const PackType& p,
1230 const std::unordered_map<K, T, Hash, KeyEq, Alloc>& map) {
1231 std::size_t n = p.template size<std::size_t>();
1232 for(const auto& item : map)
1233 n += p.template size(item);
1234 return n;
1235 }
1236
1246 template<typename PackType>
1247 static void to_datapack(
1248 PackType& pack,
1249 const std::unordered_map<K, T, Hash, KeyEq, Alloc>& map) {
1250 pack.template put(map.size());
1251 // Items are written in order
1252 for(const auto& item : map)
1253 pack.template put(item);
1254 }
1255
1265 template<typename PackType>
1266 static std::unordered_map<K, T, Hash, KeyEq, Alloc> from_datapack(
1267 const PackType& pack) {
1268 std::size_t size = pack.template get<std::size_t>();
1269 std::unordered_map<K, T> map;
1270 map.reserve(size);
1271 for(std::size_t i = 0; i < size; i++)
1272 map.emplace(pack.template get<std::pair<K, T>>());
1273 return map;
1274 }
1275 };
1276
1287 template<typename T, std::size_t N>
1288 struct Serializer<std::array<T, N>> {
1293 template<typename PackType>
1294 static std::size_t size(const PackType& p, const std::array<T, N>& array) {
1295 std::size_t n = 0;
1296 for(const T& item : array)
1297 n += p.template size(item);
1298 return n;
1299 }
1300
1310 template<typename PackType>
1311 static void to_datapack(PackType& pack, const std::array<T, N>& array) {
1312 for(const T& item : array)
1313 pack.template put(item);
1314 }
1315
1325 template<typename PackType>
1326 static std::array<T, N> from_datapack(const PackType& pack) {
1327 std::array<T, N> array;
1328 for(std::size_t i = 0; i < N; i++)
1329 array[i] = pack.template get<T>();
1330 return array;
1331 }
1332 };
1333
1340 template<>
1346 template<typename PackType>
1347 static std::size_t size(const PackType& p) {
1348 return
1349 p.template size<int>()
1350 + p.template size<FPMAS_ID_TYPE>();
1351 }
1352
1356 template<typename PackType>
1357 static std::size_t size(const PackType& p, const DistributedId&) {
1358 return size(p);
1359 }
1366 template<typename PackType>
1367 static void to_datapack(PackType& pack, const DistributedId& id) {
1368 pack.template put(id.rank());
1369 pack.template put(id.id());
1370 }
1377 template<typename PackType>
1378 static DistributedId from_datapack(const PackType& pack) {
1379 // Call order guaranteed, DO NOT CALL gets FROM THE CONSTRUCTOR
1380 int p = pack.template get<int>();
1381 FPMAS_ID_TYPE id = pack.template get<FPMAS_ID_TYPE>();
1382 return {p, id};
1383 }
1384 };
1385
1394
1395 template<typename T, typename> struct LightSerializer;
1396
1403
1410 template<typename T, typename Enable = void>
1418 static std::size_t size(const LightObjectPack& p) {
1419 return Serializer<T>::size(p);
1420 }
1421
1427 static std::size_t size(const LightObjectPack& p, const T& item) {
1428 return Serializer<T>::size(p, item);
1429 }
1430
1438 static void to_datapack(LightObjectPack& pack, const T& item) {
1439 Serializer<T>::to_datapack(pack, item);
1440 }
1441
1451 static T from_datapack(const LightObjectPack& pack) {
1452 return Serializer<T>::from_datapack(pack);
1453 }
1454 };
1455
1461 template<template<typename, typename> class S>
1462 std::ostream& operator<<(std::ostream& o, const BasicObjectPack<S>& pack) {
1463 o.setf(std::ios_base::hex, std::ios_base::basefield);
1464 o.setf(std::ios_base::showbase);
1465 for(std::size_t i = 0; i < pack.data().size; i++)
1466 o << (unsigned short) pack.data().buffer[i] << " ";
1467 o.unsetf(std::ios_base::showbase);
1468 o.unsetf(std::ios_base::hex);
1469 return o;
1470 }
1471}}}
1472#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:301
std::size_t writeOffset() const
Definition: datapack.h:424
void seekRead(std::size_t offset=0) const
Definition: datapack.h:413
static BasicObjectPack< S > parse(DataPack &&data_pack)
Definition: datapack.h:632
std::size_t readOffset() const
Definition: datapack.h:401
BasicObjectPack< S > & operator=(const T &item)
Definition: datapack.h:346
T check() const
Definition: datapack.h:591
std::size_t size() const
Definition: datapack.h:367
void seekWrite(std::size_t offset=0)
Definition: datapack.h:436
void check(T &item) const
Definition: datapack.h:604
void write(const void *input_data, std::size_t count)
Definition: datapack.h:541
static BasicObjectPack< S > parse(const DataPack &data_pack)
Definition: datapack.h:644
DataPack dump()
Definition: datapack.h:618
void expand(std::size_t size)
Definition: datapack.h:504
void put(const T &item)
Definition: datapack.h:447
T get() const
Definition: datapack.h:459
void read(T &item) const
Definition: datapack.h:559
std::size_t size(const T &item) const
Definition: datapack.h:382
void read(void *output_data, std::size_t count) const
Definition: datapack.h:579
BasicObjectPack(const T &item)
Definition: datapack.h:325
void allocate(std::size_t size)
Definition: datapack.h:470
BasicObjectPack< S > extract(std::size_t size) const
Definition: datapack.h:662
const DataPack & data() const
Definition: datapack.h:390
void write(const T &item)
Definition: datapack.h:521
#define FPMAS_ID_TYPE
Definition: distributed_id.h:32
std::ostream & operator<<(std::ostream &o, const BasicObjectPack< S > &pack)
Definition: datapack.h:1462
BasicObjectPack< LightSerializer > LightObjectPack
Definition: datapack.h:1395
BasicObjectPack< Serializer > ObjectPack
Definition: datapack.h:1393
Definition: fpmas.cpp:3
Definition: datapack.h:1411
static void to_datapack(LightObjectPack &pack, const T &item)
Definition: datapack.h:1438
static std::size_t size(const LightObjectPack &p, const T &item)
Definition: datapack.h:1427
static std::size_t size(const LightObjectPack &p)
Definition: datapack.h:1418
static T from_datapack(const LightObjectPack &pack)
Definition: datapack.h:1451
static void to_datapack(PackType &parent, const BasicObjectPack< S > &child)
Definition: datapack.h:712
static std::size_t size(const PackType &, const BasicObjectPack< S > &)
Definition: datapack.h:700
static BasicObjectPack< S > from_datapack(const PackType &parent)
Definition: datapack.h:728
static DistributedId from_datapack(const PackType &pack)
Definition: datapack.h:1378
static std::size_t size(const PackType &p)
Definition: datapack.h:1347
static void to_datapack(PackType &pack, const DistributedId &id)
Definition: datapack.h:1367
static std::size_t size(const PackType &p, const DistributedId &)
Definition: datapack.h:1357
static std::size_t size(const PackType &, const T &)
Definition: datapack.h:764
static void to_datapack(PackType &pack, const T &item)
Definition: datapack.h:777
static std::array< T, N > from_datapack(const PackType &pack)
Definition: datapack.h:1326
static std::size_t size(const PackType &p, const std::array< T, N > &array)
Definition: datapack.h:1294
static void to_datapack(PackType &pack, const std::array< T, N > &array)
Definition: datapack.h:1311
static std::size_t size(const PackType &p, const std::deque< T > &deque)
Definition: datapack.h:1042
static void to_datapack(PackType &pack, const std::deque< T > &deque)
Definition: datapack.h:1059
static std::deque< T > from_datapack(const PackType &pack)
Definition: datapack.h:1076
static std::size_t size(const PackType &p, const std::list< T > &list)
Definition: datapack.h:985
static void to_datapack(PackType &pack, const std::list< T > &list)
Definition: datapack.h:1002
static std::list< T > from_datapack(const PackType &pack)
Definition: datapack.h:1019
static void to_datapack(PackType &pack, const std::map< K, T, Comp, Alloc > &map)
Definition: datapack.h:1180
static std::map< K, T, Comp, Alloc > from_datapack(const PackType &pack)
Definition: datapack.h:1199
static std::size_t size(const PackType &p, const std::map< K, T, Comp, Alloc > &map)
Definition: datapack.h:1161
static std::size_t size(const PackType &p, const std::pair< T1, T2 > &pair)
Definition: datapack.h:1104
static std::pair< T1, T2 > from_datapack(const PackType &pack)
Definition: datapack.h:1135
static void to_datapack(PackType &pack, const std::pair< T1, T2 > &pair)
Definition: datapack.h:1119
static std::size_t size(const PackType &p, const std::set< T > &set)
Definition: datapack.h:919
static void to_datapack(PackType &pack, const std::set< T > &set)
Definition: datapack.h:936
static std::set< T > from_datapack(const PackType &pack)
Definition: datapack.h:956
static void to_datapack(PackType &pack, const std::string &str)
Definition: datapack.h:824
static std::size_t size(const PackType &, const std::string &str)
Definition: datapack.h:813
static std::string from_datapack(const PackType &pack)
Definition: datapack.h:836
static std::size_t size(const PackType &p, const std::unordered_map< K, T, Hash, KeyEq, Alloc > &map)
Definition: datapack.h:1228
static void to_datapack(PackType &pack, const std::unordered_map< K, T, Hash, KeyEq, Alloc > &map)
Definition: datapack.h:1247
static std::unordered_map< K, T, Hash, KeyEq, Alloc > from_datapack(const PackType &pack)
Definition: datapack.h:1266
static std::vector< T > from_datapack(const PackType &pack)
Definition: datapack.h:892
static std::size_t size(const PackType &p, const std::vector< T > &vec)
Definition: datapack.h:859
static void to_datapack(PackType &pack, const std::vector< T > &vec)
Definition: datapack.h:876
Definition: datapack.h:55