PLearn 0.1
PMemPool.h
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 // PMemPool.h
00004 //
00005 // Copyright (C) 2005 Nicolas Chapados 
00006 // 
00007 // Redistribution and use in source and binary forms, with or without
00008 // modification, are permitted provided that the following conditions are met:
00009 // 
00010 //  1. Redistributions of source code must retain the above copyright
00011 //     notice, this list of conditions and the following disclaimer.
00012 // 
00013 //  2. Redistributions in binary form must reproduce the above copyright
00014 //     notice, this list of conditions and the following disclaimer in the
00015 //     documentation and/or other materials provided with the distribution.
00016 // 
00017 //  3. The name of the authors may not be used to endorse or promote
00018 //     products derived from this software without specific prior written
00019 //     permission.
00020 // 
00021 // THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
00022 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00023 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
00024 // NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00025 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
00026 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00027 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00028 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00029 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00030 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00031 // 
00032 // This file is part of the PLearn library. For more information on the PLearn
00033 // library, go to the PLearn Web site at www.plearn.org
00034 
00035 /* *******************************************************      
00036  * $Id: PMemPool.h 3994 2005-08-25 13:35:03Z chapados $ 
00037  ******************************************************* */
00038 
00039 // Authors: Nicolas Chapados
00040 
00044 #ifndef PMemPool_INC
00045 #define PMemPool_INC
00046 
00047 // From C++ stdlib
00048 #include <new>
00049 #include <list>
00050 #include <map>
00051 
00052 // From PLearn
00053 #include "PP.h"
00054 
00055 namespace PLearn {
00056 
00057 // Forward-declaration
00058 class PMemPool;
00059 
00060 //#####  PMemArena  ###########################################################
00061 
00075 class PMemArena : public PPointable
00076 {
00077     friend class PMemPool;                     
00078   
00079 protected:
00080     void* storage;                             
00081     void* end_of_storage;                      
00082     size_t object_size;                        
00083     size_t allocated_objects;                  
00084     char* watermark;                           
00085     void* free_list;                           
00086 
00088     union Aligner {
00089         char a;
00090         int b;
00091         long c;
00092         double d;
00093         void* x;
00094     };
00095 
00096 public:
00099     PMemArena(size_t object_size, size_t max_num_objects);
00100 
00103     ~PMemArena();
00104   
00106     inline void* allocate();
00107 
00109     void deallocate(void* p);
00110 
00113     bool belongsToArena(void* p) const
00114     { return p >= storage && p < end_of_storage; }
00115 
00117     bool empty() const { return allocated_objects == 0; }
00118 
00119 private:
00121     PMemArena(const PMemArena&);
00122     void operator=(const PMemArena&);
00123 };
00124 
00125 
00126 //#####  PMemPool  ############################################################
00127 
00145 class PMemPool : public PPointable
00146 {
00147 protected:
00148     std::list< PP<PMemArena> > arenas; 
00149     PMemArena* last_arena;             
00150     size_t object_size;                
00151     size_t initial_arena_size;         
00152     size_t cur_arena_size;             
00153     float arena_growth_factor;         
00154     map<void*, PMemArena*> stormap;    
00155     bool fast_deallocate;              
00156     void* free_list;
00157 
00158 public:
00162     PMemPool(size_t object_size, size_t initial_arena_size,
00163              float growth_factor = 1.5,
00164              bool use_fast_deallocator = true);
00165 
00166     // Default destructor is OK
00167 
00169     void* allocate();
00170 
00174     void deallocate(void* p);
00175 
00177     bool empty() const { return arenas.size() == 0; }
00178 
00180     void purge_memory();
00181   
00182 protected:
00185     void* allocateFromArenas();
00186   
00188     PMemArena* newArena();
00189 };
00190 
00191 
00192 //#####  PObjectPool  #########################################################
00193 
00200 template <class T>
00201 class PObjectPool : public PMemPool
00202 {
00203     typedef PMemPool inherited;
00204   
00205 public:
00206     PObjectPool(size_t initial_arena_size, float growth_factor = 1.5,
00207                 bool use_fast_deallocator = true)
00208         : inherited(sizeof(T), initial_arena_size, growth_factor,
00209                     use_fast_deallocator)
00210     { }
00211 
00213     T* allocate() { return static_cast<T*>(inherited::allocate()); }
00214 
00217     void deallocate(T* p) { inherited::deallocate(p); }
00218 };
00219 
00220 
00221 
00222 //#####  PSystemPool  #########################################################
00223 
00228 //#####  Some Implementations  ################################################
00229 
00230 inline void* PMemArena::allocate()
00231 {
00232     // See if we can allocate from watermark
00233     if (watermark > storage) {
00234         watermark -= object_size;
00235         allocated_objects++;
00236         return watermark;
00237     }
00238     // Otherwise check if we can allocate from free list
00239     else if (free_list) {
00240         void** to_return = static_cast<void**>(free_list);
00241         free_list = *to_return;
00242         allocated_objects++;
00243         return to_return;
00244     }
00245     // Otherwise, cannot allocate at all: return NULL
00246     else
00247         return 0;
00248 }
00249 
00250 } // end of namespace PLearn
00251 
00252 
00253 #endif
00254 
00255 
00256 /*
00257   Local Variables:
00258   mode:c++
00259   c-basic-offset:4
00260   c-file-style:"stroustrup"
00261   c-file-offsets:((innamespace . 0)(inline-open . 0))
00262   indent-tabs-mode:nil
00263   fill-column:79
00264   End:
00265 */
00266 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=79 :
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines