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