TPIE

v1.1rc1-6-g0c97303
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 
34 namespace tpie {
35 
36 namespace bits {
37 
39 public:
40  static memory_size_type block_size() {
41  return 2*1024*1024;
42  }
43 
44 private:
45  file_accessor::raw_file_accessor m_fileAccessor;
46  stream_size_type m_blocksWritten;
47  stream_size_type m_size;
48  bool m_open;
49 
50  temp_file * m_tempFile;
51 
52 protected:
54 
55  void open(std::string path, bool reverse);
56  void open(temp_file & tempFile, bool reverse);
57 
58 private:
59  void open_inner(std::string path, bool reverse);
60 
61 protected:
70  void write_block(const char * const s, const memory_size_type n);
71 
72  void close(bool reverse);
73 
74 public:
75  static memory_size_type memory_usage() { return block_size(); }
76 
77  stream_size_type file_size();
78 };
79 
80 } // namespace bits
81 
83 private:
85 
86  tpie::array<char> m_block;
87  memory_size_type m_index;
88 
89  void write_block();
90 
91  class serializer {
93 
94  public:
95  serializer(serialization_writer & wr) : wr(wr) {}
96 
97  void write(const char * const s, const memory_size_type n) {
98  const char * i = s;
99  memory_size_type written = 0;
100  while (written != n) {
101  if (wr.m_index >= wr.block_size()) wr.write_block();
102 
103  memory_size_type remaining = n - written;
104  memory_size_type blockRemaining = wr.block_size() - wr.m_index;
105 
106  memory_size_type writeSize = std::min(remaining, blockRemaining);
107 
108  std::copy(i, i + writeSize, &wr.m_block[wr.m_index]);
109  i += writeSize;
110  written += writeSize;
111  wr.m_index += writeSize;
112  }
113  }
114  };
115 
116  friend class serializer;
117 
118 public:
119  void open(std::string path);
120  void open(temp_file & tempFile);
121 
122  void close();
123 
129  template <typename T>
130  void serialize(const T & v) {
131  using tpie::serialize;
132  serializer s(*this);
133  serialize(s, v);
134  }
135 
143  template <typename IT>
144  void serialize(IT a, IT b) {
145  using tpie::serialize;
146  serializer s(*this);
147  serialize(s, a, b);
148  }
149 };
150 
153 
154  tpie::array<char> m_block;
160  memory_size_type m_index;
161  std::vector<char> m_serializationBuffer;
162 
163  void write_block();
164 
165  class serializer {
167 
168  public:
169  serializer(serialization_reverse_writer & wr) : wr(wr) {}
170 
171  void write(const char * const s, const memory_size_type n) {
172  std::vector<char> & data = wr.m_serializationBuffer;
173  memory_size_type offs = data.size();
174  data.resize(data.size() + n);
175  std::copy(s, s + n, &data[offs]);
176  }
177 
178  ~serializer() {
179  std::vector<char> & data = wr.m_serializationBuffer;
180  const memory_size_type n = data.size();
181  const char * const s = &data[0];
182  if (wr.m_index + n <= wr.block_size()) {
183  std::copy(s, s + n, &wr.m_block[block_size() - wr.m_index - n]);
184  wr.m_index += n;
185  } else {
186  const char * i = s + n;
187  memory_size_type written = 0;
188  while (written != n) {
189  if (wr.m_index >= wr.block_size()) wr.write_block();
190 
191  memory_size_type remaining = n - written;
192  memory_size_type blockRemaining = wr.block_size() - wr.m_index;
193 
194  memory_size_type writeSize = std::min(remaining, blockRemaining);
195 
196  std::copy(i - writeSize, i, &wr.m_block[block_size() - wr.m_index - writeSize]);
197  i -= writeSize;
198  written += writeSize;
199  wr.m_index += writeSize;
200  }
201  }
202  data.resize(0);
203  }
204  };
205 
206  friend class serializer;
207 
208 public:
209  void open(std::string path);
210  void open(temp_file & tempFile);
211 
212  void close();
213 
219  template <typename T>
220  void serialize(const T & v) {
221  using tpie::serialize;
222  serializer s(*this);
223  serialize(s, v);
224  }
225 
233  template <typename IT>
234  void serialize(IT a, IT b) {
235  using tpie::serialize;
236  serializer s(*this);
237  serialize(s, a, b);
238  }
239 };
240 
241 namespace bits {
242 
244 public:
245  static memory_size_type block_size() {
246  return serialization_writer_base::block_size();
247  }
248 
249 private:
250  file_accessor::raw_file_accessor m_fileAccessor;
251  bool m_open;
252 
253 protected:
254  tpie::array<char> m_block;
255  stream_size_type m_size;
256  memory_size_type m_index;
257  memory_size_type m_blockSize;
258 
260 
261  void open(std::string path, bool reverse);
262 
263  void read_block(const stream_size_type blk);
264 
265  // Check if EOF is reached, call read_block(blk) to reset m_index/m_blockSize.
266  virtual void next_block() = 0;
267 
268 public:
269  void close();
270 
277  void read(char * const s, const memory_size_type n) {
278  // TODO: inline some of this
279  char * i = s;
280  memory_size_type written = 0;
281  while (written != n) {
282  if (m_index >= m_blockSize) {
283  // virtual invocation
284  next_block();
285  }
286 
287  memory_size_type remaining = n - written;
288  memory_size_type blockRemaining = m_blockSize - m_index;
289 
290  memory_size_type readSize = std::min(remaining, blockRemaining);
291 
292  i = std::copy(m_block.get() + m_index,
293  m_block.get() + (m_index + readSize),
294  i);
295 
296  written += readSize;
297  m_index += readSize;
298  }
299  }
300 
310  template <typename T>
311  void unserialize(T & v) {
312  using tpie::unserialize;
313  unserialize(*this, v);
314  }
315 
325  template <typename IT>
326  void unserialize(IT a, IT b) {
327  using tpie::unserialize;
328  unserialize(*this, a, b);
329  }
330 
331  static memory_size_type memory_usage() { return block_size(); }
332 
336  stream_size_type file_size();
337 
343  stream_size_type size();
344 };
345 
346 } // namespace bits
347 
350  stream_size_type m_blockNumber;
351 
352 protected:
353  virtual void next_block() /*override*/;
354 
355 public:
357 
358  void open(std::string path);
359  void open(temp_file & tempFile);
360 
361  bool can_read() {
362  if (m_index < m_blockSize) return true;
363  return m_blockNumber * (stream_size_type)block_size() + m_index < m_size;
364  }
365 
371  stream_size_type offset();
372 };
373 
376  stream_size_type m_blockNumber;
377 
378 protected:
379  virtual void next_block() /*override*/;
380 
381 public:
383 
384  void open(std::string path);
385  void open(temp_file & tempFile);
386 
387  bool can_read() {
388  if (m_index < m_blockSize) return true;
389  return m_blockNumber > 0;
390  }
391 
397  stream_size_type offset();
398 };
399 
400 }
401 
402 #endif // TPIE_SERIALIZATION_STREAM_H
T * get()
Return a raw pointer to the array content.
Definition: array.h:477
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 the existence of a temporary file.
Definition: tempname.h:152
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.