Xalan-C++ API Documentation

The Xalan C++ XSLT Processor Version 1.8

Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | 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.