TPIE

2362a60
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/file_base_crtp.h>
28 #include <tpie/stream_crtp.h>
29 #include <algorithm>
30 namespace tpie {
31 
32 class file_stream_base: public file_base_crtp<file_stream_base>, public stream_crtp<file_stream_base> {
33 public:
36 
37  friend class file_base_crtp<file_stream_base>;
38 
39  struct block_t {
40  memory_size_type size;
41  stream_size_type number;
42  bool dirty;
43  char * data;
44  };
45 
51  inline void close() throw(stream_exception) {
52  if (m_open) flush_block();
53  tpie_delete_array(m_block.data, m_itemSize * m_blockItems);
54  m_block.data = 0;
55  p_t::close();
56  }
57 
58 
66  inline void truncate(stream_size_type size) {
67  stream_size_type o=offset();
68  flush_block();
69  m_block.number = std::numeric_limits<stream_size_type>::max();
70  m_nextBlock = std::numeric_limits<stream_size_type>::max();
71  m_nextIndex = std::numeric_limits<memory_size_type>::max();
72  m_index = std::numeric_limits<memory_size_type>::max();
73  m_size = size;
74  m_fileAccessor->truncate(size);
75  if (m_tempFile)
76  m_tempFile->update_recorded_size(m_fileAccessor->byte_size());
77  seek(std::min(o, size));
78  }
79 
80 protected:
81  file_stream_base(memory_size_type itemSize,
82  double blockFactor,
83  file_accessor::file_accessor * fileAccessor);
84 
85  inline ~file_stream_base() {
86  close();
87  }
88 
89  void swap(file_stream_base & other) {
90  using std::swap;
91  swap(m_index, other.m_index);
92  swap(m_nextBlock, other.m_nextBlock);
93  swap(m_nextIndex, other.m_nextIndex);
94  swap(m_blockStartIndex, other.m_blockStartIndex);
95  swap(m_blockItems, other.m_blockItems);
96  swap(m_blockSize, other.m_blockSize);
97  swap(m_size, other.m_size);
98  swap(m_canRead, other.m_canRead);
99  swap(m_canWrite, other.m_canWrite);
100  swap(m_itemSize, other.m_itemSize);
101  swap(m_open, other.m_open);
102  swap(m_fileAccessor, other.m_fileAccessor);
103  swap(m_block.size, other.m_block.size);
104  swap(m_block.number, other.m_block.number);
105  swap(m_block.dirty, other.m_block.dirty);
106  swap(m_block.data, other.m_block.data);
107  swap(m_ownedTempFile, other.m_ownedTempFile);
108  swap(m_tempFile, other.m_tempFile);
109  }
110 
111  inline void open_inner(const std::string & path,
112  access_type accessType,
113  memory_size_type userDataSize,
114  cache_hint cacheHint) throw (stream_exception) {
115  p_t::open_inner(path, accessType, userDataSize, cacheHint);
116 
117  m_blockStartIndex = 0;
118  m_nextBlock = std::numeric_limits<stream_size_type>::max();
119  m_nextIndex = std::numeric_limits<memory_size_type>::max();
120  m_index = std::numeric_limits<memory_size_type>::max();
121 
122  m_block.size = 0;
123  m_block.number = std::numeric_limits<stream_size_type>::max();
124  m_block.dirty = false;
125  m_block.data = tpie_new_array<char>(m_blockItems * m_itemSize);
126 
127  initialize();
128  seek(0);
129  }
130 
134  void get_block(stream_size_type block);
135 
139  inline void flush_block() {
140  if (m_block.dirty) {
141  assert(m_canWrite);
142  update_vars();
143  m_fileAccessor->write_block(m_block.data, m_block.number, m_block.size);
144  if (m_tempFile)
145  m_tempFile->update_recorded_size(m_fileAccessor->byte_size());
146  }
147  m_block.dirty = false;
148  }
149 
150  inline void update_vars() {
151  if (m_block.dirty && m_index != std::numeric_limits<memory_size_type>::max()) {
152  assert(m_index <= m_blockItems);
153  m_block.size = std::max(m_block.size, m_index);
154  m_size = std::max(m_size, static_cast<stream_size_type>(m_index)+m_blockStartIndex);
155  }
156  }
157 
158  inline void initialize() {
159  flush_block();
160  s_t::initialize();
161  }
162 
163  inline void write_update() {
164  m_block.dirty = true;
165  }
166 
167 
168  block_t m_block;
169 
170 private:
171  friend class stream_crtp<file_stream_base>;
172  file_stream_base & get_file() {return *this;}
173  const file_stream_base & get_file() const {return *this;}
174  block_t & get_block() {return m_block;}
175  const block_t & get_block() const {return m_block;}
176  void update_block_core();
177 };
178 
179 } // namespace tpie
180 
181 #endif // __TPIE_FILE_STREAM_BASE_H__
stream_size_type m_nextBlock
After a cross-block seek: Block index of next block, or maxint if the current block is good enough OR...
Definition: stream_crtp.h:248
cache_hint
Definition: cache_hint.h:28
CRTP base of file_base.
const std::string & path() const
The path of the file opened or the empty string.
stream_size_type offset() const
Calculate the current offset in the stream.
Definition: stream_crtp.h:90
stream_size_type byte_size() const
Size (in bytes) of entire stream as laid out on disk after padding the final block to alignment bound...
memory_size_type m_index
Item index into the current block, or maxint if we don't have a block.
Definition: stream_crtp.h:244
virtual void write_block(const void *data, stream_size_type blockNumber, memory_size_type itemCount)=0
Write the given number of items from the given buffer into the given block.
void truncate(stream_size_type size)
Truncate file to given size.
memory_size_type m_nextIndex
After a cross-block seek: Item index into next block.
Definition: stream_crtp.h:251
Base class of classes that access files.
void seek(stream_offset_type offset, offset_type whence=beginning)
Moves the logical offset in the stream.
Definition: stream_crtp.h:50
void flush_block()
Write block to disk.
CRTP base of file::stream and file_stream.
access_type
Type describing how we wish to access a file.
Definition: access_type.h:29
stream_size_type m_blockStartIndex
The file-level item index of the first item in the current block.
Definition: stream_crtp.h:255
void get_block(stream_size_type block)
Use file_accessor to fetch indicated block number into m_block.
stream_size_type size() const
Get the size of the file measured in items.
Definition: stream_crtp.h:132
void close()
Close the file and release resources.
void tpie_delete_array(T *a, size_t size)
Delete an array allocated with tpie_new_array.
Definition: memory.h:319