00001 /* 00002 * Licensed to the Apache Software Foundation (ASF) under one 00003 * or more contributor license agreements. See the NOTICE file 00004 * distributed with this work for additional information 00005 * regarding copyright ownership. The ASF licenses this file 00006 * to you under the Apache License, Version 2.0 (the "License"); 00007 * you may not use this file except in compliance with the License. 00008 * You may obtain a copy of the License at 00009 * 00010 * http://www.apache.org/licenses/LICENSE-2.0 00011 * 00012 * Unless required by applicable law or agreed to in writing, software 00013 * distributed under the License is distributed on an "AS IS" BASIS, 00014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00015 * See the License for the specific language governing permissions and 00016 * limitations under the License. 00017 */ 00018 00019 #if !defined(ARENAALLOCATOR_INCLUDE_GUARD_1357924680) 00020 #define ARENAALLOCATOR_INCLUDE_GUARD_1357924680 00021 00022 00023 00024 #include <algorithm> 00025 00026 00027 00028 #include <xalanc/Include/STLHelper.hpp> 00029 #include <xalanc/Include/XalanList.hpp> 00030 00031 00032 00033 #include "ArenaBlock.hpp" 00034 00035 00036 00037 XALAN_CPP_NAMESPACE_BEGIN 00038 00039 00040 00041 template<class ObjectType, 00042 #if defined(XALAN_NO_DEFAULT_TEMPLATE_ARGUMENTS) 00043 class ArenaBlockType> 00044 #else 00045 class ArenaBlockType = ArenaBlock<ObjectType> > 00046 #endif 00047 class ArenaAllocator 00048 { 00049 public: 00050 00051 typedef ArenaAllocator<ObjectType, ArenaBlockType> ThisType; 00052 00053 typedef XalanList<ArenaBlockType*> ArenaBlockListType; 00054 00055 typedef typename ArenaBlockType::size_type size_type; 00056 00057 /* 00058 * Construct an instance that will allocate blocks of the specified size. 00059 * 00060 * @param theBlockSize The block size. 00061 */ 00062 ArenaAllocator( 00063 MemoryManager& theManager, 00064 size_type theBlockSize) : 00065 m_blockSize(theBlockSize), 00066 m_blocks(theManager) 00067 { 00068 } 00069 00070 virtual 00071 ~ArenaAllocator() 00072 { 00073 reset(); 00074 } 00075 00076 MemoryManager& 00077 getMemoryManager() 00078 { 00079 return m_blocks.getMemoryManager(); 00080 } 00081 00082 const MemoryManager& 00083 getMemoryManager() const 00084 { 00085 return m_blocks.getMemoryManager(); 00086 } 00087 00088 /* 00089 * Get size of an ArenaBlock, that is, the number 00090 * of objects in each block. 00091 * 00092 * @return The size of the block 00093 */ 00094 size_type 00095 getBlockSize() const 00096 { 00097 return m_blockSize; 00098 } 00099 00100 /* 00101 * Set size of an ArenaBlock, that is, the number 00102 * of objects in each block. Only affects blocks 00103 * allocated after the call. 00104 * 00105 * @param theSize The size of the block 00106 */ 00107 void 00108 setBlockSize(size_type theSize) 00109 { 00110 m_blockSize = theSize; 00111 } 00112 00113 /* 00114 * Get the number of ArenaBlocks currently allocated. 00115 * 00116 * @return The number of blocks. 00117 */ 00118 size_type 00119 getBlockCount() const 00120 { 00121 return (size_type)m_blocks.size(); 00122 } 00123 00124 /* 00125 * Allocate a block of the appropriate size for an 00126 * object. Call commitAllocation() when after 00127 * the object is successfully constructed. 00128 * 00129 * @return A pointer to a block of memory 00130 */ 00131 virtual ObjectType* 00132 allocateBlock() 00133 { 00134 if (m_blocks.empty() == true || 00135 m_blocks.back()->blockAvailable() == false) 00136 { 00137 m_blocks.push_back( 00138 ArenaBlockType::create( 00139 getMemoryManager(), 00140 m_blockSize)); 00141 } 00142 assert( 00143 m_blocks.empty() == false && 00144 m_blocks.back() != 0 && 00145 m_blocks.back()->blockAvailable() == true); 00146 00147 return m_blocks.back()->allocateBlock(); 00148 } 00149 00150 /* 00151 * Commits the allocation of the previous 00152 * allocateBlock() call. 00153 * 00154 * @param theObject A pointer to a block of memory 00155 */ 00156 virtual void 00157 commitAllocation(ObjectType* theObject) 00158 { 00159 assert( 00160 m_blocks.empty() == false && 00161 m_blocks.back()->ownsBlock(theObject) == true); 00162 00163 m_blocks.back()->commitAllocation(theObject); 00164 00165 assert(m_blocks.back()->ownsObject(theObject) == true); 00166 } 00167 00168 virtual bool 00169 ownsObject(const ObjectType* theObject) const 00170 { 00171 bool fResult = false; 00172 00173 typedef typename ArenaBlockListType::const_reverse_iterator const_reverse_iterator; 00174 00175 // Search back for a block that may have allocated the object... 00176 const const_reverse_iterator theEnd = this->m_blocks.rend(); 00177 00178 const_reverse_iterator i = this->m_blocks.rbegin(); 00179 00180 while(i != theEnd) 00181 { 00182 assert(*i != 0); 00183 00184 if ((*i)->ownsObject(theObject) == true) 00185 { 00186 fResult = true; 00187 00188 break; 00189 } 00190 else 00191 { 00192 ++i; 00193 } 00194 } 00195 00196 return fResult; 00197 } 00198 00199 virtual void 00200 reset() 00201 { 00202 XALAN_STD_QUALIFIER for_each( 00203 m_blocks.begin(), 00204 m_blocks.end(), 00205 DeleteFunctor<ArenaBlockType>(m_blocks.getMemoryManager())); 00206 00207 m_blocks.clear(); 00208 } 00209 00210 protected: 00211 00212 // data members... 00213 size_type m_blockSize; 00214 00215 ArenaBlockListType m_blocks; 00216 00217 private: 00218 00219 // Not defined... 00220 ArenaAllocator(const ArenaAllocator<ObjectType, ArenaBlockType>&); 00221 00222 ArenaAllocator<ObjectType, ArenaBlockType>& 00223 operator=(const ArenaAllocator<ObjectType, ArenaBlockType>&); 00224 00225 bool 00226 operator==(const ArenaAllocator<ObjectType, ArenaBlockType>&) const; 00227 }; 00228 00229 00230 00231 XALAN_CPP_NAMESPACE_END 00232 00233 00234 00235 #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.11 |
|