Xalan-C++ API Documentation

The Xalan C++ XSLT Processor Version 1.11


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

Interpreting class diagrams

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

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

Apache Logo