fsa.h
Go to the documentation of this file.
1 /*
2 
3 A* Algorithm Implementation using STL is
4 Copyright (C)2001-2005 Justin Heyes-Jones
5 
6 Permission is given by the author to freely redistribute and
7 include this code in any program as long as this credit is
8 given where due.
9 
10  COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS,
11  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
12  INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE
13  IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
14  OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND
15  PERFORMANCE OF THE COVERED CODE IS WITH YOU. SHOULD ANY COVERED
16  CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL
17  DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY
18  NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF
19  WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE
20  OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
21  THIS DISCLAIMER.
22 
23  Use at your own risk!
24 
25 
26 
27  FixedSizeAllocator class
28  Copyright 2001 Justin Heyes-Jones
29 
30  This class is a constant time O(1) memory manager for objects of
31  a specified type. The type is specified using a template class.
32 
33  Memory is allocated from a fixed size buffer which you can specify in the
34  class constructor or use the default.
35 
36  Using GetFirst and GetNext it is possible to iterate through the elements
37  one by one, and this would be the most common use for the class.
38 
39  I would suggest using this class when you want O(1) add and delete
40  and you don't do much searching, which would be O(n). Structures such as binary
41  trees can be used instead to get O(logn) access time.
42 
43 */
44 
45 #ifndef FSA_H
46 #define FSA_H
47 
48 #include <string.h>
49 #include <stdio.h>
50 
51 template <class USER_TYPE> class FixedSizeAllocator {
52 public:
53  // Constants
54  enum { FSA_DEFAULT_SIZE = 100 };
55 
56  // This class enables us to transparently manage the extra data
57  // needed to enable the user class to form part of the double-linked
58  // list class
59  struct FSA_ELEMENT {
60  USER_TYPE UserType;
61 
64  };
65 
66 private:
68 public: // methods
69  explicit FixedSizeAllocator(unsigned int MaxElements = FSA_DEFAULT_SIZE)
70  : m_MaxElements(MaxElements), m_pFirstUsed(NULL)
71  {
72  // Allocate enough memory for the maximum number of elements
73 
74  m_pMemory = new char[m_MaxElements];
75 
76  // Set the free list first pointer
78 
79  // Clear the memory
80  memset(m_pMemory, 0, sizeof(FSA_ELEMENT) * m_MaxElements);
81 
82  // Point at first element
83  FSA_ELEMENT *pElement = m_pFirstFree;
84 
85  // Set the double linked free list
86  for (unsigned int i = 0; i < m_MaxElements; i++) {
87  pElement->pPrev = pElement - 1;
88  pElement->pNext = pElement + 1;
89 
90  pElement++;
91  }
92 
93  // first element should have a null prev
94  m_pFirstFree->pPrev = NULL;
95  // last element should have a null next
96  (pElement - 1)->pNext = NULL;
97  }
98 
100  {
101  // Free up the memory
102  delete[] m_pMemory;
103  }
104 
105  // Allocate a new USER_TYPE and return a pointer to it
106  USER_TYPE *alloc()
107  {
108  FSA_ELEMENT *pNewNode = NULL;
109 
110  if (!m_pFirstFree) {
111  return NULL;
112  } else {
113  pNewNode = m_pFirstFree;
114  m_pFirstFree = pNewNode->pNext;
115 
116  // if the new node points to another free node then
117  // change that nodes prev free pointer...
118  if (pNewNode->pNext) {
119  pNewNode->pNext->pPrev = NULL;
120  }
121 
122  // node is now on the used list
123 
124  pNewNode->pPrev = NULL; // the allocated node is always first in the list
125 
126  if (m_pFirstUsed == NULL) {
127  pNewNode->pNext = NULL; // no other nodes
128  } else {
129  m_pFirstUsed->pPrev = pNewNode; // insert this at the head of the used list
130  pNewNode->pNext = m_pFirstUsed;
131  }
132 
133  m_pFirstUsed = pNewNode;
134  }
135 
136  return reinterpret_cast<USER_TYPE *>(pNewNode);
137  }
138 
139  // Free the given user type
140  // For efficiency I don't check whether the user_data is a valid
141  // pointer that was allocated. I may add some debug only checking
142  // (To add the debug check you'd need to make sure the pointer is in
143  // the m_pMemory area and is pointing at the start of a node)
144  void free(USER_TYPE *user_data)
145  {
146  FSA_ELEMENT *pNode = reinterpret_cast<FSA_ELEMENT *>(user_data);
147 
148  // manage used list, remove this node from it
149  if (pNode->pPrev) {
150  pNode->pPrev->pNext = pNode->pNext;
151  } else {
152  // this handles the case that we delete the first node in the used list
153  m_pFirstUsed = pNode->pNext;
154  }
155 
156  if (pNode->pNext) {
157  pNode->pNext->pPrev = pNode->pPrev;
158  }
159 
160  // add to free list
161  if (m_pFirstFree == NULL) {
162  // free list was empty
163  m_pFirstFree = pNode;
164  pNode->pPrev = NULL;
165  pNode->pNext = NULL;
166  } else {
167  // Add this node at the start of the free list
168  m_pFirstFree->pPrev = pNode;
169  pNode->pNext = m_pFirstFree;
170  m_pFirstFree = pNode;
171  }
172  }
173 
174  // For debugging this displays both lists (using the prev/next list pointers)
175  void Debug()
176  {
177  printf("free list ");
178 
180  while (p) {
181  printf("%p!%p ", p->pPrev, p->pNext);
182  p = p->pNext;
183  }
184  printf("\n");
185 
186  printf("used list ");
187 
188  p = m_pFirstUsed;
189  while (p) {
190  printf("%p!%p ", p->pPrev, p->pNext);
191  p = p->pNext;
192  }
193  printf("\n");
194  }
195 
196  // Iterators
197 
198  USER_TYPE *GetFirst() { return reinterpret_cast<USER_TYPE *>(m_pFirstUsed); }
199  USER_TYPE *GetNext(USER_TYPE *node)
200  {
201  return reinterpret_cast<USER_TYPE *>((reinterpret_cast<FSA_ELEMENT *>(node))->pNext);
202  }
203 
204 public: // data
205 private: // methods
206 private: // data
209  unsigned int m_MaxElements;
211 };
212 
213 #endif // defined FSA_H
USER_TYPE * GetNext(USER_TYPE *node)
Definition: fsa.h:199
FSA_ELEMENT * m_pFirstFree
Definition: fsa.h:207
void Debug()
Definition: fsa.h:175
FixedSizeAllocator(unsigned int MaxElements=FSA_DEFAULT_SIZE)
Definition: fsa.h:69
USER_TYPE * alloc()
Definition: fsa.h:106
FixedSizeAllocator(const FixedSizeAllocator &)
Definition: fsa.h:67
FSA_ELEMENT * m_pFirstUsed
Definition: fsa.h:208
unsigned int m_MaxElements
Definition: fsa.h:209
~FixedSizeAllocator()
Definition: fsa.h:99
USER_TYPE * GetFirst()
Definition: fsa.h:198
FSA_ELEMENT * m_pMemory
Definition: fsa.h:210
void free(USER_TYPE *user_data)
Definition: fsa.h:144
FSA_ELEMENT * pPrev
Definition: fsa.h:62
FSA_ELEMENT * pNext
Definition: fsa.h:63


stage
Author(s): Richard Vaughan , Brian Gerkey , Reed Hedges , Andrew Howard , Toby Collett , Pooya Karimian , Jeremy Asher , Alex Couture-Beil , Geoff Biggs , Rich Mattes , Abbas Sadat
autogenerated on Mon Feb 28 2022 23:48:55