Xalan-C++ API Reference  1.12.0
ReusableArenaAllocator.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 
19 #if !defined(REUSABLEARENAALLOCATOR_INCLUDE_GUARD_1357924680)
20 #define REUSABLEARENAALLOCATOR_INCLUDE_GUARD_1357924680
21 
22 
23 
24 #include <algorithm>
25 
26 
27 
28 #include "ReusableArenaBlock.hpp"
29 #include "ArenaAllocator.hpp"
30 
31 
32 
33 namespace XALAN_CPP_NAMESPACE {
34 
35 
36 
37 template<class ObjectType>
38 class ReusableArenaAllocator : public ArenaAllocator<ObjectType,
39  ReusableArenaBlock<ObjectType> >
40 {
41 public:
42 
44 
46 
47  typedef ArenaAllocator<ObjectType,
49 
51 
53 
58 
59 
60  /*
61  * Construct an instance that will allocate blocks of the specified size.
62  *
63  * @param theBlockSize The block size.
64  */
66  MemoryManager& theManager,
67  size_type theBlockSize,
68  bool destroyBlocks = false) :
69  BaseClassType(theManager, theBlockSize),
70  m_destroyBlocks(destroyBlocks)
71  {
72  }
73 
74  virtual
76  {
77  }
78 
79  /*
80  * Destroy the object, and free the block for re-use.
81  *
82  * @param theObject the address of the object.
83  * @return true if the object was deleted, false if not.
84  */
85  bool
86  destroyObject(ObjectType* theObject)
87  {
88  bool bResult = false;
89 
90  assert ( theObject != 0 );
91 
92  if ( this->m_blocks.empty() )
93  return bResult;
94 
95  iterator iTerator = this->m_blocks.begin();
96 
97  iterator iEnd = this->m_blocks.end();
98 
99  // first , run over unfull blocks ( that consentrated from the head )
100  while( iTerator != iEnd
101  && (*iTerator)->blockAvailable() )
102  {
103  if ((*iTerator)->ownsBlock(theObject) == true)
104  {
105  (*iTerator)->destroyObject(theObject);
106 
107  // move the block we have just deleted to the head of the list
108  if (iTerator != this->m_blocks.begin())
109  {
110  // move the block to the beginning
111  ReusableArenaBlockType* block = *iTerator;
112 
113  assert(block != 0);
114 
115  this->m_blocks.erase(iTerator);
116 
117  this->m_blocks.push_front(block);
118  }
119 
120  if (m_destroyBlocks)
121  {
122  destroyBlock();
123  }
124 
125  bResult = true;
126 
127  break;
128  }
129 
130  ++iTerator;
131  }
132 
133  reverse_iterator rIterator = this->m_blocks.rbegin();
134 
135  reverse_iterator rEnd = this->m_blocks.rend();
136 
137  // if the block hasn't been found from the head , start with full blocks ( from the taile)
138  while ( !bResult && rIterator != rEnd )
139  {
140  if ((*rIterator)->ownsBlock(theObject))
141  {
142  (*rIterator)->destroyObject(theObject);
143 
144  if (rIterator != this->m_blocks.rbegin())
145  {
146  // move the block to the beginning
147  ReusableArenaBlockType* block = *iTerator;
148 
149  assert(block != 0);
150 
151  this->m_blocks.erase(iTerator);
152 
153  this->m_blocks.push_front(block);
154 
155  }
156 
157  if (m_destroyBlocks)
158  {
159  destroyBlock();
160  }
161 
162  bResult = true;
163 
164  break;
165  }
166 
167  if ( *rIterator == *iTerator)
168  {
169  break;
170  }
171  else
172  {
173  ++rIterator;
174  }
175  }
176 
177  return bResult;
178  }
179 
180  /*
181  * Allocate a block of the appropriate size for an
182  * object. Call commitAllocation() when after
183  * the object is successfully constructed. You _must_
184  * commit an allocation before performing any other
185  * operation on the allocator.
186  *
187  *
188  * @return A pointer to a block of memory
189  */
190  virtual ObjectType*
192  {
193  if( this->m_blocks.empty()
194  || !this->m_blocks.front()->blockAvailable() )
195  {
196  this->m_blocks.push_front(
197  ReusableArenaBlockType::create(
198  this->getMemoryManager(),
199  this->m_blockSize));
200 
201  assert( this->m_blocks.front() != 0 );
202  }
203 
204  assert( this->m_blocks.front() != 0 );
205  assert( this->m_blocks.front()->blockAvailable() );
206 
207  return this->m_blocks.front()->allocateBlock();
208  }
209 
210  /*
211  * Commits the allocation of the previous
212  * allocateBlock() call.
213  *
214  * @param theObject A pointer to a block of memory
215  */
216  virtual void
217  commitAllocation(ObjectType* theObject)
218  {
219  // Note that this-> is required by template lookup rules.
220  assert( this->m_blocks.empty() == false );
221  assert( this->m_blocks.front() != 0 );
222  assert( this->m_blocks.front()->ownsBlock(theObject) == true );
223 
224  this->m_blocks.front()->commitAllocation(theObject);
225 
226  if( !this->m_blocks.front()->blockAvailable() )
227  {
228  ReusableArenaBlockType* fullBlock = this->m_blocks.front();
229 
230  assert ( fullBlock != 0 );
231 
232  this->m_blocks.pop_front();
233 
234  this->m_blocks.push_back( fullBlock );
235  }
236  }
237 
238 
239  virtual bool
240  ownsObject(const ObjectType* theObject) const
241  {
242  if ( this->m_blocks.empty() )
243  return false;
244 
245  const_iterator iTerator = this->m_blocks.begin();
246 
247  const_iterator iEnd = this->m_blocks.end();
248 
249  while( iTerator != iEnd
250  && (*iTerator)->blockAvailable() )
251  {
252  if ((*iTerator)->ownsBlock(theObject) )
253  {
254  return true;
255  }
256 
257  ++iTerator;
258  }
259 
260  const_reverse_iterator rIterator = this->m_blocks.rbegin();
261 
262  const_reverse_iterator rEnd = this->m_blocks.rend();
263 
264  while( rIterator != rEnd )
265  {
266  if ((*rIterator)->ownsBlock(theObject) )
267  {
268  return true;
269  }
270 
271  if ( *iTerator == *rIterator )
272  {
273  break;
274  }
275  else
276  {
277  ++rIterator;
278  }
279  }
280 
281  return false;
282  }
283 
284 protected:
285 
286  /*
287  * The method destroys an empty block from the head of the list.
288  * For eliminating multiple create/destroy operation, the block
289  * is destroyed only if the second one is not full.
290  */
291  void
293  {
294  assert(m_destroyBlocks == true);
295 
296  if ( this->m_blocks.empty() == false)
297  {
298  const_iterator iTerator = this->m_blocks.begin();
299 
300  if ( (*iTerator)->isEmpty() )
301  {
302  ++iTerator;
303 
304  if (iTerator == this->m_blocks.end() ||
305  (*iTerator)->blockAvailable() )
306  {
307  this->m_blocks.pop_front();
308  }
309  }
310  }
311  }
312 
313  // data members
314  const bool m_destroyBlocks;
315 
316 private:
317 
318  // Not defined...
320 
322  operator=(const ReusableArenaAllocator<ObjectType>&);
323 
324  bool
326 };
327 
328 
329 
330 }
331 
332 
333 
334 #endif // !defined(REUSABLEARENAALLOCATOR_INCLUDE_GUARD_1357924680)
xalanc::ReusableArenaAllocator::const_reverse_iterator
ArenaBlockListType::const_reverse_iterator const_reverse_iterator
Definition: ReusableArenaAllocator.hpp:57
xalanc::ReusableArenaAllocator::reverse_iterator
ArenaBlockListType::reverse_iterator reverse_iterator
Definition: ReusableArenaAllocator.hpp:56
xalanc::ArenaAllocator< data_type, ReusableArenaBlock< data_type > >::size_type
ReusableArenaBlock< data_type > ::size_type size_type
Definition: ArenaAllocator.hpp:55
XALAN_CPP_NAMESPACE
#define XALAN_CPP_NAMESPACE
Xalan-C++ namespace, including major and minor version.
Definition: XalanVersion.hpp:76
xalanc::XalanList< ReusableArenaBlock< data_type > * >::reverse_iterator
reverse_iterator_ reverse_iterator
Definition: XalanList.hpp:192
xalanc::ReusableArenaAllocator::m_destroyBlocks
const bool m_destroyBlocks
Definition: ReusableArenaAllocator.hpp:314
ReusableArenaBlock.hpp
xalanc::ReusableArenaAllocator::size_type
ReusableArenaBlockType::size_type size_type
Definition: ReusableArenaAllocator.hpp:45
xalanc::ReusableArenaAllocator::iterator
ArenaBlockListType::iterator iterator
Definition: ReusableArenaAllocator.hpp:54
xalanc::ReusableArenaAllocator
Definition: ReusableArenaAllocator.hpp:38
xalanc::ReusableArenaAllocator::ThisType
ReusableArenaAllocator< ObjectType > ThisType
Definition: ReusableArenaAllocator.hpp:50
xalanc::ReusableArenaAllocator::ReusableArenaAllocator
ReusableArenaAllocator(MemoryManager &theManager, size_type theBlockSize, bool destroyBlocks=false)
Definition: ReusableArenaAllocator.hpp:65
xalanc::ReusableArenaAllocator::ReusableArenaBlockType
ReusableArenaBlock< ObjectType > ReusableArenaBlockType
Definition: ReusableArenaAllocator.hpp:43
xalanc::operator==
bool operator==(const XalanVector< Type > &theLHS, const XalanVector< Type > &theRHS)
Definition: XalanVector.hpp:1118
xalanc::ReusableArenaAllocator::~ReusableArenaAllocator
virtual ~ReusableArenaAllocator()
Definition: ReusableArenaAllocator.hpp:75
xalanc::ReusableArenaAllocator::const_iterator
ArenaBlockListType::const_iterator const_iterator
Definition: ReusableArenaAllocator.hpp:55
xalanc::ArenaAllocator
Definition: ArenaAllocator.hpp:47
xalanc::ReusableArenaBlock< data_type >::size_type
BaseClassType::size_type size_type
Definition: ReusableArenaBlock.hpp:48
ArenaAllocator.hpp
xalanc::XalanList< ReusableArenaBlock< data_type > * >::const_reverse_iterator
const_reverse_iterator_ const_reverse_iterator
Definition: XalanList.hpp:193
xalanc::ReusableArenaAllocator::ownsObject
virtual bool ownsObject(const ObjectType *theObject) const
Definition: ReusableArenaAllocator.hpp:240
xalanc::ReusableArenaAllocator::destroyObject
bool destroyObject(ObjectType *theObject)
Definition: ReusableArenaAllocator.hpp:86
xalanc::ReusableArenaAllocator::BaseClassType
ArenaAllocator< ObjectType, ReusableArenaBlockType > BaseClassType
Definition: ReusableArenaAllocator.hpp:48
xalanc::ReusableArenaBlock< ObjectType >
xalanc::XalanListIteratorBase
Definition: XalanList.hpp:63
xalanc::ReusableArenaAllocator::ArenaBlockListType
XalanList< ReusableArenaBlockType * > ArenaBlockListType
Definition: ReusableArenaAllocator.hpp:52
xalanc::ReusableArenaAllocator::allocateBlock
virtual ObjectType * allocateBlock()
Definition: ReusableArenaAllocator.hpp:191
xalanc::ReusableArenaAllocator::commitAllocation
virtual void commitAllocation(ObjectType *theObject)
Definition: ReusableArenaAllocator.hpp:217
xalanc::XalanList
Xalan implementation of a doubly linked list.
Definition: XalanList.hpp:155
xalanc::ReusableArenaAllocator::destroyBlock
void destroyBlock()
Definition: ReusableArenaAllocator.hpp:292