Back to index

lightning-sunbird  0.9+nobinonly
nsRecycled.h
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Ilya Konstantinov (mozilla-code@future.shiny.co.il)
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either the GNU General Public License Version 2 or later (the "GPL"), or
00027  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 #ifndef nsRecycled_h__
00040 #define nsRecycled_h__
00041 
00042 #include "nsAutoPtr.h"
00043 #include "prtypes.h"
00044 
00045 /*
00046  * A simple one-object recycler.
00047  * Derive from this class if usually only one heap-allocated instance of your class
00048  * exists at a time. This class accelerates heap allocations by keeping around
00049  * a pre-allocated buffer the size of a single instance of your class.
00050  *
00051  * The OwnerType template parameter is given to differentiate inheriting classes. For instance,
00052  * nsFoo should inherit from nsRecycledSingle<nsFoo>. If a hierarchy inherits from nsFoo,
00053  * the same preallocated buffer would be used for instances of all derived classes, so you
00054  * should ensure that usually only one instance of any of those classes exists at a time.
00055  *
00056  * Example:
00057  *  class nsFoo : public nsIBar, nsRecycledSingle<nsFoo>
00058  *  {
00059  *     ...
00060  *  };
00061  *
00062  */
00063 template<class OwnerType>
00064 class nsRecycledSingle
00065 {
00066 public:
00067   /* Initializes the memory to 0. */
00068   void* operator new(size_t sz) CPP_THROW_NEW
00069   {
00070       void* result = nsnull;
00071   
00072       if (!gPoolInUse)
00073       {
00074          if (gPoolSize >= sz)
00075          {
00076             result = gPool;
00077          }
00078          else
00079          {
00080             // Original pool, if any, is deleted by this plain assignment.
00081             result = ::operator new(sz);
00082             gPool = (char*)result;
00083             gPoolSize = sz;
00084          }
00085          gPoolInUse = PR_TRUE;
00086       }
00087       else
00088       {
00089          if (sz > gPoolSize)
00090          {
00091             // This would be a good opportunity to throw away our
00092             // current pool and replace it with this, larger one.
00093 
00094             // Original pool will die as a regular allocated buffer
00095             // when its time is due.
00096             gPool.forget();
00097             result = ::operator new(sz);
00098             gPool = (char*)result;
00099             gPoolSize = sz;
00100          }
00101          else
00102          {
00103             result = ::operator new(sz);
00104          }
00105       }
00106       
00107      if (result) {
00108         memset(result, 0, sz);
00109      }
00110      
00111      return result;
00112   }
00113 
00114   void operator delete(void* aPtr)
00115   {
00116       if (gPool == aPtr)
00117       {
00118          gPoolInUse = PR_FALSE;
00119          return;
00120       }
00121       else
00122       {
00123          ::operator delete(aPtr);
00124       }
00125   }
00126   
00127 protected:
00128   static nsAutoPtr<char> gPool;
00129   static size_t gPoolSize;
00130   static PRBool gPoolInUse;
00131 };
00132 
00133 template<class OwnerType> 
00134 nsAutoPtr<char> nsRecycledSingle<OwnerType>::gPool;
00135 template<class OwnerType> 
00136 size_t nsRecycledSingle<OwnerType>::gPoolSize = 0;
00137 template<class OwnerType> 
00138 PRBool nsRecycledSingle<OwnerType>::gPoolInUse = PR_FALSE;
00139 
00140 #endif // nsRecycled_h__