Xalan-C++ API Documentation

The Xalan C++ XSLT Processor Version 1.10

XalanArrayAllocator.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 1999-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #if !defined(XALANARRAYALLOCATOR_HEADER_GUARD_1357924680)
17 #define XALANARRAYALLOCATOR_HEADER_GUARD_1357924680
18 
19 
20 
22 
23 
24 
25 #include <cassert>
26 #include <utility>
27 
28 
32 
33 
34 
35 XALAN_CPP_NAMESPACE_BEGIN
36 
37 
38 
39 template<class Type>
41 {
42 public:
43 
45  typedef typename VectorType::size_type size_type;
46 
47  typedef XALAN_STD_QUALIFIER pair<size_type, VectorType * > ListEntryType;
49 
50  typedef Type value_type;
51 
53 
54  // Default size for vector allocation.
55  enum { eDefaultBlockSize = 500 };
56 
63  size_type theBlockSize = eDefaultBlockSize) :
64  m_list(theManager),
65  m_blockSize(theBlockSize),
66  m_lastEntryFound(0)
67  {
68  }
69 
71  {
72  typename ListType::iterator iter = m_list.begin();
73 
74  MemoryManagerType& theManager = m_list.getMemoryManager();
75 
76  for( iter = m_list.begin(); iter != m_list.end(); ++iter)
77  {
78  if( (*iter).second != 0)
79  {
80 #if defined(XALAN_REQUIRES_QUALIFIED_DESTRUCTOR)
81  (*iter).second->VectorType::~VectorType();
82 #else
83  (*iter).second->~VectorType();
84 #endif
85  theManager.deallocate((void*)(*iter).second);
86  }
87  }
88  }
89 
93  void
95  {
96  m_list.clear();
97 
98  m_lastEntryFound = 0;
99  }
100 
106  void
108  {
109  if (m_list.empty() == true)
110  {
111  m_lastEntryFound = 0;
112  }
113  else
114  {
115  const ListIteratorType theEnd = m_list.end();
116  ListIteratorType theCurrent = m_list.begin();
117 
118  do
119  {
120  (*theCurrent).first = (*theCurrent).second->size();
121 
122  ++theCurrent;
123  } while(theCurrent != theEnd);
124 
125  m_lastEntryFound = &*m_list.begin();
126  }
127  }
128 
135  Type*
136  allocate(size_type theCount)
137  {
138  // Handle the case of theCount being greater than the block size first...
139  if (theCount >= m_blockSize)
140  {
141  return createEntry(theCount, theCount);
142  }
143  else
144  {
145  ListEntryType* theEntry =
146  findEntry(theCount);
147 
148  // Did we find a slot?
149  if (theEntry == 0)
150  {
151  // Nope, create a new one...
152  return createEntry(m_blockSize, theCount);
153  }
154  else
155  {
156  // The address we want is that of the first free element in the
157  // vector...
158  assert( theEntry->second != 0);
159  Type* const thePointer =
160  &*theEntry->second->begin() + (theEntry->second->size() - theEntry->first);
161 
162  // Resize the vector to the appropriate size...
163  theEntry->first -= theCount;
164 
165  return thePointer;
166  }
167  }
168  }
169 
170 private:
171 
172  // Utility functions...
173  Type*
174  createEntry(
175  size_type theBlockSize,
176  size_type theCount)
177  {
178  assert(theBlockSize >= theCount);
179 
180  // Push on a new entry. The entry has no open space,
181  // since it's greater than our block size...
182  m_list.push_back(ListEntryType(0, VectorType::create(m_list.getMemoryManager())));
183 
184  // Get the new entry...
185  ListEntryType& theNewEntry = m_list.back();
186 
187  // Resize the vector to the appropriate size...
188  assert(theNewEntry.second);
189 
190  theNewEntry.second->resize(theBlockSize, value_type());
191 
192  // Set the number of free spaces accordingly...
193  theNewEntry.first = theBlockSize - theCount;
194 
195  if (theNewEntry.first != 0)
196  {
197  m_lastEntryFound = &theNewEntry;
198  }
199 
200  // Return a pointer to the beginning of the allocated memory...
201  return &*theNewEntry.second->begin();
202  }
203 
204  ListEntryType*
205  findEntry(size_type theCount)
206  {
207  // Search for an entry that has some free space.
208 
209  if (m_lastEntryFound != 0 && m_lastEntryFound->first >= theCount)
210  {
211  return m_lastEntryFound;
212  }
213  else
214  {
215  const ListIteratorType theEnd = m_list.end();
216  ListIteratorType theCurrent = m_list.begin();
217 
218  ListEntryType* theEntry = 0;
219 
220  while(theCurrent != theEnd)
221  {
222  // We're looking for the best fit, so
223  // if the free space and the count we're
224  // looking for are equal, that's pretty
225  // much the best we can do...
226  if ((*theCurrent).first == theCount)
227  {
228  theEntry = &*theCurrent;
229 
230  break;
231  }
232  else if ((*theCurrent).first >= theCount)
233  {
234  // If we haven't found anything yet, the first
235  // entry we find that's large enough becomes
236  // our best fit.
237  //
238  // Otherwise, we'll assume that a smaller
239  // slot is a better fit, though I may be
240  // wrong about this...
241  if (theEntry == 0 ||
242  (*theCurrent).first < theEntry->first)
243  {
244  // Nope, so this becomes our best-fit so far.
245  theEntry = &*theCurrent;
246  }
247 
248  ++theCurrent;
249  }
250  else
251  {
252  // Won't fit, so just continue...
253  ++theCurrent;
254  }
255  }
256 
257  m_lastEntryFound = theEntry;
258 
259  return theEntry;
260  }
261  }
262 
263  // Not implemented...
265 
267  operator=(const XalanArrayAllocator<Type>& theSource);
268 
269  bool
270  operator==(const XalanArrayAllocator<Type>& theRHS) const;
271 
272 
273  // Data members...
274  ListType m_list;
275 
276  const size_type m_blockSize;
277 
278  ListEntryType* m_lastEntryFound;
279 };
280 
281 
282 
283 XALAN_CPP_NAMESPACE_END
284 
285 
286 
287 #endif // !defined(XALANARRAYALLOCATOR_HEADER_GUARD_1357924680)
bool operator==(const XalanVector< Type > &theLHS, const XalanVector< Type > &theRHS)
Definition: XalanVector.hpp:1111
~XalanArrayAllocator()
Definition: XalanArrayAllocator.hpp:70
VectorType::size_type size_type
Definition: XalanArrayAllocator.hpp:45
XalanList< ListEntryType > ListType
Definition: XalanArrayAllocator.hpp:48
XALAN_CPP_NAMESPACE_BEGIN typedef XERCES_CPP_NAMESPACE_QUALIFIER MemoryManager MemoryManagerType
Definition: XalanMemoryManagement.hpp:39
ListType::iterator ListIteratorType
Definition: XalanArrayAllocator.hpp:52
void clear()
Clear the instance, and release all allocated memory.
Definition: XalanArrayAllocator.hpp:94
Type value_type
Definition: XalanArrayAllocator.hpp:50
XALAN_CPP_NAMESPACE_BEGIN typedef size_t size_type
Definition: XalanMap.hpp:44
XalanArrayAllocator(MemoryManagerType &theManager, size_type theBlockSize=eDefaultBlockSize)
Constructor.
Definition: XalanArrayAllocator.hpp:62
XALAN_STD_QUALIFIER pair< size_type, VectorType * > ListEntryType
Definition: XalanArrayAllocator.hpp:47
Definition: XalanArrayAllocator.hpp:40
XalanVector< Type > VectorType
Definition: XalanArrayAllocator.hpp:44
size_t size_type
Definition: XalanVector.hpp:71
#define XALAN_PLATFORMSUPPORT_EXPORT
Definition: PlatformSupportDefinitions.hpp:33
Definition: XalanList.hpp:65
Definition: XalanVector.hpp:61
void reset()
Reset the instance, but keep all memory so it can be reused for allocations.
Definition: XalanArrayAllocator.hpp:107
Type * allocate(size_type theCount)
Allocate slots for the given number of Types instance and return the address of the slots...
Definition: XalanArrayAllocator.hpp:136

Interpreting class diagrams

Doxygen and GraphViz are used to generate this API documentation from the Xalan-C header files.

dot

Xalan-C++ XSLT Processor Version 1.10
Copyright © 1999-2004 The Apache Software Foundation. All Rights Reserved.

Apache Logo