## Xalan-C++ API Documentation

### The Xalan C++ XSLT Processor Version 1.9

Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members | Related Pages

# XalanArrayAllocator.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 #if !defined(XALANARRAYALLOCATOR_HEADER_GUARD_1357924680)
    00017 #define XALANARRAYALLOCATOR_HEADER_GUARD_1357924680
    00018
    00019
    00020
    00021 #include <xalanc/PlatformSupport/PlatformSupportDefinitions.hpp>
    00022
    00023
    00024
    00025 #include <cassert>
    00026 #include <utility>
    00027
    00028
    00029 #include <xalanc/Include/XalanMemMgrHelper.hpp>
    00030 #include <xalanc/Include/XalanVector.hpp>
    00031 #include <xalanc/Include/XalanList.hpp>
    00032
    00033
    00034
    00035 XALAN_CPP_NAMESPACE_BEGIN
    00036
    00037
    00038
    00039 template<class Type>
    00040 class XALAN_PLATFORMSUPPORT_EXPORT XalanArrayAllocator
    00041 {
    00042 public:
    00043
    00044     typedef XalanVector<Type>               VectorType;
    00045     typedef typename VectorType::size_type  size_type;
    00046
    00047     typedef XALAN_STD_QUALIFIER pair<size_type, VectorType * >      ListEntryType;
    00048     typedef XalanList<ListEntryType>                                ListType;
    00049
    00050     typedef Type                            value_type;
    00051
    00052     typedef typename ListType::iterator     ListIteratorType;
    00053
    00054     // Default size for vector allocation.
    00055     enum { eDefaultBlockSize = 500 };
    00056
    00062     XalanArrayAllocator(MemoryManagerType&       theManager,
    00063                         size_type   theBlockSize = eDefaultBlockSize) :
    00064         m_list(theManager),
    00065         m_blockSize(theBlockSize),
    00066         m_lastEntryFound(0)
    00067     {
    00068     }
    00069
    00070     ~XalanArrayAllocator()
    00071     {
    00072         typename ListType::iterator iter = m_list.begin();
    00073
    00074         MemoryManagerType& theManager = m_list.getMemoryManager();
    00075
    00076         for( iter = m_list.begin(); iter != m_list.end(); ++iter)
    00077         {
    00078             if( (*iter).second != 0)
    00079             {
    00080 #if defined(XALAN_REQUIRES_QUALIFIED_DESTRUCTOR)
    00081                 (*iter).second->VectorType::~VectorType();
    00082 #else
    00083                 (*iter).second->~VectorType();
    00084 #endif
    00085                 theManager.deallocate((void*)(*iter).second);
    00086             }
    00087         }
    00088     }
    00089
    00093     void
    00094     clear()
    00095     {
    00096         m_list.clear();
    00097
    00098         m_lastEntryFound = 0;
    00099     }
    00100
    00106     void
    00107     reset()
    00108     {
    00109         if (m_list.empty() == true)
    00110         {
    00111             m_lastEntryFound = 0;
    00112         }
    00113         else
    00114         {
    00115             const ListIteratorType  theEnd = m_list.end();
    00116             ListIteratorType        theCurrent = m_list.begin();
    00117
    00118             do
    00119             {
    00120                 (*theCurrent).first = (*theCurrent).second->size();
    00121
    00122                 ++theCurrent;
    00123             } while(theCurrent != theEnd);
    00124
    00125             m_lastEntryFound = &*m_list.begin();
    00126         }
    00127     }
    00128
    00135     Type*
    00136     allocate(size_type  theCount)
    00137     {
    00138         // Handle the case of theCount being greater than the block size first...
    00139         if (theCount >= m_blockSize)
    00140         {
    00141             return createEntry(theCount, theCount);
    00142         }
    00143         else
    00144         {
    00145             ListEntryType*  theEntry =
    00146                 findEntry(theCount);
    00147
    00148             // Did we find a slot?
    00149             if (theEntry == 0)
    00150             {
    00151                 // Nope, create a new one...
    00152                 return createEntry(m_blockSize, theCount);
    00153             }
    00154             else
    00155             {
    00156                 // The address we want is that of the first free element in the
    00157                 // vector...
    00158                 assert( theEntry->second != 0);
    00159                 Type* const     thePointer =
    00160                     &*theEntry->second->begin() + (theEntry->second->size() - theEntry->first);
    00161
    00162                 // Resize the vector to the appropriate size...
    00163                 theEntry->first -= theCount;
    00164
    00165                 return thePointer;
    00166             }
    00167         }
    00168     }
    00169
    00170 private:
    00171
    00172     // Utility functions...
    00173     Type*
    00174     createEntry(
    00175             size_type   theBlockSize,
    00176             size_type   theCount)
    00177     {
    00178         assert(theBlockSize >= theCount);
    00179
    00180         // Push on a new entry.  The entry has no open space,
    00181         // since it's greater than our block size...
    00182         m_list.push_back(ListEntryType(0, VectorType::create(m_list.getMemoryManager())));
    00183
    00184         // Get the new entry...
    00185         ListEntryType&  theNewEntry = m_list.back();
    00186
    00187         // Resize the vector to the appropriate size...
    00188         assert(theNewEntry.second);
    00189
    00190         theNewEntry.second->resize(theBlockSize, value_type());
    00191
    00192         // Set the number of free spaces accordingly...
    00193         theNewEntry.first = theBlockSize - theCount;
    00194
    00195         if (theNewEntry.first != 0)
    00196         {
    00197             m_lastEntryFound = &theNewEntry;
    00198         }
    00199
    00200         // Return a pointer to the beginning of the allocated memory...
    00201         return &*theNewEntry.second->begin();
    00202     }
    00203
    00204     ListEntryType*
    00205     findEntry(size_type     theCount)
    00206     {
    00207         // Search for an entry that has some free space.
    00208
    00209         if (m_lastEntryFound != 0 && m_lastEntryFound->first >= theCount)
    00210         {
    00211             return m_lastEntryFound;
    00212         }
    00213         else
    00214         {
    00215             const ListIteratorType  theEnd = m_list.end();
    00216             ListIteratorType        theCurrent = m_list.begin();
    00217
    00218             ListEntryType*  theEntry = 0;
    00219
    00220             while(theCurrent != theEnd)
    00221             {
    00222                 // We're looking for the best fit, so
    00223                 // if the free space and the count we're
    00224                 // looking for are equal, that's pretty
    00225                 // much the best we can do...
    00226                 if ((*theCurrent).first == theCount)
    00227                 {
    00228                     theEntry = &*theCurrent;
    00229
    00230                     break;
    00231                 }
    00232                 else if ((*theCurrent).first >= theCount)
    00233                 {
    00234                     // If we haven't found anything yet, the first
    00235                     // entry we find that's large enough becomes
    00236                     // our best fit.
    00237                     //
    00238                     // Otherwise, we'll assume that a smaller
    00239                     // slot is a better fit, though I may be
    00240                     // wrong about this...
    00241                     if (theEntry == 0 ||
    00242                         (*theCurrent).first < theEntry->first)
    00243                     {
    00244                         // Nope, so this becomes our best-fit so far.
    00245                         theEntry = &*theCurrent;
    00246                     }
    00247
    00248                     ++theCurrent;
    00249                 }
    00250                 else
    00251                 {
    00252                     // Won't fit, so just continue...
    00253                     ++theCurrent;
    00254                 }
    00255             }
    00256
    00257             m_lastEntryFound = theEntry;
    00258
    00259             return theEntry;
    00260         }
    00261     }
    00262
    00263     // Not implemented...
    00264     XalanArrayAllocator(const XalanArrayAllocator<Type>&    theSource);
    00265
    00266     XalanArrayAllocator<Type>&
    00267     operator=(const XalanArrayAllocator<Type>&  theSource);
    00268
    00269     bool
    00270     operator==(const XalanArrayAllocator<Type>& theRHS) const;
    00271
    00272
    00273     // Data members...
    00274     ListType            m_list;
    00275
    00276     const size_type     m_blockSize;
    00277
    00278     ListEntryType*      m_lastEntryFound;
    00279 };
    00280
    00281
    00282
    00283 XALAN_CPP_NAMESPACE_END
    00284
    00285
    00286
    00287 #endif  // !defined(XALANARRAYALLOCATOR_HEADER_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.9 Copyright © 1999-2004 The Apache Software Foundation. All Rights Reserved.