Loading [MathJax]/extensions/tex2jax.js
Free Electron
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
geodesic_cpp_mod/geodesic_memory.h
1 //Copyright (C) 2008 Danil Kirsanov, MIT License
2 #ifndef _GEODESIC_MEMORY_20071231
3 #define _GEODESIC_MEMORY_20071231
4 
5 //two fast and simple memory allocators
6 
7 #include <vector>
8 #include <math.h>
9 
10 namespace geodesic{
11 
12 template<class T> //quickly allocates multiple elements of a given type; no deallocation
13 class SimlpeMemoryAllocator
14 {
15 public:
16  typedef T* pointer;
17 
18  SimlpeMemoryAllocator(unsigned block_size = 0,
19  unsigned max_number_of_blocks = 0)
20  {
21  reset(block_size,
22  max_number_of_blocks);
23  };
24 
25  ~SimlpeMemoryAllocator(){};
26 
27  void reset(unsigned block_size,
28  unsigned max_number_of_blocks)
29  {
30  m_block_size = block_size;
31  m_max_number_of_blocks = max_number_of_blocks;
32 
33 
34  m_current_position = 0;
35 
36  m_storage.reserve(max_number_of_blocks);
37  m_storage.resize(1);
38  m_storage[0].resize(block_size);
39  };
40 
41  pointer allocate(unsigned const n) //allocate n units
42  {
43  FEASSERT(n < m_block_size);
44 
45  if(m_current_position + n >= m_block_size)
46  {
47  m_storage.push_back( std::vector<T>() );
48  m_storage.back().resize(m_block_size);
49  m_current_position = 0;
50  }
51  pointer result = & m_storage.back()[m_current_position];
52  m_current_position += n;
53 
54  return result;
55  };
56 private:
57  std::vector<std::vector<T> > m_storage;
58  unsigned m_block_size; //size of a single block
59  unsigned m_max_number_of_blocks; //maximum allowed number of blocks
60  unsigned m_current_position; //first unused element inside the current block
61 };
62 
63 
64 template<class T> //quickly allocates and deallocates single elements of a given type
65 class MemoryAllocator
66 {
67 public:
68  typedef T* pointer;
69 
70  MemoryAllocator(unsigned block_size = 1024,
71  unsigned max_number_of_blocks = 1024)
72  {
73  reset(block_size,
74  max_number_of_blocks);
75  };
76 
77  ~MemoryAllocator(){};
78 
79  void clear()
80  {
81  reset(m_block_size,
82  m_max_number_of_blocks);
83  }
84 
85  void reset(unsigned block_size,
86  unsigned max_number_of_blocks)
87  {
88  m_block_size = block_size;
89  m_max_number_of_blocks = max_number_of_blocks;
90 
91  FEASSERT(m_block_size > 0);
92  FEASSERT(m_max_number_of_blocks > 0);
93 
94  m_current_position = 0;
95 
96  m_storage.reserve(max_number_of_blocks);
97  m_storage.resize(1);
98  m_storage[0].resize(block_size);
99 
100  m_deleted.clear();
101  m_deleted.reserve(2*block_size);
102  };
103 
104  pointer allocate() //allocates single unit of memory
105  {
106  pointer result;
107  if(m_deleted.empty())
108  {
109  if(m_current_position + 1 >= m_block_size)
110  {
111  m_storage.push_back( std::vector<T>() );
112  m_storage.back().resize(m_block_size);
113  m_current_position = 0;
114  }
115  result = & m_storage.back()[m_current_position];
116  ++m_current_position;
117  }
118  else
119  {
120  result = m_deleted.back();
121  m_deleted.pop_back();
122  }
123 
124  return result;
125  };
126 
127  void deallocate(pointer p) //allocate n units
128  {
129  if(m_deleted.size() < m_deleted.capacity())
130  {
131  m_deleted.push_back(p);
132  }
133  };
134 
135 private:
136  std::vector<std::vector<T> > m_storage;
137  unsigned m_block_size; //size of a single block
138  unsigned m_max_number_of_blocks; //maximum allowed number of blocks
139  unsigned m_current_position; //first unused element inside the current block
140 
141  std::vector<pointer> m_deleted; //pointers to deleted elemets
142 };
143 
144 
145 class OutputBuffer
146 {
147 public:
148  OutputBuffer():
149  m_num_bytes(0)
150  {}
151 
152  void clear()
153  {
154  m_num_bytes = 0;
155 #if __cplusplus >= 201103L
156  m_buffer = std::unique_ptr<double>();
157 #else
158  m_buffer = std::auto_ptr<double>();
159 #endif
160  }
161 
162  template<class T>
163  T* allocate(unsigned n)
164  {
165  double wanted = n*sizeof(T);
166  if(wanted > m_num_bytes)
167  {
168  unsigned new_size = (unsigned) ceil(wanted / (double)sizeof(double));
169 #if __cplusplus >= 201103L
170  m_buffer = std::unique_ptr<double>(new double[new_size]);
171 #else
172  m_buffer = std::auto_ptr<double>(new double[new_size]);
173 #endif
174  m_num_bytes = new_size*sizeof(double);
175  }
176 
177  return (T*)m_buffer.get();
178  }
179 
180  template <class T>
181  T* get()
182  {
183  return (T*)m_buffer.get();
184  }
185 
186  template<class T>
187  unsigned capacity()
188  {
189  return (unsigned)floor((double)m_num_bytes/(double)sizeof(T));
190  };
191 
192 private:
193 
194 #if __cplusplus >= 201103L
195  std::unique_ptr<double> m_buffer;
196 #else
197  std::auto_ptr<double> m_buffer;
198 #endif
199  unsigned m_num_bytes;
200 };
201 
202 
203 } //geodesic
204 
205 #endif //_GEODESIC_MEMORY_20071231
Definition: geodesic_cpp_03_02_2008/geodesic_algorithm_base.h:11