Thrill  0.1
serialization.hpp
Go to the documentation of this file.
1 /*******************************************************************************
2  * thrill/data/serialization.hpp
3  *
4  * Part of Project Thrill - http://project-thrill.org
5  *
6  * Copyright (C) 2015 Timo Bingmann <[email protected]>
7  *
8  * All rights reserved. Published under the BSD-2 license in the LICENSE file.
9  ******************************************************************************/
10 
11 #pragma once
12 #ifndef THRILL_DATA_SERIALIZATION_HEADER
13 #define THRILL_DATA_SERIALIZATION_HEADER
14 
17 #include <tlx/meta/has_member.hpp>
18 
19 #include <array>
20 #include <string>
21 #include <tuple>
22 #include <type_traits>
23 #include <utility>
24 #include <vector>
25 
26 namespace thrill {
27 namespace data {
28 
29 //! \addtogroup data_layer
30 //! \{
31 
32 /******************* Serialization of plain old data types ********************/
33 
34 template <typename Archive, typename T>
35 struct Serialization<Archive, T,
36  typename std::enable_if<
37  // a POD, but not a pointer
38  std::is_pod<T>::value
39  && !std::is_pointer<T>::value
40  >::type> {
41  static void Serialize(const T& x, Archive& ar) {
42  ar.template PutRaw<T>(x);
43  }
44  static T Deserialize(Archive& ar) {
45  return ar.template GetRaw<T>();
46  }
47  static constexpr bool is_fixed_size = true;
48  static constexpr size_t fixed_size = sizeof(T);
49 };
50 
51 /********************** Serialization of strings ******************************/
52 
53 template <typename Archive>
54 struct Serialization<Archive, std::string> {
55  static void Serialize(const std::string& x, Archive& ar) {
56  ar.PutString(x);
57  }
58  static std::string Deserialize(Archive& ar) {
59  return ar.GetString();
60  }
61  static constexpr bool is_fixed_size = false;
62  static constexpr size_t fixed_size = 0;
63 };
64 
65 /*********************** Serialization of pairs *******************************/
66 
67 template <typename Archive, typename U, typename V>
68 struct Serialization<Archive, std::pair<U, V> > {
69  static void Serialize(const std::pair<U, V>& x, Archive& ar) {
72  }
73  static std::pair<U, V> Deserialize(Archive& ar) {
76  return std::pair<U, V>(std::move(u), std::move(v));
77  }
78  static constexpr bool is_fixed_size =
81  static constexpr size_t fixed_size =
84 };
85 
86 //! \addtogroup data_internal Data Internals
87 //! \{
88 
89 /*********************** Serialization of tuples ******************************/
90 
91 namespace detail {
92 
93 // ------------------------- tuple serializer --------------------------------//
94 // serialize the (|tuple| - RevIndex)-th element in the tuple
95 // and call recursively to serialize the next element:
96 // (|tuple| - (RevIndex - 1))
97 // for simplicity we talk about the k-th element
98 template <typename Archive, size_t RevIndex, typename... Args>
100 
101  static constexpr size_t Index = sizeof ... (Args) - RevIndex;
102  // type of k-th element
103  using ThisElemType =
104  typename std::tuple_element<Index, std::tuple<Args...> >::type;
105 
106  static void Serialize(const std::tuple<Args...>& x, Archive& ar) {
107  // serialize k-th element
108  Serialization<Archive, ThisElemType>::Serialize(std::get<Index>(x), ar);
109  // recursively serialize (k+1)-th element
111  }
112 
113  static constexpr bool is_fixed_size
115  && TupleSerialization<Archive, RevIndex - 1, Args...>::is_fixed_size;
116 
117  static constexpr size_t fixed_size =
119  + TupleSerialization<Archive, RevIndex - 1, Args...>::fixed_size;
120 };
121 
122 // Base case when RevIndex == 0
123 template <typename Archive, typename... Args>
124 struct TupleSerialization<Archive, 0, Args...> {
125  static void Serialize(const std::tuple<Args...>&, Archive&) {
126  // Doesn't do anything
127  }
128  static constexpr bool is_fixed_size = true;
129  static constexpr size_t fixed_size = 0;
130 };
131 
132 // ------------------------- tuple deserializer ------------------------------//
133 template <typename Archive, int RevIndex, typename T, typename... Args>
134 struct TupleDeserializer { };
135 
136 // deserialize the (|tuple| - RevIndex)-th element in the tuple and call
137 // recursively to serialize the next element: (|tuple| - (RevIndex - 1)) for
138 // simplicity we talk about the k-th element
139 template <typename Archive, int RevIndex, typename T, typename... Args>
140 struct TupleDeserializer<Archive, RevIndex, std::tuple<T, Args...> > {
141  static std::tuple<T, Args...> Deserialize(Archive& ar) {
142  // deserialize the k-th element and put it in a tuple
143  auto head = std::make_tuple(Serialization<Archive, T>::Deserialize(ar));
144  // deserialize all elements i, i > k and concat the tuples
145  return std::tuple_cat(
146  head, TupleDeserializer<
147  Archive, RevIndex - 1, std::tuple<Args...> >::Deserialize(ar));
148  }
149 };
150 
151 // Base Case when RevIndex == 0
152 template <typename Archive>
153 struct TupleDeserializer<Archive, 0, std::tuple<> > {
154  static std::tuple<> Deserialize(Archive&) {
155  return std::make_tuple();
156  }
157 };
158 
159 } // namespace detail
160 
161 //! \}
162 
163 // -------------------- tuple de-/serializer interface -----------------------//
164 template <typename Archive, typename... Args>
165 struct Serialization<Archive, std::tuple<Args...> > {
166  static void Serialize(const std::tuple<Args...>& x, Archive& ar) {
168  Archive, sizeof ... (Args), Args...>::Serialize(x, ar);
169  }
170  static std::tuple<Args...> Deserialize(Archive& ar) {
172  Archive, sizeof ... (Args), std::tuple<Args...> >::Deserialize(ar);
173  }
174 
175  static constexpr bool is_fixed_size = detail::TupleSerialization<
176  Archive, sizeof ... (Args), Args...>::is_fixed_size;
177  static constexpr size_t fixed_size = detail::TupleSerialization<
178  Archive, sizeof ... (Args), Args...>::fixed_size;
179 };
180 
181 /*********************** Serialization of vector ******************************/
182 
183 template <typename Archive, typename T>
184 struct Serialization<Archive, std::vector<T> > {
185  static void Serialize(const std::vector<T>& x, Archive& ar) {
186  ar.PutVarint(x.size());
187  for (typename std::vector<T>::const_iterator it = x.begin();
188  it != x.end(); ++it)
190  }
191  static std::vector<T> Deserialize(Archive& ar) {
192  size_t size = ar.GetVarint();
193  std::vector<T> out;
194  out.reserve(size);
195  for (size_t i = 0; i != size; ++i)
196  out.emplace_back(Serialization<Archive, T>::Deserialize(ar));
197  return out;
198  }
199  static constexpr bool is_fixed_size = false;
200  static constexpr size_t fixed_size = 0;
201 };
202 
203 /*********************** Serialization of array *******************************/
204 
205 template <typename Archive, typename T, size_t N>
206 struct Serialization<Archive, std::array<T, N>,
207  typename std::enable_if<
208  // sometimes std::array<T> is a POD, if T is a POD
209  !std::is_pod<std::array<T, N> >::value
210  >::type
211  > {
212  static void Serialize(const std::array<T, N>& x, Archive& ar) {
213  for (typename std::array<T, N>::const_iterator it = x.begin();
214  it != x.end(); ++it)
216  }
217  static std::array<T, N> Deserialize(Archive& ar) {
218  std::array<T, N> out;
219  for (size_t i = 0; i != N; ++i)
220  out[i] = std::move(Serialization<Archive, T>::Deserialize(ar));
221  return out;
222  }
223  static constexpr bool is_fixed_size = Serialization<Archive, T>::is_fixed_size;
224  static constexpr size_t fixed_size = N * Serialization<Archive, T>::fixed_size;
225 };
226 
227 /******************* Serialization via Class Methods **************************/
228 
229 TLX_MAKE_HAS_MEMBER(thrill_is_fixed_size);
230 
231 template <typename Archive, typename T>
232 struct Serialization<Archive, T,
233  typename std::enable_if<
234  has_member_thrill_is_fixed_size<T>::value
235  >::type
236  > {
237  static void Serialize(const T& x, Archive& ar) {
238  x.ThrillSerialize(ar);
239  }
240  static T Deserialize(Archive& ar) {
241  return T::ThrillDeserialize(ar);
242  }
243  static constexpr bool is_fixed_size = T::thrill_is_fixed_size;
244  static constexpr size_t fixed_size = T::thrill_fixed_size;
245 };
246 
247 //! \}
248 
249 } // namespace data
250 } // namespace thrill
251 
252 #endif // !THRILL_DATA_SERIALIZATION_HEADER
253 
254 /******************************************************************************/
double T
TLX_MAKE_HAS_MEMBER(thrill_is_fixed_size)
typename std::tuple_element< Index, std::tuple< Args... > >::type ThisElemType
STL namespace.
static std::tuple< Args... > Deserialize(Archive &ar)
static std::pair< U, V > Deserialize(Archive &ar)
static void Serialize(const std::vector< T > &x, Archive &ar)
int N
Definition: gen_data.py:15
static void Serialize(const std::pair< U, V > &x, Archive &ar)
list x
Definition: gen_data.py:39
static std::vector< T > Deserialize(Archive &ar)
static void Serialize(const std::tuple< Args... > &x, Archive &ar)
std::basic_string< char, std::char_traits< char >, Allocator< char > > string
string with Manager tracking
Definition: allocator.hpp:220
std::vector< T, Allocator< T > > vector
vector with Manager tracking
Definition: allocator.hpp:228
static void Serialize(const std::tuple< Args... > &, Archive &)
static void Serialize(const std::tuple< Args... > &x, Archive &ar)
static void Serialize(const std::string &x, Archive &ar)