VR-Forces 5.0.2 Developer's Guide
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
DtReusableMemoryVector.h
Go to the documentation of this file.
1 /*****************************************************************************
2  * Copyright (c) 2020 MAK Technologies, Inc.
3  * All rights reserved.
4  *****************************************************************************/
5 
9 #pragma once
10 
11 #include <list>
12 #include <vector>
13 #include <iostream>
14 
16 
17 namespace makVrv
18 {
19  class DtNullRemoval{};
20 
21  template<class T, class I, class R = DtNullRemoval>
22  // A vector allowing allocation/de-allocation/reuse of blocks of arbitrary size
23  // Internally uses a vector.
24  // Invalidated memory(range) is tracked and added to 'free' blocks.
25  // When a request for a size comes in, will attempt to satisfy the request
26  // by finding a 'free' block of that size and update/re-arrange the free blocks
27  // accordingly.
28  // If size requested is size of free block, that block is erased.
29  // If size requested > size of free block, that block's remainder free memory start, end
30  // is updated to reflect the new 'free' block.
32  {
33  public:
38  public:
41  int findFreeBlock(const size_t sizeRequired);
42 
47  std::pair<int, int> remove(const R& removalPredicate);
48 
50  void removeIndices(int startIndex, int endIndex);
51 
53  void printFreeBlocks(void);
54 
56  size_t size(void) const;
57 
59  const T& operator[](int index) const;
60 
62  T& operator[](int index);
63 
65  void reserve(size_t reserveSize);
66 
68  const T* data(void) const;
69 
71  void updateFreeBlocks(int startIndex, int endIndex);
72 
73  protected:
75  struct Block
76  {
78  size_t size;
79  };
80 
81  typedef std::list<Block> ListFreeBlocks;
82 
84 
86 
87  typedef std::vector<T> VectorOfTs;
89  };
90 
91 
92  template<class T, class I, class R>
94  {
95  //intentional nop
96  }
97  template<class T, class I, class R>
99  {
100  //intentional nop
101  }
102 
103  template<class T, class I, class R>
104  int DtReusableMemoryVector<T, I, R>::findFreeBlock(const size_t sizeRequired)
105  {
106  int startIndex = -1;
107  for (typename ListFreeBlocks::iterator it = myListFreeBlocks.begin(); it != myListFreeBlocks.end(); ++it)
108  {
109  Block& block = *it;
110  if (sizeRequired <= block.size)
111  {
112  startIndex = block.startIndex;
113  if (block.size == sizeRequired)
114  {
115  myListFreeBlocks.erase(it);
116  }
117  else
118  {
119  block.startIndex = startIndex + sizeRequired;
120  block.size = block.size - sizeRequired;
121 
122  }
123  break;
124  }
125  }
126 
127  if (startIndex == -1)
128  {
129  T info;
130  myInitializerForT(info);
131 
132  startIndex = myVectorOfTs.size();
133  myVectorOfTs.resize(myVectorOfTs.size() + sizeRequired, info);
134  }
135 
136  return startIndex;
137  }
138 
139  template<class T, class I, class R>
141  {
142  std::cout << "free blocks: start" << std::endl;
143  for (typename ListFreeBlocks::iterator it = myListFreeBlocks.begin(); it != myListFreeBlocks.end(); ++it)
144  {
145  std::cout << "block: start: " << it->startIndex << " size: " << it->size << std::endl;
146  }
147  std::cout << "free blocks: end" << std::endl << std::endl;
148  }
149 
150  template<class T, class I, class R>
152  {
153  return myVectorOfTs.size();
154  }
155 
156  template<class T, class I, class R>
158  {
159  return myVectorOfTs[index];
160  }
161 
162  template<class T, class I, class R>
164  {
165  return myVectorOfTs[index];
166  }
167 
168  template<class T, class I, class R>
169  std::pair<int,int> DtReusableMemoryVector<T, I, R>::DtReusableMemoryVector::remove(const R& removalPredicate)
170  {
171  int index = 0;
172  int startIndex = -1;
173  int endIndex = -1;
174  bool removalStarted = false;
175  for (typename VectorOfTs::iterator it = myVectorOfTs.begin(); it != myVectorOfTs.end(); ++it, ++index)
176  {
177  T& info = *it;
178  if (removalPredicate(info))
179  {
180  if (removalStarted == false)
181  {
182  removalStarted = true;
183  startIndex = index;
184  }
185  if (removalStarted)
186  {
187  endIndex = index;
188  }
189  myInitializerForT(info);
190  }
191  }
192 
193  ASSERT_PREDICATE(startIndex < (int)myVectorOfTs.size());
194  if(!(startIndex < (int)myVectorOfTs.size()))
195  {
196  std::cout << "start index not valid!!"<<std::endl;
197  }
198 
199  ASSERT_PREDICATE(endIndex < (int)myVectorOfTs.size());
200  if(!(endIndex < (int)myVectorOfTs.size()))
201  {
202  std::cout << "end index not valid!!" << std::endl;
203  }
204 
205  updateFreeBlocks(startIndex, endIndex);
206 
207  std::pair<int, int> startAndEnd;
208  startAndEnd.first = startIndex;
209  startAndEnd.second = endIndex;
210 
211  return startAndEnd;
212  }
213 
214  template<class T, class I, class R>
215  void DtReusableMemoryVector<T, I, R>::DtReusableMemoryVector::removeIndices(int startIndex, int endIndex)
216  {
217  ASSERT_PREDICATE(startIndex < (int)myVectorOfTs.size());
218  if (!(startIndex < (int)myVectorOfTs.size()))
219  {
220  std::cout << "start index not valid!!" << std::endl;
221  }
222 
223  ASSERT_PREDICATE(endIndex < (int)myVectorOfTs.size());
224  if (!(endIndex < (int)myVectorOfTs.size()))
225  {
226  std::cout << "end index not valid!!" << std::endl;
227  }
228 
229  for(int currIndex = startIndex; currIndex<=endIndex; ++currIndex)
230  {
231  T& info = myVectorOfTs[currIndex];
232  myInitializerForT(info);
233  }
234 
235  updateFreeBlocks(startIndex, endIndex);
236  }
237 
238  template<class T, class I, class R>
240  {
241  myVectorOfTs.reserve(reserveSize);
242  }
243 
244  template<class T, class I, class R>
246  {
247  return myVectorOfTs.data();
248  }
249 
250  template<class T, class I, class R>
251  void DtReusableMemoryVector<T, I, R>::updateFreeBlocks(int startIndex, int endIndex)
252  {
253  Block block;
254  block.startIndex = startIndex;
255  block.size = endIndex - startIndex + 1;
256 
257  //Find out if this new free block should combine with other free blocks
258  for (auto freeBlockItr = myListFreeBlocks.begin(); freeBlockItr != myListFreeBlocks.end();)
259  {
260  auto nextItr = freeBlockItr;
261  ++nextItr;
262  Block& freeBlock = *freeBlockItr;
263  if (freeBlock.startIndex + freeBlock.size == startIndex)
264  {
265  freeBlock.size = freeBlock.size + block.size;
266  block = freeBlock;
267  myListFreeBlocks.erase(freeBlockItr);
268  }
269  else if (block.startIndex + block.size == freeBlock.startIndex)
270  {
271  freeBlock.size = freeBlock.size + block.size;
272  freeBlock.startIndex = block.startIndex;
273  block = freeBlock;
274  myListFreeBlocks.erase(freeBlockItr);
275  }
276  freeBlockItr = nextItr;
277  }
278 
279  myListFreeBlocks.insert(myListFreeBlocks.end(), block);
280  }
281 
282 }
std::vector< T > VectorOfTs
Definition: DtReusableMemoryVector.h:87
std::list< Block > ListFreeBlocks
Definition: DtReusableMemoryVector.h:81
size_t size
Definition: DtReusableMemoryVector.h:78
DtReusableMemoryVector()
constructor
Definition: DtReusableMemoryVector.h:93
~DtReusableMemoryVector()
destructor
Definition: DtReusableMemoryVector.h:98
void printFreeBlocks(void)
debug printout of the free blocks that are available
Definition: DtReusableMemoryVector.h:140
VectorOfTs myVectorOfTs
Definition: DtReusableMemoryVector.h:88
ListFreeBlocks myListFreeBlocks
Definition: DtReusableMemoryVector.h:83
void removeIndices(int startIndex, int endIndex)
remove a range of indices, inclusive
size_t size(void) const
current size of the vector
Definition: DtReusableMemoryVector.h:151
int startIndex
Definition: DtReusableMemoryVector.h:77
void reserve(size_t reserveSize)
reserve a block of memory for this vector of a specific size
Definition: DtReusableMemoryVector.h:239
int findFreeBlock(const size_t sizeRequired)
get an available free block or add one to the end of the vector if one is not available ...
Definition: DtReusableMemoryVector.h:104
const T & operator[](int index) const
access an element in the vector via index
Definition: DtReusableMemoryVector.h:157
Definition: DtReusableMemoryVector.h:31
block of free data in the vector
Definition: DtReusableMemoryVector.h:75
#define ASSERT_PREDICATE(p)
Definition: DtAssert.h:28
assert macros
I myInitializerForT
Definition: DtReusableMemoryVector.h:85
const T * data(void) const
get the pointer to the raw data in the vector
Definition: DtReusableMemoryVector.h:245
Definition: DtReusableMemoryVector.h:19
void updateFreeBlocks(int startIndex, int endIndex)
add a new free block or combine it with free blocks already in the list
Definition: DtReusableMemoryVector.h:251

Document ID: Generated on Sun Dec 4 20:22:03 EST 2022 from SVN revision 249613
Copyright © 2005-2021 MAK Technologies. All Rights Reserved (www.mak.com)