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

ReusableArenaBlock.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(REUSABLEARENABLOCK_INCLUDE_GUARD_1357924680) 00018 #define REUSABLEARENABLOCK_INCLUDE_GUARD_1357924680 00019 00020 00021 00022 #include <xalanc/PlatformSupport/XalanBitmap.hpp> 00023 #include <xalanc/PlatformSupport/ArenaBlock.hpp> 00024 00025 00026 00027 00028 XALAN_CPP_NAMESPACE_BEGIN 00029 00030 00031 00032 template<class ObjectType> 00033 class ReusableArenaBlock : public ArenaBlock<ObjectType> 00034 { 00035 public: 00036 00037 typedef ArenaBlock<ObjectType> BaseClassType; 00038 00039 typedef typename BaseClassType::size_type size_type; 00040 00041 /* 00042 * Construct an ArenaBlock of the specified size 00043 * of objects. 00044 * 00045 * @param theBlockSize The size of the block (the number of objects it can contain). 00046 */ 00047 ReusableArenaBlock(size_type theBlockSize) : 00048 BaseClassType(theBlockSize), 00049 m_freeList(theBlockSize), 00050 m_freeBlockCount(0) 00051 { 00052 } 00053 00054 ~ReusableArenaBlock() 00055 { 00056 // Note that this-> is required by template lookup rules. 00057 this->destroyAll(); 00058 } 00059 00060 /* 00061 * Allocate a block. Once the object is constructed, you must call 00062 * commitAllocation(). 00063 * 00064 * @return a pointer to the new block. 00065 */ 00066 virtual ObjectType* 00067 allocateBlock() 00068 { 00069 if (m_freeBlockCount == 0) 00070 { 00071 return BaseClassType::allocateBlock(); 00072 } 00073 else 00074 { 00075 return getNextFromFreeList(); 00076 } 00077 } 00078 00079 /* 00080 * Commit the previous allocation. 00081 * 00082 * @param theBlock the address that was returned by allocateBlock() 00083 */ 00084 virtual void 00085 commitAllocation(ObjectType* theBlock) 00086 { 00087 assert(theBlock != 0); 00088 assert(m_freeBlockCount == 0 || 00089 theBlock == getNextFromFreeList()); 00090 00091 if (m_freeBlockCount == 0) 00092 { 00093 BaseClassType::commitAllocation(theBlock); 00094 } 00095 else 00096 { 00097 removeFromFreeList(theBlock); 00098 } 00099 } 00100 00101 /* 00102 * Find out if there is a block available. 00103 * 00104 * @return true if one is available, false if not. 00105 */ 00106 virtual bool 00107 blockAvailable() const 00108 { 00109 return m_freeBlockCount != 0 ? true : BaseClassType::blockAvailable(); 00110 } 00111 00112 /* 00113 * Get the number of objects currently allocated in the 00114 * block. 00115 * 00116 * @return The number of objects allocated. 00117 */ 00118 virtual size_type 00119 getCountAllocated() const 00120 { 00121 return BaseClassType::getCountAllocated() - m_freeBlockCount; 00122 } 00123 00124 /* 00125 * Determine if this block owns the specified object. Note 00126 * that even if the object address is within our block, this 00127 * call will return false if no object currently occupies the 00128 * block. See also ownsBlock(). 00129 * 00130 * @param theObject the address of the object. 00131 * @return true if we own the object, false if not. 00132 */ 00133 virtual bool 00134 ownsObject(const ObjectType* theObject) const 00135 { 00136 return BaseClassType::ownsObject(theObject) && !isOnFreeList(theObject); 00137 } 00138 00139 /* 00140 * Destroy the object, and return the block to the free list. 00141 * The behavior is undefined if the object pointed to is not 00142 * owned by the block. 00143 * 00144 * @param theObject the address of the object. 00145 */ 00146 void 00147 destroyObject(ObjectType* theObject) 00148 { 00149 assert(ownsObject(theObject) == true); 00150 00151 this->m_destroyFunction(*theObject); 00152 00153 addToFreeList(theObject); 00154 } 00155 00156 protected: 00157 00158 /* 00159 * Determine if the block should be destroyed. Returns true, 00160 * unless the object is on the free list. The behavior is 00161 * undefined if the object pointed to is not owned by the 00162 * block. 00163 * 00164 * @param theObject the address of the object 00165 * @return true if block should be destroyed, false if not. 00166 */ 00167 virtual bool 00168 shouldDestroyBlock(const ObjectType* theObject) const 00169 { 00170 return !isOnFreeList(theObject); 00171 } 00172 00173 private: 00174 00175 // Not implemented... 00176 ReusableArenaBlock(const ReusableArenaBlock<ObjectType>&); 00177 00178 ReusableArenaBlock<ObjectType>& 00179 operator=(const ReusableArenaBlock<ObjectType>&); 00180 00181 bool 00182 operator==(const ReusableArenaBlock<ObjectType>&) const; 00183 00184 00185 /* 00186 * Determine if the block is on the free list. The behavior is 00187 * undefined if the object pointed to is not owned by the 00188 * block. 00189 * 00190 * @param theObject the address of the object 00191 * @return true if block is on the free list, false if not. 00192 */ 00193 bool 00194 isOnFreeList(const ObjectType* theObject) const 00195 { 00196 if (m_freeBlockCount == 0) 00197 { 00198 return false; 00199 } 00200 else 00201 { 00202 const size_type theOffset = 00203 this->getBlockOffset(theObject); 00204 00205 return m_freeList.isSet(theOffset); 00206 } 00207 } 00208 00209 /* 00210 * Add a block to the free list. The behavior is 00211 * undefined if the object pointed to is not owned by the 00212 * block. 00213 * 00214 * @param theObject the address of the object 00215 */ 00216 void 00217 addToFreeList(const ObjectType* theObject) 00218 { 00219 const size_type theOffset = 00220 this->getBlockOffset(theObject); 00221 00222 m_freeList.set(theOffset); 00223 00224 ++m_freeBlockCount; 00225 } 00226 00227 /* 00228 * Remove a block from the free list. The behavior is 00229 * undefined if the object pointed to is not owned by the 00230 * block. 00231 * 00232 * @param theObject the address of the object 00233 */ 00234 void 00235 removeFromFreeList(const ObjectType* theObject) 00236 { 00237 const size_type theOffset = 00238 this->getBlockOffset(theObject); 00239 00240 m_freeList.clear(theOffset); 00241 00242 --m_freeBlockCount; 00243 } 00244 00245 /* 00246 * Get the next block from the free list. Returns 0 if 00247 * the free list is empty. 00248 * 00249 * @return the address of the block 00250 */ 00251 ObjectType* 00252 getNextFromFreeList() 00253 { 00254 ObjectType* theResult = 0; 00255 00256 if (m_freeBlockCount > 0) 00257 { 00258 const size_type theFreeListSize = m_freeList.getSize(); 00259 00260 for(size_type i = 0; i < theFreeListSize; ++i) 00261 { 00262 if (m_freeList.isSet(i) == true) 00263 { 00264 // Note that this-> is required by template lookup rules. 00265 theResult = this->getBlockAddress(i); 00266 00267 break; 00268 } 00269 } 00270 } 00271 00272 return theResult; 00273 } 00274 00275 // Bitmap which tracks which blocks are not in use 00276 // and that should not be destroyed. 00277 XalanBitmap m_freeList; 00278 00279 // The number of blocks on the free list.) 00280 size_type m_freeBlockCount; 00281 }; 00282 00283 00284 00285 XALAN_CPP_NAMESPACE_END 00286 00287 00288 00289 #endif // !defined(REUSABLEARENABLOCK_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.