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(ARENAALLOCATOR_INCLUDE_GUARD_1357924680) 00018 #define ARENAALLOCATOR_INCLUDE_GUARD_1357924680 00019 00020 00021 00022 #include <algorithm> 00023 00024 00025 00026 #include <xalanc/Include/STLHelper.hpp> 00027 #include <xalanc/Include/XalanList.hpp> 00028 00029 00030 00031 #include "ArenaBlock.hpp" 00032 00033 00034 00035 XALAN_CPP_NAMESPACE_BEGIN 00036 00037 00038 00039 template<class ObjectType, 00040 #if defined(XALAN_NO_DEFAULT_TEMPLATE_ARGUMENTS) 00041 class ArenaBlockType> 00042 #else 00043 class ArenaBlockType = ArenaBlock<ObjectType> > 00044 #endif 00045 class ArenaAllocator 00046 { 00047 public: 00048 00049 typedef ArenaAllocator<ObjectType, ArenaBlockType> ThisType; 00050 00051 typedef XalanList<ArenaBlockType*> ArenaBlockListType; 00052 00053 typedef typename ArenaBlockType::size_type size_type; 00054 00055 /* 00056 * Construct an instance that will allocate blocks of the specified size. 00057 * 00058 * @param theBlockSize The block size. 00059 */ 00060 ArenaAllocator( 00061 MemoryManagerType& theManager, 00062 size_type theBlockSize) : 00063 m_blockSize(theBlockSize), 00064 m_blocks(theManager) 00065 { 00066 } 00067 00068 virtual 00069 ~ArenaAllocator() 00070 { 00071 reset(); 00072 } 00073 00074 MemoryManagerType& 00075 getMemoryManager() 00076 { 00077 return m_blocks.getMemoryManager(); 00078 } 00079 00080 const MemoryManagerType& 00081 getMemoryManager() const 00082 { 00083 return m_blocks.getMemoryManager(); 00084 } 00085 00086 /* 00087 * Get size of an ArenaBlock, that is, the number 00088 * of objects in each block. 00089 * 00090 * @return The size of the block 00091 */ 00092 size_type 00093 getBlockSize() const 00094 { 00095 return m_blockSize; 00096 } 00097 00098 /* 00099 * Set size of an ArenaBlock, that is, the number 00100 * of objects in each block. Only affects blocks 00101 * allocated after the call. 00102 * 00103 * @param theSize The size of the block 00104 */ 00105 void 00106 setBlockSize(size_type theSize) 00107 { 00108 m_blockSize = theSize; 00109 } 00110 00111 /* 00112 * Get the number of ArenaBlocks currently allocated. 00113 * 00114 * @return The number of blocks. 00115 */ 00116 size_type 00117 getBlockCount() const 00118 { 00119 return (size_type)m_blocks.size(); 00120 } 00121 00122 /* 00123 * Allocate a block of the appropriate size for an 00124 * object. Call commitAllocation() when after 00125 * the object is successfully constructed. 00126 * 00127 * @return A pointer to a block of memory 00128 */ 00129 virtual ObjectType* 00130 allocateBlock() 00131 { 00132 if (m_blocks.empty() == true || 00133 m_blocks.back()->blockAvailable() == false) 00134 { 00135 m_blocks.push_back( 00136 ArenaBlockType::create( 00137 getMemoryManager(), 00138 m_blockSize)); 00139 } 00140 assert( 00141 m_blocks.empty() == false && 00142 m_blocks.back() != 0 && 00143 m_blocks.back()->blockAvailable() == true); 00144 00145 return m_blocks.back()->allocateBlock(); 00146 } 00147 00148 /* 00149 * Commits the allocation of the previous 00150 * allocateBlock() call. 00151 * 00152 * @param theObject A pointer to a block of memory 00153 */ 00154 virtual void 00155 commitAllocation(ObjectType* theObject) 00156 { 00157 assert( 00158 m_blocks.empty() == false && 00159 m_blocks.back()->ownsBlock(theObject) == true); 00160 00161 m_blocks.back()->commitAllocation(theObject); 00162 00163 assert(m_blocks.back()->ownsObject(theObject) == true); 00164 } 00165 00166 virtual bool 00167 ownsObject(const ObjectType* theObject) const 00168 { 00169 bool fResult = false; 00170 00171 typedef typename ArenaBlockListType::const_reverse_iterator const_reverse_iterator; 00172 00173 // Search back for a block that may have allocated the object... 00174 const const_reverse_iterator theEnd = this->m_blocks.rend(); 00175 00176 const_reverse_iterator i = this->m_blocks.rbegin(); 00177 00178 while(i != theEnd) 00179 { 00180 assert(*i != 0); 00181 00182 if ((*i)->ownsObject(theObject) == true) 00183 { 00184 fResult = true; 00185 00186 break; 00187 } 00188 else 00189 { 00190 ++i; 00191 } 00192 } 00193 00194 return fResult; 00195 } 00196 00197 virtual void 00198 reset() 00199 { 00200 XALAN_STD_QUALIFIER for_each( 00201 m_blocks.begin(), 00202 m_blocks.end(), 00203 DeleteFunctor<ArenaBlockType>(m_blocks.getMemoryManager())); 00204 00205 m_blocks.clear(); 00206 } 00207 00208 protected: 00209 00210 // data members... 00211 size_type m_blockSize; 00212 00213 ArenaBlockListType m_blocks; 00214 00215 private: 00216 00217 // Not defined... 00218 ArenaAllocator(const ArenaAllocator<ObjectType, ArenaBlockType>&); 00219 00220 ArenaAllocator<ObjectType, ArenaBlockType>& 00221 operator=(const ArenaAllocator<ObjectType, ArenaBlockType>&); 00222 00223 bool 00224 operator==(const ArenaAllocator<ObjectType, ArenaBlockType>&) const; 00225 }; 00226 00227 00228 00229 XALAN_CPP_NAMESPACE_END 00230 00231 00232 00233 #endif // !defined(ARENAALLOCATOR_INCLUDE_GUARD_1357924680)
Doxygen and GraphViz are used to generate this API documentation from the Xalan-C header files.
Xalan-C++ XSLT Processor Version 1.10 |
|