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(ARENABLOCKBASE_INCLUDE_GUARD_1357924680) 00018 #define ARENABLOCKBASE_INCLUDE_GUARD_1357924680 00019 00020 00021 #include <cassert> 00022 #include <functional> 00023 //#include <memory> 00024 00025 #include <xalanc/Include/XalanMemoryManagement.hpp> 00026 00027 00028 #if !defined(XALAN_NO_SELECTIVE_TEMPLATE_INSTANTIATION) 00029 #include <xalanc/PlatformSupport/XalanAllocator.hpp> 00030 #endif 00031 00032 00033 XALAN_CPP_NAMESPACE_BEGIN 00034 00035 00036 #if defined(XALAN_NO_SELECTIVE_TEMPLATE_INSTANTIATION) 00037 00038 template <class Type> 00039 class ArenaBlockAllocator 00040 { 00041 public: 00042 00043 typedef typename T size_type; 00044 typedef ptrdiff_t difference_type; 00045 typedef Type* pointer; 00046 typedef const Type* const_pointer; 00047 typedef Type& reference; 00048 typedef const Type& const_reference; 00049 typedef Type value_type; 00050 00051 ArenaBlockAllocator(MemoryManagerType& theManager) : 00052 m_memoryManager(theManager) 00053 { 00054 } 00055 00056 ~ArenaBlockAllocator() 00057 { 00058 } 00059 00060 MemoryManagerType& 00061 getMemoryManager() 00062 { 00063 return m_memoryManager; 00064 } 00065 00066 pointer 00067 allocate( 00068 size_type size, 00069 const void* /* hint */ = 0) 00070 { 00071 return (pointer)m_memoryManager.allocate(size * sizeof(Type)); 00072 } 00073 00074 void 00075 deallocate( 00076 pointer p, 00077 size_type /* n */) 00078 { 00079 if(p != 0) 00080 { 00081 m_memoryManager.deallocate(p); 00082 } 00083 } 00084 00085 private: 00086 00087 // not defined 00088 ArenaBlockAllocator(const ArenaBlockAllocator<Type>&); 00089 00090 ArenaBlockAllocator<Type>& 00091 operator=(const ArenaBlockAllocator<Type>&); 00092 00093 MemoryManagerType& m_memoryManager; 00094 }; 00095 #endif 00096 00097 00098 00099 template<class ObjectType, 00100 #if defined(XALAN_NO_DEFAULT_TEMPLATE_ARGUMENTS) 00101 class SizeType> 00102 #else 00103 class SizeType = size_t> 00104 #endif 00105 class ArenaBlockBase 00106 { 00107 public: 00108 00109 typedef ArenaBlockBase<ObjectType, SizeType> ThisType; 00110 00111 #if defined(XALAN_NO_SELECTIVE_TEMPLATE_INSTANTIATION) 00112 typedef ArenaBlockAllocator<ObjectType> AllocatorType; 00113 #else 00114 typedef XalanAllocator<ObjectType> AllocatorType; 00115 #endif 00116 00117 typedef SizeType size_type; 00118 00119 MemoryManagerType& 00120 getMemoryManager() 00121 { 00122 return m_allocator.getMemoryManager(); 00123 } 00124 00125 /* 00126 * Find out if there is a block available. 00127 * 00128 * @return true if one is available, false if not. 00129 */ 00130 bool 00131 blockAvailable() const 00132 { 00133 return m_objectCount < m_blockSize ? true : false; 00134 } 00135 00136 /* 00137 * Find out if there are any block is allocated 00138 * 00139 * @return true if one is available, false if not. 00140 */ 00141 bool 00142 isEmpty() const 00143 { 00144 return m_objectCount == 0 ? true : false; 00145 } 00146 00147 /* 00148 * Get the number of objects currently allocated in the 00149 * block. 00150 * 00151 * @return The number of objects allocated. 00152 */ 00153 size_type 00154 getCountAllocated() const 00155 { 00156 return m_objectCount; 00157 } 00158 00159 /* 00160 * Get the block size, that is, the number 00161 * of objects in each block. 00162 * 00163 * @return The size of the block 00164 */ 00165 size_type 00166 getBlockSize() const 00167 { 00168 return m_blockSize; 00169 } 00170 00171 /* 00172 * Determine if this block owns the specified object block. 00173 * Note that, unlike ownsObject(), there does not need to 00174 * be an object at the address. 00175 * 00176 * @param theObject the address of the object 00177 * @return true if we own the object block, false if not. 00178 */ 00179 bool 00180 ownsBlock(const ObjectType* theObject) const 00181 { 00182 return isInBorders(theObject, m_blockSize); 00183 } 00184 00185 protected: 00186 00187 ArenaBlockBase( 00188 MemoryManagerType& theManager, 00189 size_type theBlockSize) : 00190 m_allocator(theManager), 00191 m_objectCount(0), 00192 m_blockSize(theBlockSize), 00193 #if defined(XALAN_NEW_STD_ALLOCATOR) 00194 m_objectBlock(m_allocator.allocate(m_blockSize)) 00195 #else 00196 m_objectBlock(m_allocator.allocate(m_blockSize, 0)) 00197 #endif 00198 { 00199 assert(theBlockSize > 0); 00200 00201 assert(m_objectBlock != 0); 00202 } 00203 00204 ~ArenaBlockBase() 00205 { 00206 // Release the memory... 00207 m_allocator.deallocate(m_objectBlock, m_blockSize); 00208 00209 } 00210 00211 /* 00212 * Determine if this block is located between beginning of the array 00213 * and the "rightBorder" array member (not included) 00214 * @param theObject the address of the object 00215 * rightBorder the right 00216 * @return true if we own the object block, false if not. 00217 */ 00218 bool 00219 isInBorders( 00220 const ObjectType* theObject, 00221 size_type rightBoundary) const 00222 { 00223 if ( rightBoundary > m_blockSize ) 00224 { 00225 rightBoundary = m_blockSize; 00226 } 00227 00228 // Use less<>, since it's guaranteed to do pointer 00229 // comparisons correctly... 00230 XALAN_STD_QUALIFIER less<const ObjectType*> functor; 00231 00232 if (functor(theObject, m_objectBlock) == false && 00233 functor(theObject, m_objectBlock + rightBoundary) == true) 00234 { 00235 return true; 00236 } 00237 else 00238 { 00239 return false; 00240 } 00241 } 00242 00243 /* 00244 * Determine the offset into the block for the given address. 00245 * Behavior is undefined if the address is not within our 00246 * block 00247 * 00248 * @param theObject the address of the object 00249 * @return the offset 00250 */ 00251 size_type 00252 getBlockOffset(const ObjectType* theObject) const 00253 { 00254 assert(size_type( (theObject - m_objectBlock) / sizeof(ObjectType) ) < m_blockSize); 00255 00256 return theObject - m_objectBlock; 00257 } 00258 00259 /* 00260 * Determine the address within our block of the object 00261 * at the specified offset. 00262 * Behavior is undefined if the offset is greater than the 00263 * block size. 00264 * 00265 * @param theObject the address of the object 00266 * @return the offset 00267 */ 00268 ObjectType* 00269 getBlockAddress(size_type theOffset) const 00270 { 00271 assert(theOffset < m_blockSize); 00272 00273 return m_objectBlock + theOffset; 00274 } 00275 00276 // data members... 00277 AllocatorType m_allocator; 00278 00279 size_type m_objectCount; 00280 00281 const size_type m_blockSize; 00282 00283 ObjectType* m_objectBlock; 00284 00285 private: 00286 00287 // Not implemented... 00288 ArenaBlockBase(const ThisType&); 00289 00290 ThisType& 00291 operator=(const ThisType&); 00292 00293 bool 00294 operator==(const ThisType&) const; 00295 }; 00296 00297 XALAN_CPP_NAMESPACE_END 00298 00299 00300 00301 #endif // !defined(ARENABLOCKBASE_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 |
|