TPIE

2362a60
serialization_stream.h
Go to the documentation of this file.
1 // -*- mode: c++; tab-width: 4; indent-tabs-mode: t; eval: (progn (c-set-style "stroustrup") (c-set-offset 'innamespace 0)); -*-
2 // vi:set ts=4 sts=4 sw=4 noet :
3 // Copyright 2013, The TPIE development team
4 //
5 // This file is part of TPIE.
6 //
7 // TPIE is free software: you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License as published by the
9 // Free Software Foundation, either version 3 of the License, or (at your
10 // option) any later version.
11 //
12 // TPIE is distributed in the hope that it will be useful, but WITHOUT ANY
13 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 // License for more details.
16 //
17 // You should have received a copy of the GNU Lesser General Public License
18 // along with TPIE. If not, see <http://www.gnu.org/licenses/>
19 
20 #ifndef TPIE_SERIALIZATION_STREAM_H
21 #define TPIE_SERIALIZATION_STREAM_H
22 
26 
27 #include <tpie/serialization2.h>
29 #include <memory>
30 #include <tpie/access_type.h>
31 #include <tpie/array.h>
32 #include <tpie/tempname.h>
33 #include <algorithm>
34 
35 namespace tpie {
36 
37 namespace bits {
38 
40 public:
41  static memory_size_type block_size() {
42  return 2*1024*1024;
43  }
44 
45 private:
46  file_accessor::raw_file_accessor m_fileAccessor;
47  stream_size_type m_blocksWritten;
48  stream_size_type m_size;
49  bool m_open;
50 
51  temp_file * m_tempFile;
52 
53 protected:
55 
56  void open(std::string path, bool reverse);
57  void open(temp_file & tempFile, bool reverse);
58 
59 private:
60  void open_inner(std::string path, bool reverse);
61 
62 protected:
71  void write_block(const char * const s, const memory_size_type n);
72 
73  void close(bool reverse);
74 
75 public:
76  static memory_size_type memory_usage() { return block_size(); }
77 
78  stream_size_type file_size();
79 };
80 
81 } // namespace bits
82 
84 private:
86 
87  tpie::array<char> m_block;
88  memory_size_type m_index;
89 
90  void write_block();
91 
92 public:
93 
94  class serializer {
96 
97  public:
98  serializer(serialization_writer & wr) : wr(wr) {}
99 
100  void write(const char * const s, const memory_size_type n) {
101  const char * i = s;
102  memory_size_type written = 0;
103  while (written != n) {
104  if (wr.m_index >= wr.block_size()) wr.write_block();
105 
106  memory_size_type remaining = n - written;
107  memory_size_type blockRemaining = wr.block_size() - wr.m_index;
108 
109  memory_size_type writeSize = std::min(remaining, blockRemaining);
110 
111  std::copy(i, i + writeSize, &wr.m_block[wr.m_index]);
112  i += writeSize;
113  written += writeSize;
114  wr.m_index += writeSize;
115  }
116  }
117  };
118 
119  friend class serializer;
120 
123 
124  void open(std::string path);
125  void open(temp_file & tempFile);
126 
127  void close();
128 
134  template <typename T>
135  void serialize(const T & v) {
136  using tpie::serialize;
137  serializer s(*this);
138  serialize(s, v);
139  }
140 
148  template <typename IT>
149  void serialize(IT a, IT b) {
150  using tpie::serialize;
151  serializer s(*this);
152  serialize(s, a, b);
153  }
154 };
155 
158 
159  tpie::array<char> m_block;
165  memory_size_type m_index;
166  std::vector<char> m_serializationBuffer;
167 
168  void write_block();
169 
170 public:
171 
172  class serializer {
174 
175  public:
176  serializer(serialization_reverse_writer & wr) : wr(wr) {}
177 
178  void write(const char * const s, const memory_size_type n) {
179  std::vector<char> & data = wr.m_serializationBuffer;
180  memory_size_type offs = data.size();
181  data.resize(data.size() + n);
182  std::copy(s, s + n, &data[offs]);
183  }
184 
185  ~serializer() {
186  std::vector<char> & data = wr.m_serializationBuffer;
187  const memory_size_type n = data.size();
188  const char * const s = &data[0];
189  if (wr.m_index + n <= wr.block_size()) {
190  std::copy(s, s + n, &wr.m_block[block_size() - wr.m_index - n]);
191  wr.m_index += n;
192  } else {
193  const char * i = s + n;
194  memory_size_type written = 0;
195  while (written != n) {
196  if (wr.m_index >= wr.block_size()) wr.write_block();
197 
198  memory_size_type remaining = n - written;
199  memory_size_type blockRemaining = wr.block_size() - wr.m_index;
200 
201  memory_size_type writeSize = std::min(remaining, blockRemaining);
202 
203  std::copy(i - writeSize, i, &wr.m_block[block_size() - wr.m_index - writeSize]);
204  i -= writeSize;
205  written += writeSize;
206  wr.m_index += writeSize;
207  }
208  }
209  data.resize(0);
210  }
211  };
212 
213  friend class serializer;
214 
217 
218  void open(std::string path);
219  void open(temp_file & tempFile);
220 
221  void close();
222 
228  template <typename T>
229  void serialize(const T & v) {
230  using tpie::serialize;
231  serializer s(*this);
232  serialize(s, v);
233  }
234 
242  template <typename IT>
243  void serialize(IT a, IT b) {
244  using tpie::serialize;
245  serializer s(*this);
246  serialize(s, a, b);
247  }
248 };
249 
250 namespace bits {
251 
253 public:
254  static memory_size_type block_size() {
255  return serialization_writer_base::block_size();
256  }
257 
258 private:
259  file_accessor::raw_file_accessor m_fileAccessor;
260  bool m_open;
261 
262 protected:
263  tpie::array<char> m_block;
264  stream_size_type m_size;
265  memory_size_type m_index;
266  memory_size_type m_blockSize;
267 
269 
270  void open(std::string path, bool reverse);
271 
272  void read_block(const stream_size_type blk);
273 
274  // Check if EOF is reached, call read_block(blk) to reset m_index/m_blockSize.
275  virtual void next_block() = 0;
276 
277 public:
278  void close();
279 
286  void read(char * const s, const memory_size_type n) {
287  // TODO: inline some of this
288  char * i = s;
289  memory_size_type written = 0;
290  while (written != n) {
291  if (m_index >= m_blockSize) {
292  // virtual invocation
293  next_block();
294  }
295 
296  memory_size_type remaining = n - written;
297  memory_size_type blockRemaining = m_blockSize - m_index;
298 
299  memory_size_type readSize = std::min(remaining, blockRemaining);
300 
301  i = std::copy(m_block.get() + m_index,
302  m_block.get() + (m_index + readSize),
303  i);
304 
305  written += readSize;
306  m_index += readSize;
307  }
308  }
309 
319  template <typename T>
320  void unserialize(T & v) {
321  using tpie::unserialize;
322  unserialize(*this, v);
323  }
324 
334  template <typename IT>
335  void unserialize(IT a, IT b) {
336  using tpie::unserialize;
337  unserialize(*this, a, b);
338  }
339 
340  static memory_size_type memory_usage() { return block_size(); }
341 
345  stream_size_type file_size();
346 
352  stream_size_type size();
353 };
354 
355 } // namespace bits
356 
359  stream_size_type m_blockNumber;
360 
361 protected:
362  void next_block() override;
363 
364 public:
366  virtual ~serialization_reader() = default;
367 
368  void open(std::string path);
369  void open(temp_file & tempFile);
370 
371  bool can_read() {
372  if (m_index < m_blockSize) return true;
373  return m_blockNumber * (stream_size_type)block_size() + m_index < m_size;
374  }
375 
381  stream_size_type offset();
382 };
383 
386  stream_size_type m_blockNumber;
387 
388 protected:
389  void next_block() override;
390 
391 public:
393 
394  void open(std::string path);
395  void open(temp_file & tempFile);
396 
397  bool can_read() {
398  if (m_index < m_blockSize) return true;
399  return m_blockNumber > 0;
400  }
401 
407  stream_size_type offset();
408 };
409 
410 }
411 
412 #endif // TPIE_SERIALIZATION_STREAM_H
T * get()
Return a raw pointer to the array content.
Definition: array.h:531
Binary serialization and unserialization.
stream_size_type offset()
Number of bytes read, not including the header.
void serialize(const T &v)
Serialize a serializable item and write it to the stream.
Declare default file accessor.
stream_size_type size()
Size of file in bytes, not including the header.
Generic internal array with known memory requirements.
void serialize(const T &v)
Serialize a serializable item and write it to the stream.
stream_size_type offset()
Number of bytes read, not including the header.
void write_block(const char *const s, const memory_size_type n)
Write n bytes from memory area s to next block in stream.
stream_size_type file_size()
Size of file in bytes, including the header.
void unserialize(S &src, foo &v)
Sample tpie::unserialize prototype.
void unserialize(T &v)
Unserialize an unserializable item from the stream.
Class representing a reference to a temporary file.
Definition: tempname.h:202
void serialize(IT a, IT b)
Serialize a sequence of serializable items and write them to the stream.
void serialize(IT a, IT b)
Serialize a sequence of serializable items and write them to the stream.
POSIX-style file accessor.
Definition: posix.h:35
Temporary file names.
Describes how to acces a file.
void serialize(D &dst, const foo &v)
Sample tpie::serialize prototype.
void unserialize(IT a, IT b)
Unserialize a sequence of unserializable items from the stream.
void read(char *const s, const memory_size_type n)
Read n bytes from stream into buffer starting at s.