00001 /* 00002 * The Apache Software License, Version 1.1 00003 * 00004 * 00005 * Copyright (c) 2000-2002 The Apache Software Foundation. All rights 00006 * reserved. 00007 * 00008 * Redistribution and use in source and binary forms, with or without 00009 * modification, are permitted provided that the following conditions 00010 * are met: 00011 * 00012 * 1. Redistributions of source code must retain the above copyright 00013 * notice, this list of conditions and the following disclaimer. 00014 * 00015 * 2. Redistributions in binary form must reproduce the above copyright 00016 * notice, this list of conditions and the following disclaimer in 00017 * the documentation and/or other materials provided with the 00018 * distribution. 00019 * 00020 * 3. The end-user documentation included with the redistribution, 00021 * if any, must include the following acknowledgment: 00022 * "This product includes software developed by the 00023 * Apache Software Foundation (http://www.apache.org/)." 00024 * Alternately, this acknowledgment may appear in the software itself, 00025 * if and wherever such third-party acknowledgments normally appear. 00026 * 00027 * 4. The names "Xalan" and "Apache Software Foundation" must 00028 * not be used to endorse or promote products derived from this 00029 * software without prior written permission. For written 00030 * permission, please contact apache@apache.org. 00031 * 00032 * 5. Products derived from this software may not be called "Apache", 00033 * nor may "Apache" appear in their name, without prior written 00034 * permission of the Apache Software Foundation. 00035 * 00036 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 00037 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00038 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00039 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR 00040 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00041 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00042 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 00043 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 00044 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00045 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 00046 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00047 * SUCH DAMAGE. 00048 * ==================================================================== 00049 * 00050 * This software consists of voluntary contributions made by many 00051 * individuals on behalf of the Apache Software Foundation and was 00052 * originally based on software copyright (c) 1999, International 00053 * Business Machines, Inc., http://www.ibm.com. For more 00054 * information on the Apache Software Foundation, please see 00055 * <http://www.apache.org/>. 00056 */ 00057 00058 #if !defined(REUSABLEARENABLOCK_INCLUDE_GUARD_1357924680) 00059 #define REUSABLEARENABLOCK_INCLUDE_GUARD_1357924680 00060 00061 00062 00063 #include <xalanc/PlatformSupport/XalanBitmap.hpp> 00064 #include <xalanc/PlatformSupport/ArenaBlock.hpp> 00065 00066 00067 00068 00069 XALAN_CPP_NAMESPACE_BEGIN 00070 00071 00072 00073 template<class ObjectType> 00074 class ReusableArenaBlock : public ArenaBlock<ObjectType> 00075 { 00076 public: 00077 00078 typedef ArenaBlock<ObjectType> BaseClassType; 00079 00080 typedef typename BaseClassType::size_type size_type; 00081 00082 /* 00083 * Construct an ArenaBlock of the specified size 00084 * of objects. 00085 * 00086 * @param theBlockSize The size of the block (the number of objects it can contain). 00087 */ 00088 ReusableArenaBlock(size_type theBlockSize) : 00089 BaseClassType(theBlockSize), 00090 m_freeList(theBlockSize), 00091 m_freeBlockCount(0) 00092 { 00093 } 00094 00095 ~ReusableArenaBlock() 00096 { 00097 // Note that this-> is required by template lookup rules. 00098 this->destroyAll(); 00099 } 00100 00101 /* 00102 * Allocate a block. Once the object is constructed, you must call 00103 * commitAllocation(). 00104 * 00105 * @return a pointer to the new block. 00106 */ 00107 virtual ObjectType* 00108 allocateBlock() 00109 { 00110 if (m_freeBlockCount == 0) 00111 { 00112 return BaseClassType::allocateBlock(); 00113 } 00114 else 00115 { 00116 return getNextFromFreeList(); 00117 } 00118 } 00119 00120 /* 00121 * Commit the previous allocation. 00122 * 00123 * @param theBlock the address that was returned by allocateBlock() 00124 */ 00125 virtual void 00126 commitAllocation(ObjectType* theBlock) 00127 { 00128 assert(theBlock != 0); 00129 assert(m_freeBlockCount == 0 || 00130 theBlock == getNextFromFreeList()); 00131 00132 if (m_freeBlockCount == 0) 00133 { 00134 BaseClassType::commitAllocation(theBlock); 00135 } 00136 else 00137 { 00138 removeFromFreeList(theBlock); 00139 } 00140 } 00141 00142 /* 00143 * Find out if there is a block available. 00144 * 00145 * @return true if one is available, false if not. 00146 */ 00147 virtual bool 00148 blockAvailable() const 00149 { 00150 return m_freeBlockCount != 0 ? true : BaseClassType::blockAvailable(); 00151 } 00152 00153 /* 00154 * Get the number of objects currently allocated in the 00155 * block. 00156 * 00157 * @return The number of objects allocated. 00158 */ 00159 virtual size_type 00160 getCountAllocated() const 00161 { 00162 return BaseClassType::getCountAllocated() - m_freeBlockCount; 00163 } 00164 00165 /* 00166 * Determine if this block owns the specified object. Note 00167 * that even if the object address is within our block, this 00168 * call will return false if no object currently occupies the 00169 * block. See also ownsBlock(). 00170 * 00171 * @param theObject the address of the object. 00172 * @return true if we own the object, false if not. 00173 */ 00174 virtual bool 00175 ownsObject(const ObjectType* theObject) const 00176 { 00177 return BaseClassType::ownsObject(theObject) && !isOnFreeList(theObject); 00178 } 00179 00180 /* 00181 * Destroy the object, and return the block to the free list. 00182 * The behavior is undefined if the object pointed to is not 00183 * owned by the block. 00184 * 00185 * @param theObject the address of the object. 00186 */ 00187 void 00188 destroyObject(ObjectType* theObject) 00189 { 00190 assert(ownsObject(theObject) == true); 00191 00192 this->m_destroyFunction(*theObject); 00193 00194 addToFreeList(theObject); 00195 } 00196 00197 protected: 00198 00199 /* 00200 * Determine if the block should be destroyed. Returns true, 00201 * unless the object is on the free list. The behavior is 00202 * undefined if the object pointed to is not owned by the 00203 * block. 00204 * 00205 * @param theObject the address of the object 00206 * @return true if block should be destroyed, false if not. 00207 */ 00208 virtual bool 00209 shouldDestroyBlock(const ObjectType* theObject) const 00210 { 00211 return !isOnFreeList(theObject); 00212 } 00213 00214 private: 00215 00216 // Not implemented... 00217 ReusableArenaBlock(const ReusableArenaBlock<ObjectType>&); 00218 00219 ReusableArenaBlock<ObjectType>& 00220 operator=(const ReusableArenaBlock<ObjectType>&); 00221 00222 bool 00223 operator==(const ReusableArenaBlock<ObjectType>&) const; 00224 00225 00226 /* 00227 * Determine if the block is on the free list. The behavior is 00228 * undefined if the object pointed to is not owned by the 00229 * block. 00230 * 00231 * @param theObject the address of the object 00232 * @return true if block is on the free list, false if not. 00233 */ 00234 bool 00235 isOnFreeList(const ObjectType* theObject) const 00236 { 00237 if (m_freeBlockCount == 0) 00238 { 00239 return false; 00240 } 00241 else 00242 { 00243 const size_type theOffset = 00244 this->getBlockOffset(theObject); 00245 00246 return m_freeList.isSet(theOffset); 00247 } 00248 } 00249 00250 /* 00251 * Add a block to the free list. The behavior is 00252 * undefined if the object pointed to is not owned by the 00253 * block. 00254 * 00255 * @param theObject the address of the object 00256 */ 00257 void 00258 addToFreeList(const ObjectType* theObject) 00259 { 00260 const size_type theOffset = 00261 this->getBlockOffset(theObject); 00262 00263 m_freeList.set(theOffset); 00264 00265 ++m_freeBlockCount; 00266 } 00267 00268 /* 00269 * Remove a block from the free list. The behavior is 00270 * undefined if the object pointed to is not owned by the 00271 * block. 00272 * 00273 * @param theObject the address of the object 00274 */ 00275 void 00276 removeFromFreeList(const ObjectType* theObject) 00277 { 00278 const size_type theOffset = 00279 this->getBlockOffset(theObject); 00280 00281 m_freeList.clear(theOffset); 00282 00283 --m_freeBlockCount; 00284 } 00285 00286 /* 00287 * Get the next block from the free list. Returns 0 if 00288 * the free list is empty. 00289 * 00290 * @return the address of the block 00291 */ 00292 ObjectType* 00293 getNextFromFreeList() 00294 { 00295 ObjectType* theResult = 0; 00296 00297 if (m_freeBlockCount > 0) 00298 { 00299 const size_type theFreeListSize = m_freeList.getSize(); 00300 00301 for(size_type i = 0; i < theFreeListSize; ++i) 00302 { 00303 if (m_freeList.isSet(i) == true) 00304 { 00305 // Note that this-> is required by template lookup rules. 00306 theResult = this->getBlockAddress(i); 00307 00308 break; 00309 } 00310 } 00311 } 00312 00313 return theResult; 00314 } 00315 00316 // Bitmap which tracks which blocks are not in use 00317 // and that should not be destroyed. 00318 XalanBitmap m_freeList; 00319 00320 // The number of blocks on the free list.) 00321 size_type m_freeBlockCount; 00322 }; 00323 00324 00325 00326 XALAN_CPP_NAMESPACE_END 00327 00328 00329 00330 #endif // !defined(REUSABLEARENABLOCK_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.6 |
|