TPIE

11a2c2d
file_stream_base.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 2012 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 
23 
24 #ifndef __TPIE_FILE_STREAM_BASE_H__
25 #define __TPIE_FILE_STREAM_BASE_H__
26 
27 #include <tpie/tpie_export.h>
28 #include <tpie/file_base_crtp.h>
29 #include <tpie/stream_crtp.h>
30 #include <algorithm>
31 namespace tpie {
32 
33 class TPIE_EXPORT file_stream_base: public file_base_crtp<file_stream_base>, public stream_crtp<file_stream_base> {
34 public:
37 
38  friend class file_base_crtp<file_stream_base>;
39 
40  struct block_t {
41  memory_size_type size;
42  stream_size_type number;
43  bool dirty;
44  char * data;
45  };
46 
52  inline void close() {
53  if (m_open) flush_block();
54  tpie_delete_array(m_block.data, m_itemSize * m_blockItems);
55  m_block.data = 0;
56  p_t::close();
57  }
58 
59 
67  inline void truncate(stream_size_type size) {
68  stream_size_type o=offset();
69  flush_block();
70  m_block.number = std::numeric_limits<stream_size_type>::max();
71  m_nextBlock = std::numeric_limits<stream_size_type>::max();
72  m_nextIndex = std::numeric_limits<memory_size_type>::max();
73  m_index = std::numeric_limits<memory_size_type>::max();
74  m_size = size;
75  m_fileAccessor->truncate(size);
76  if (m_tempFile)
77  m_tempFile->update_recorded_size(m_fileAccessor->byte_size());
78  seek(std::min(o, size));
79  }
80 
81 protected:
82  file_stream_base(memory_size_type itemSize,
83  double blockFactor,
84  file_accessor::file_accessor * fileAccessor);
85 
86  inline ~file_stream_base() {
87  close();
88  }
89 
90  void swap(file_stream_base & other) {
91  using std::swap;
92  swap(m_index, other.m_index);
93  swap(m_nextBlock, other.m_nextBlock);
94  swap(m_nextIndex, other.m_nextIndex);
95  swap(m_blockStartIndex, other.m_blockStartIndex);
96  swap(m_blockItems, other.m_blockItems);
97  swap(m_blockSize, other.m_blockSize);
98  swap(m_size, other.m_size);
99  swap(m_canRead, other.m_canRead);
100  swap(m_canWrite, other.m_canWrite);
101  swap(m_itemSize, other.m_itemSize);
102  swap(m_open, other.m_open);
103  swap(m_fileAccessor, other.m_fileAccessor);
104  swap(m_block.size, other.m_block.size);
105  swap(m_block.number, other.m_block.number);
106  swap(m_block.dirty, other.m_block.dirty);
107  swap(m_block.data, other.m_block.data);
108  swap(m_ownedTempFile, other.m_ownedTempFile);
109  swap(m_tempFile, other.m_tempFile);
110  }
111 
112  inline void open_inner(const std::string & path,
113  access_type accessType,
114  memory_size_type userDataSize,
115  cache_hint cacheHint) {
116  p_t::open_inner(path, accessType, userDataSize, cacheHint);
117 
118  m_blockStartIndex = 0;
119  m_nextBlock = std::numeric_limits<stream_size_type>::max();
120  m_nextIndex = std::numeric_limits<memory_size_type>::max();
121  m_index = std::numeric_limits<memory_size_type>::max();
122 
123  m_block.size = 0;
124  m_block.number = std::numeric_limits<stream_size_type>::max();
125  m_block.dirty = false;
126  m_block.data = tpie_new_array<char>(m_blockItems * m_itemSize);
127 
128  initialize();
129  seek(0);
130  }
131 
135  void get_block(stream_size_type block);
136 
140  inline void flush_block() {
141  if (m_block.dirty) {
142  assert(m_canWrite);
143  update_vars();
144  m_fileAccessor->write_block(m_block.data, m_block.number, m_block.size);
145  if (m_tempFile)
146  m_tempFile->update_recorded_size(m_fileAccessor->byte_size());
147  }
148  m_block.dirty = false;
149  }
150 
151  inline void update_vars() {
152  if (m_block.dirty && m_index != std::numeric_limits<memory_size_type>::max()) {
153  assert(m_index <= m_blockItems);
154  m_block.size = std::max(m_block.size, m_index);
155  m_size = std::max(m_size, static_cast<stream_size_type>(m_index)+m_blockStartIndex);
156  }
157  }
158 
159  inline void initialize() {
160  flush_block();
161  s_t::initialize();
162  }
163 
164  inline void write_update() {
165  m_block.dirty = true;
166  }
167 
168 
169  block_t m_block;
170 
171 private:
172  friend class stream_crtp<file_stream_base>;
173  file_stream_base & get_file() {return *this;}
174  const file_stream_base & get_file() const {return *this;}
175  block_t & get_block() {return m_block;}
176  const block_t & get_block() const {return m_block;}
177  void update_block_core();
178 };
179 
180 } // namespace tpie
181 
182 #endif // __TPIE_FILE_STREAM_BASE_H__
stream_crtp.h
tpie::file_stream_base::truncate
void truncate(stream_size_type size)
Truncate file to given size.
Definition: file_stream_base.h:67
tpie::stream_crtp
Definition: stream_crtp.h:36
tpie::access_type
access_type
Type describing how we wish to access a file.
Definition: access_type.h:29
tpie::file_stream_base::block_t
Definition: file_stream_base.h:40
tpie::file_stream_base::close
void close()
Close the file and release resources.
Definition: file_stream_base.h:52
tpie::file_base_crtp
Base class of classes that access files.
Definition: file_base_crtp.h:50
tpie::cache_hint
cache_hint
Definition: cache_hint.h:28
tpie::file_accessor::stream_accessor_base
Definition: stream_accessor_base.h:34
file_base_crtp.h
tpie::tpie_delete_array
void tpie_delete_array(T *a, size_t size)
Delete an array allocated with tpie_new_array.
Definition: memory.h:288
tpie::file_stream_base
Definition: file_stream_base.h:33
tpie
Definition: access_type.h:26
tpie::file_stream_base::flush_block
void flush_block()
Write block to disk.
Definition: file_stream_base.h:140