Xalan-C++ API Documentation

The Xalan C++ XSLT Processor Version 1.8

Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members | Related Pages

ReusableArenaAllocator.hpp

Go to the documentation of this file.
00001 /* 00002 * Copyright 1999-2004 The Apache Software Foundation. 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #if !defined(REUSABLEARENAALLOCATOR_INCLUDE_GUARD_1357924680) 00018 #define REUSABLEARENAALLOCATOR_INCLUDE_GUARD_1357924680 00019 00020 00021 00022 #include <algorithm> 00023 #include <vector> 00024 00025 00026 00027 #include "ReusableArenaBlock.hpp" 00028 #include "ArenaAllocator.hpp" 00029 00030 00031 00032 XALAN_CPP_NAMESPACE_BEGIN 00033 00034 00035 00036 template<class ObjectType> 00037 class ReusableArenaAllocator : public ArenaAllocator<ObjectType, 00038 ReusableArenaBlock<ObjectType> > 00039 { 00040 public: 00041 00042 typedef ReusableArenaBlock<ObjectType> ReusableArenaBlockType; 00043 00044 typedef typename ReusableArenaBlockType::size_type size_type; 00045 00046 typedef ArenaAllocator<ObjectType, 00047 ReusableArenaBlockType> BaseClassType; 00048 00049 #if defined (XALAN_NO_STD_NAMESPACE) 00050 typedef vector<ReusableArenaBlockType*> ArenaBlockListType; 00051 #else 00052 typedef std::vector<ReusableArenaBlockType*> ArenaBlockListType; 00053 #endif 00054 00055 /* 00056 * Construct an instance that will allocate blocks of the specified size. 00057 * 00058 * @param theBlockSize The block size. 00059 */ 00060 ReusableArenaAllocator(size_type theBlockSize) : 00061 BaseClassType(theBlockSize), 00062 m_lastBlockReferenced(0) 00063 { 00064 } 00065 00066 virtual 00067 ~ReusableArenaAllocator() 00068 { 00069 } 00070 00071 /* 00072 * Destroy the object, and free the block for re-use. 00073 * 00074 * @param theObject the address of the object. 00075 * @return true if the object was deleted, false if not. 00076 */ 00077 bool 00078 destroyObject(ObjectType* theObject) 00079 { 00080 bool fSuccess = false; 00081 00082 // Check this, just in case... 00083 if (m_lastBlockReferenced != 0 && m_lastBlockReferenced->ownsObject(theObject) == true) 00084 { 00085 m_lastBlockReferenced->destroyObject(theObject); 00086 00087 fSuccess = true; 00088 } 00089 else 00090 { 00091 // Note that this-> is required by template lookup rules. 00092 const typename ArenaBlockListType::reverse_iterator theEnd = this->m_blocks.rend(); 00093 00094 typename ArenaBlockListType::reverse_iterator i = this->m_blocks.rbegin(); 00095 00096 while(i != theEnd) 00097 { 00098 if ((*i)->ownsObject(theObject) == true) 00099 { 00100 m_lastBlockReferenced = *i; 00101 00102 m_lastBlockReferenced->destroyObject(theObject); 00103 00104 fSuccess = true; 00105 00106 break; 00107 } 00108 else 00109 { 00110 ++i; 00111 } 00112 } 00113 } 00114 00115 return fSuccess; 00116 } 00117 00118 /* 00119 * Allocate a block of the appropriate size for an 00120 * object. Call commitAllocation() when after 00121 * the object is successfully constructed. You _must_ 00122 * commit an allocation before performing any other 00123 * operation on the allocator. 00124 * 00125 * @return A pointer to a block of memory 00126 */ 00127 virtual ObjectType* 00128 allocateBlock() 00129 { 00130 if (m_lastBlockReferenced == 0 || 00131 m_lastBlockReferenced->blockAvailable() == false) 00132 { 00133 // Search back for a block with some space available... 00134 const typename ArenaBlockListType::reverse_iterator theEnd = this->m_blocks.rend(); 00135 00136 // Note that this-> is required by template lookup rules. 00137 typename ArenaBlockListType::reverse_iterator i = this->m_blocks.rbegin(); 00138 00139 while(i != theEnd) 00140 { 00141 assert(*i != 0); 00142 00143 if (*i != m_lastBlockReferenced && (*i)->blockAvailable() == true) 00144 { 00145 // Ahh, found one with free space. 00146 m_lastBlockReferenced = *i; 00147 00148 break; 00149 } 00150 else 00151 { 00152 ++i; 00153 } 00154 } 00155 00156 if (i == theEnd) 00157 { 00158 // No blocks have free space available, so create a new block, and 00159 // push it on the list. 00160 // Note that this-> is required by template lookup rules. 00161 m_lastBlockReferenced = new ReusableArenaBlockType(this->m_blockSize); 00162 00163 this->m_blocks.push_back(m_lastBlockReferenced); 00164 } 00165 } 00166 assert(m_lastBlockReferenced != 0 && m_lastBlockReferenced->blockAvailable() == true); 00167 00168 return m_lastBlockReferenced->allocateBlock(); 00169 } 00170 00171 /* 00172 * Commits the allocation of the previous 00173 * allocateBlock() call. 00174 * 00175 * @param theObject A pointer to a block of memory 00176 */ 00177 virtual void 00178 commitAllocation(ObjectType* theObject) 00179 { 00180 // Note that this-> is required by template lookup rules. 00181 assert(this->m_blocks.empty() == false && m_lastBlockReferenced != 0 && m_lastBlockReferenced->ownsBlock(theObject) == true); 00182 00183 m_lastBlockReferenced->commitAllocation(theObject); 00184 assert(m_lastBlockReferenced->ownsObject(theObject) == true); 00185 } 00186 00187 virtual void 00188 reset() 00189 { 00190 m_lastBlockReferenced = 0; 00191 00192 BaseClassType::reset(); 00193 } 00194 00195 virtual bool 00196 ownsObject(const ObjectType* theObject) const 00197 { 00198 bool fResult = false; 00199 00200 // If no block has ever been referenced, then we haven't allocated 00201 // any objects. 00202 if (m_lastBlockReferenced != 0) 00203 { 00204 // Check the last referenced block first. 00205 fResult = m_lastBlockReferenced->ownsObject(theObject); 00206 00207 if (fResult == false) 00208 { 00209 fResult = BaseClassType::ownsObject(theObject); 00210 } 00211 } 00212 00213 return fResult; 00214 } 00215 00216 private: 00217 00218 // Not defined... 00219 ReusableArenaAllocator(const ReusableArenaAllocator<ObjectType>&); 00220 00221 ReusableArenaAllocator<ObjectType>& 00222 operator=(const ReusableArenaAllocator<ObjectType>&); 00223 00224 // Data members... 00225 ReusableArenaBlockType* m_lastBlockReferenced; 00226 }; 00227 00228 00229 00230 XALAN_CPP_NAMESPACE_END 00231 00232 00233 00234 #endif // !defined(REUSABLEARENAALLOCATOR_INCLUDE_GUARD_1357924680)

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.8
Copyright © 1999-2004 The Apache Software Foundation. All Rights Reserved.