TPIE

11a2c2d
file_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 2009, 2011, 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_BASE_H__
25 #define __TPIE_FILE_BASE_H__
26 
27 #include <tpie/tpie_export.h>
28 #include <tpie/file_base_crtp.h>
29 #include <tpie/stream_crtp.h>
30 #include <tpie/exception.h>
32 #ifndef WIN32
34 #else
35 #include <tpie/file_accessor/win32.h>
36 #endif //WIN32
37 #include <boost/intrusive/list.hpp>
38 #include <tpie/tempname.h>
39 #include <memory>
40 #include <tpie/memory.h>
41 #include <tpie/cache_hint.h>
42 #include <tpie/access_type.h>
43 #include <tpie/types.h>
44 #include <algorithm>
45 
46 namespace tpie {
47 
48 class TPIE_EXPORT file_base: public file_base_crtp<file_base> {
50 protected:
55 #ifdef WIN32
56 #pragma warning( push )
57 #pragma warning( disable : 4200 )
58 #endif
59  struct block_t : public boost::intrusive::list_base_hook<> {
60  memory_size_type size;
61  memory_size_type usage;
62  stream_size_type number;
63  bool dirty;
64  char data[0];
65  };
66 #ifdef WIN32
67 #pragma warning( pop )
68 #endif
69 
70  inline void update_size(stream_size_type size) {
71  m_size = std::max(m_size, size);
72  if (m_tempFile)
73  m_tempFile->update_recorded_size(m_fileAccessor->byte_size());
74  }
75 
76 public:
77  inline stream_size_type size() const throw() {
78  return file_size();
79  }
80 
81  void close();
82 
86  class stream: public stream_crtp<stream> {
87  private:
88  typedef stream_crtp<stream> p_t;
89 
90  friend class stream_crtp<stream>;
91 
93  file_base * m_file;
94 
95  protected:
96  block_t & get_block() {return *m_block;}
97  const block_t & get_block() const {return *m_block;}
98  inline file_base & get_file() {assert(m_file != 0); return *m_file;}
99  inline const file_base & get_file() const {assert(m_file != 0); return *m_file;}
100 
101  void update_block_core();
102 
103  inline void update_vars() {}
104 
108 
109  public:
113  inline bool attached() const { return 0 != m_file; }
114 
115  protected:
119  void attach_inner(file_base & f);
120 
124  void detach_inner();
125 
126  public:
130  inline memory_size_type block_items() const {return get_file().m_blockItems;}
131 
132  protected:
140  inline void write_update() {
141  m_block->dirty = true;
142  m_block->size = std::max(m_block->size, m_index);
143  get_file().update_size(static_cast<stream_size_type>(m_index)+m_blockStartIndex);
144  }
145 
146  public:
152  stream(file_base & file, stream_size_type offset=0);
153 
154  stream() : m_file(0) {}
155 
156  private:
160  void free();
161 
162  public:
163  inline ~stream() {free();}
164 
165 
166  protected:
170  inline void initialize() {
171  if (m_block != &get_file().m_emptyBlock) get_file().free_block(m_block);
172  p_t::initialize();
173  m_block = &get_file().m_emptyBlock;
174  }
175  };
176 
181  void truncate(stream_size_type s) {
182  assert(m_open);
183  if (!m_used.empty()) {
184  throw io_exception("Tried to truncate a file with one or more open streams");
185  }
186  m_size = s;
187  m_fileAccessor->truncate(s);
188  if (m_tempFile)
189  m_tempFile->update_recorded_size(m_fileAccessor->byte_size());
190  }
191 
195  ~file_base();
196 
197 
198 protected:
199  file_base(memory_size_type item_size,
200  double blockFactor=1.0,
201  file_accessor::file_accessor * fileAccessor=NULL);
202 
203  void create_block();
204  void delete_block();
205  block_t * get_block(stream_size_type block);
206  void free_block(block_t * block);
207 
208 
209  static block_t m_emptyBlock;
210  // TODO This should really be a hash map
211  boost::intrusive::list<block_t> m_used;
212  boost::intrusive::list<block_t> m_free;
213 };
214 
215 } // namespace tpie
216 
217 #endif //__TPIE_FILE_BASE_H__
tpie::file_base::stream::write_update
void write_update()
Call whenever the current block buffer is modified.
Definition: file_base.h:140
stream_crtp.h
tpie::file_base::block_t
This is the type of our block buffers.
Definition: file_base.h:59
tpie::file
Central file abstraction.
Definition: file.h:39
types.h
cache_hint.h
tpie::file_base::stream::block_items
memory_size_type block_items() const
Fetch number of items per block.
Definition: file_base.h:130
file_accessor.h
tempname.h
tpie::file_base::stream::m_block
block_t * m_block
Current block.
Definition: file_base.h:107
tpie::stream_crtp
Definition: stream_crtp.h:36
tpie::file_base::truncate
void truncate(stream_size_type s)
Truncate file to given size.
Definition: file_base.h:181
tpie::file_base_crtp
Base class of classes that access files.
Definition: file_base_crtp.h:50
tpie::file_accessor::stream_accessor_base
Definition: stream_accessor_base.h:34
file_base_crtp.h
tpie::file_base::stream::attached
bool attached() const
True if we are attached to a tpie::file.
Definition: file_base.h:113
exception.h
tpie::file_base::stream::initialize
void initialize()
Set up block buffers and offsets.
Definition: file_base.h:170
tpie::file_base::stream
Stream in file. We support multiple streams per file.
Definition: file_base.h:86
tpie::io_exception
Definition: exception.h:50
tpie::file_base
Definition: file_base.h:48
posix.h
memory.h
access_type.h
tpie
Definition: access_type.h:26