Xalan-C++ API Documentation

The Xalan-C++ XSL Transformer Version 1.0

Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

ReusableArenaBlock.hpp

Go to the documentation of this file.
00001 /*
00002  * The Apache Software License, Version 1.1
00003  *
00004  *
00005  * Copyright (c) 2000 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 <PlatformSupport/XalanBitmap.hpp>
00064 #include <PlatformSupport/ArenaBlock.hpp>
00065 
00066 
00067 
00068 
00069 template<class ObjectType>
00070 class ReusableArenaBlock : public ArenaBlock<ObjectType>
00071 {
00072 public:
00073 
00074     typedef ArenaBlock<ObjectType>  BaseClassType;
00075 
00076     /*
00077      * Construct an ArenaBlock of the specified size
00078      * of objects.
00079      *
00080      * @param theBlockSize The size of the block (the number of objects it can contain).
00081      */
00082     ReusableArenaBlock(size_type    theBlockSize) :
00083         BaseClassType(theBlockSize),
00084         m_freeList(theBlockSize),
00085         m_freeBlockCount(0)
00086     {
00087     }
00088 
00089     ~ReusableArenaBlock()
00090     {
00091         destroyAll();
00092     }
00093 
00094     /*
00095      * Allocate a block.  Once the object is constructed, you must call
00096      * commitAllocation().
00097      *
00098      * @return a pointer to the new block.
00099      */
00100     virtual ObjectType*
00101     allocateBlock()
00102     {
00103         if (m_freeBlockCount == 0)
00104         {
00105             return BaseClassType::allocateBlock();
00106         }
00107         else
00108         {
00109             return getNextFromFreeList();
00110         }
00111     }
00112 
00113     /*
00114      * Commit the previous allocation.
00115      *
00116      * @param theBlock the address that was returned by allocateBlock()
00117      */
00118     virtual void
00119     commitAllocation(ObjectType*    theBlock)
00120     {
00121         assert(theBlock != 0);
00122         assert(m_freeBlockCount == 0 ||
00123                theBlock == getNextFromFreeList());
00124 
00125         if (m_freeBlockCount == 0)
00126         {
00127             BaseClassType::commitAllocation(theBlock);
00128         }
00129         else
00130         {
00131             removeFromFreeList(theBlock);
00132         }
00133     }
00134 
00135     /*
00136      * Find out if there is a block available.
00137      *
00138      * @return true if one is available, false if not.
00139      */
00140     virtual bool
00141     blockAvailable() const
00142     {
00143         return m_freeBlockCount != 0 ? true : BaseClassType::blockAvailable();
00144     }
00145 
00146     /*
00147      * Get the number of objects currently allocated in the
00148      * block.
00149      *
00150      * @return The number of objects allocated.
00151      */
00152     virtual size_type
00153     getCountAllocated() const
00154     {
00155         return BaseClassType::getCountAllocated() - m_freeBlockCount;
00156     }
00157 
00158     /*
00159      * Determine if this block owns the specified object.  Note
00160      * that even if the object address is within our block, this
00161      * call will return false if no object currently occupies the
00162      * block.  See also ownsBlock().
00163      *
00164      * @param theObject the address of the object.
00165      * @return true if we own the object, false if not.
00166      */
00167     virtual bool
00168     ownsObject(const ObjectType*    theObject) const
00169     {
00170         return BaseClassType::ownsObject(theObject) && !isOnFreeList(theObject);
00171     }
00172 
00173     /*
00174      * Destroy the object, and return the block to the free list.
00175      * The behavior is undefined if the object pointed to is not
00176      * owned by the block.
00177      *
00178      * @param theObject the address of the object.
00179      */
00180     void
00181     destroyObject(ObjectType*   theObject)
00182     {
00183         assert(ownsObject(theObject) == true);
00184 
00185         m_destroyFunction(*theObject);
00186 
00187         addToFreeList(theObject);
00188     }
00189 
00190 protected:
00191 
00192     /*
00193      * Determine if the block should be destroyed.  Returns true,
00194      * unless the object is on the free list.  The behavior is
00195      * undefined if the object pointed to is not owned by the
00196      * block.
00197      *
00198      * @param theObject the address of the object
00199      * @return true if block should be destroyed, false if not.
00200      */
00201     virtual bool
00202     shouldDestroyBlock(const ObjectType*    theObject) const
00203     {
00204         return !isOnFreeList(theObject);
00205     }
00206 
00207 private:
00208 
00209     // Not implemented...
00210     ReusableArenaBlock(const ReusableArenaBlock<ObjectType>&);
00211 
00212     ReusableArenaBlock<ObjectType>&
00213     operator=(const ReusableArenaBlock<ObjectType>&);
00214 
00215     bool
00216     operator==(const ReusableArenaBlock<ObjectType>&) const;
00217 
00218 
00219     /*
00220      * Determine if the block is on the free list.  The behavior is
00221      * undefined if the object pointed to is not owned by the
00222      * block.
00223      *
00224      * @param theObject the address of the object
00225      * @return true if block is on the free list, false if not.
00226      */
00227     bool
00228     isOnFreeList(const ObjectType*  theObject) const
00229     {
00230         if (m_freeBlockCount == 0)
00231         {
00232             return false;
00233         }
00234         else
00235         {
00236             const size_type     theOffset =
00237                     getBlockOffset(theObject);
00238 
00239             return m_freeList.isSet(theOffset);
00240         }
00241     }
00242 
00243     /*
00244      * Add a block to the free list.  The behavior is
00245      * undefined if the object pointed to is not owned by the
00246      * block.
00247      *
00248      * @param theObject the address of the object
00249      */
00250     void
00251     addToFreeList(const ObjectType*     theObject)
00252     {
00253         const size_type     theOffset =
00254                 getBlockOffset(theObject);
00255 
00256         m_freeList.set(theOffset);
00257 
00258         ++m_freeBlockCount;
00259     }
00260 
00261     /*
00262      * Remove a block from the free list.  The behavior is
00263      * undefined if the object pointed to is not owned by the
00264      * block.
00265      *
00266      * @param theObject the address of the object
00267      */
00268     void
00269     removeFromFreeList(const ObjectType*    theObject)
00270     {
00271         const size_type     theOffset =
00272                 getBlockOffset(theObject);
00273 
00274         m_freeList.clear(theOffset);
00275 
00276         --m_freeBlockCount;
00277     }
00278 
00279     /*
00280      * Get the next block from the free list.  Returns 0 if
00281      * the free list is empty.
00282      *
00283      * @return the address of the block
00284      */
00285     ObjectType*
00286     getNextFromFreeList()
00287     {
00288         ObjectType*     theResult = 0;
00289 
00290         if (m_freeBlockCount > 0)
00291         {
00292             const unsigned long theFreeListSize = m_freeList.getSize();
00293 
00294             for(unsigned long i = 0; i < theFreeListSize; ++i)
00295             {
00296                 if (m_freeList.isSet(i) == true)
00297                 {
00298                     theResult = getBlockAddress(i);
00299 
00300                     break;
00301                 }
00302             }
00303         }
00304 
00305         return theResult;
00306     }
00307 
00308     // Bitmap which tracks which blocks are not in use
00309     // and that should not be destroyed.
00310     XalanBitmap     m_freeList;
00311 
00312     // The number of blocks on the free list.)
00313     unsigned long   m_freeBlockCount;
00314 };
00315 
00316 
00317 
00318 #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++ XSL Transformer Version 1.0
Copyright © 2000 The Apache Software Foundation. All Rights Reserved.