TPIE

v1.1rc1-6-g0c97303
stack.h
Go to the documentation of this file.
1 // -*- mode: c++; tab-width: 4; indent-tabs-mode: t; c-file-style: "stroustrup"; -*-
2 // vi:set ts=4 sts=4 sw=4 noet cino+=(0 :
3 // Copyright 2008, 2011, 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_AMI_STACK_H
25 #define _TPIE_AMI_STACK_H
26 
27 #include <tpie/array.h>
28 #include <tpie/portability.h>
29 #include <tpie/deprecated.h>
30 #include <tpie/stream.h>
31 #include <tpie/tpie_assert.h>
32 
33 namespace tpie {
34 
38 template <typename T>
39 class stack {
40 public:
41 
45  inline stack(double blockFactor = 1.0)
46  : m_file_stream(blockFactor)
47  , m_buffer(buffer_size(blockFactor))
48  , m_bufferItems(0)
49  {
50  m_file_stream.open(static_cast<memory_size_type>(0), access_normal);
51  }
52 
59  inline stack(const std::string& path, double block_factor = 1.0)
60  : m_file_stream(block_factor)
61  , m_buffer(buffer_size(block_factor))
62  , m_bufferItems(0)
63  {
64  m_file_stream.open(path, access_read_write, static_cast<memory_size_type>(0), access_normal);
65 
66  m_file_stream.seek(0, file_stream_base::end);
67  }
68 
75  inline stack(temp_file & tempFile, double block_factor = 1.0)
76  : m_file_stream(block_factor)
77  , m_buffer(buffer_size(block_factor))
78  , m_bufferItems(0)
79  {
80  m_file_stream.open(tempFile, access_read_write,
81  static_cast<memory_size_type>(0), access_normal);
82 
83  m_file_stream.seek(0, file_stream_base::end);
84  }
85 
86 
91  ~stack() {
92  empty_buffer();
93  m_file_stream.truncate(this->size());
94  }
95 
102  inline void push(const T & t) throw(stream_exception) {
103  if (m_buffer.size() == m_bufferItems) empty_buffer();
104  m_buffer[m_bufferItems++] = t;
105  }
106 
110  inline const T & pop() throw(stream_exception) {
111  if (m_bufferItems) return m_buffer[--m_bufferItems];
112  const T & item = m_file_stream.read_back();
113  return item;
114  }
115 
119  inline const T & top() throw(stream_exception) {
120  if (m_bufferItems) return m_buffer[m_bufferItems-1];
121  m_buffer[0] = m_file_stream.read_back();
122  m_file_stream.read();
123  return m_buffer[0];
124  }
125 
129  inline stream_size_type size() const {
130  return m_file_stream.offset()+m_bufferItems;
131  }
132 
136  inline bool empty() const {
137  return size() == 0;
138  }
139 
143  inline static memory_size_type memory_usage(float blockFactor=1.0) {
144  return sizeof(stack<T>)
145  + file_stream<T>::memory_usage(blockFactor)
146  + array<T>::memory_usage(buffer_size(blockFactor));
147  }
148 
149 protected:
150 
153 
154 private:
155  array<T> m_buffer;
156  size_t m_bufferItems;
157 
158  inline void empty_buffer() {
159  if (m_bufferItems == 0) return;
160  m_file_stream.write(m_buffer.begin(), m_buffer.begin()+m_bufferItems);
161  m_bufferItems = 0;
162  }
163 
164  inline static memory_size_type buffer_size(double blockFactor) {
165  return file<T>::block_size(blockFactor)/sizeof(T);
166  }
167 
168 };
169 
170 namespace ami {
171 
175 template<class T>
176 class stack {
177 public:
178 
182  stack() :
183  m_ulate(m_tempFile) {
184  // Empty ctor.
185  }
186 
194  stack(const std::string& path,
195  stream_type type = READ_WRITE_STREAM)
196  : m_tempFile(path, true)
197  , m_ulate(m_tempFile)
198  {
199  unused(type);
200  }
201 
208  err push(const T &t);
209 
218  err pop(const T **t);
219 
228  err peek(const T **t);
229 
233  TPIE_OS_OFFSET size() const {
234  return m_ulate.size();
235  }
236 
240  bool is_empty() const {
241  return m_ulate.empty();
242  }
243 
249  void persist(persistence p) {
250  m_tempFile.set_persistent(p == PERSIST_PERSISTENT);
251  }
252 
257  persistence persist() const {
258  return m_tempFile.is_persistent() ? PERSIST_PERSISTENT : PERSIST_DELETE;
259  }
260 
266  err trim() {
267  return NO_ERROR;
268  }
269 
277  err main_memory_usage(TPIE_OS_SIZE_T *usage,
278  stream_usage usage_type) const;
279 
283  TPIE_OS_OFFSET stream_len() const {
284  TP_LOG_WARNING_ID("Using AMI_stack<T>::stream_len() is deprecated.");
285  return size();
286  }
287 
288 private:
289 
290  temp_file m_tempFile;
291 
292  // em-ulate. get it?
293  tpie::stack<T> m_ulate;
294 };
295 
297 
298 template<class T>
299 err stack<T>::push(const T &t) {
300 
301  err retval = NO_ERROR;
302 
303  try {
304  m_ulate.push(t);
305  } catch (end_of_stream_exception &) {
306  retval = END_OF_STREAM;
307  } catch (stream_exception &) {
308  retval = IO_ERROR;
309  }
310 
311  return retval;
312 
313 }
314 
316 
317 template<class T>
318 err stack<T>::pop(const T **t) {
319 
320  err retval = NO_ERROR;
321 
322  try {
323 
324  const T & res = m_ulate.pop();
325  *t = &res;
326 
327  } catch (end_of_stream_exception &) {
328  retval = END_OF_STREAM;
329  } catch (stream_exception &) {
330  retval = IO_ERROR;
331  }
332 
333  return retval;
334 
335 }
336 
338 
339 template<class T>
340 err stack<T>::peek(const T **t) {
341 
342  err retval = NO_ERROR;
343 
344  try {
345 
346  const T & res = m_ulate.top();
347  *t = &res;
348 
349  } catch (end_of_stream_exception &) {
350  retval = END_OF_STREAM;
351  } catch (stream_exception &) {
352  retval = IO_ERROR;
353  }
354 
355  return retval;
356 
357 }
358 
360 
361 template<class T>
362 err stack<T>::main_memory_usage(TPIE_OS_SIZE_T *usage,
363  stream_usage usage_type) const {
364 
365  switch (usage_type) {
366 
367  // All these types are o.k.
372  case STREAM_USAGE_BUFFER:
373  *usage = tpie::stack<T>::memory_usage();
374  *usage += sizeof(*this);
375  break;
376 
377  default:
378  tp_assert(0, "Unknown mem::stream_usage type added.");
379  }
380 
381  return NO_ERROR;
382 }
383 
385 
386 } // ami namespace
387 
388 } // tpie namespace
389 
390 #endif // _TPIE_AMI_STACK_H
Defines the tp_assert macro.
stack()
Initializes the stack.
Definition: stack.h:182
Amount currently in use.
Definition: stream_usage.h:34
Maximum additional amount used by each substream created.
Definition: stream_usage.h:38
PERSIST_DELETE
Delete the stream from the disk when it is destructed.
Definition: persist.h:39
Max amount that will ever be used.
Definition: stream_usage.h:36
file_stream< T > m_file_stream
The file_stream used to store the items.
Definition: stack.h:152
void unused(const T &x)
Declare that a variable is unused on purpose.
Definition: util.h:42
TPIE_OS_OFFSET stream_len() const
Definition: stack.h:283
No error occurred.
Definition: err.h:47
~stack()
Closes the underlying stream and truncates it to the logical end of the stack.
Definition: stack.h:91
const T & pop()
Pops one item from the stack.
Definition: stack.h:110
Macros for deprecating classes, methods and typedefs.
err push(const T &t)
Pushes one item onto the stack.
Definition: stack.h:299
An implementation of an external-memory stack.
Definition: stack.h:39
This file contains a few deprecated definitions for legacy code.
Overhead of the object without the buffer.
Definition: stream_usage.h:30
TPIE_OS_OFFSET size() const
Returns the number of items currently on the stack.
Definition: stack.h:233
void set_persistent(bool p)
Set persistence.
Definition: tempname.h:168
stack(const std::string &path, stream_type type=READ_WRITE_STREAM)
Initializes the stack by (re-)opening the file given.
Definition: stack.h:194
A low level I/O error occurred.
Definition: err.h:49
AMI streams.
Generic internal array with known memory requirements.
persistence persist() const
Returns the persistence status of the (stream underlying the) stack.
Definition: stack.h:257
stack(temp_file &tempFile, double block_factor=1.0)
Initialize temporary stack.
Definition: stack.h:75
stream_size_type size() const
Returns the number of items currently on the stack.
Definition: stack.h:129
void persist(persistence p)
Set the persistence status of the (stream underlying the) stack.
Definition: stack.h:249
Class representing the existence of a temporary file.
Definition: tempname.h:152
err trim()
Truncates the underlying stream to the exact size (rounded up to the next block) of items...
Definition: stack.h:266
An implementation of an external-memory stack compatible with the old AMI interface.
Definition: stack.h:176
stream_type
AMI stream types passed to constructors.
Definition: stream.h:52
memory_size_type block_size() const
Get the size of a block in bytes.
PERSIST_PERSISTENT
Do not delete the stream from the disk when it is destructed.
Definition: persist.h:41
bool is_empty() const
Returns whether the stack is empty or not.
Definition: stack.h:240
bool is_persistent() const
Definition: tempname.h:162
err pop(const T **t)
Pops one item from the stack.
Definition: stack.h:318
bool empty() const
Returns whether the stack is empty or not.
Definition: stack.h:136
Simple class acting both as file and a file::stream.
Definition: file_stream.h:44
err
Legacy TPIE error codes.
Definition: err.h:45
void push(const T &t)
Pushes one item onto the stack.
Definition: stack.h:102
static memory_size_type memory_usage(float blockFactor=1.0)
Compute the memory used by a stack.
Definition: stack.h:143
iterator begin()
Return an iterator to the beginning of the array.
Definition: array.h:274
stack(double blockFactor=1.0)
Initialize anonymous stack.
Definition: stack.h:45
size_type size() const
Return the size of the array.
Definition: array.h:472
const T & top()
Peeks at the topmost item on the stack.
Definition: stack.h:119
#define tp_assert(condition, message)
Definition: tpie_assert.h:47
stack(const std::string &path, double block_factor=1.0)
Initialize named, nontemporary stack.
Definition: stack.h:59
static stream_size_type memory_usage(stream_size_type size)
Return the number of bytes required to create a data structure supporting a given number of elements...
Definition: util.h:81
stream_usage
Definition: stream_usage.h:28
Neither sequential access nor random access is intended.
Definition: cache_hint.h:31
An attempt was made to read past the end of a stream or write past the end of a substream.
Definition: err.h:52
err main_memory_usage(TPIE_OS_SIZE_T *usage, stream_usage usage_type) const
Compute the memory used by the stack and the aggregated stream.
Definition: stack.h:362
Max amount ever used by a buffer.
Definition: stream_usage.h:32
err peek(const T **t)
Peeks at the topmost item on the stack.
Definition: stack.h:340
Open a file for reading or writing.
Definition: access_type.h:35