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

panda/src/putil/uniqueIdAllocator.cxx

Go to the documentation of this file.
00001 // Filename: uniqueIdAllocator.cxx
00002 // Created by:  schuyler 2003-03-13
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
00016 //
00017 ////////////////////////////////////////////////////////////////////
00018 // 
00019 
00020 #include "pandabase.h"
00021 #include "notify.h"
00022 
00023 #include "uniqueIdAllocator.h"
00024 
00025 NotifyCategoryDecl(uniqueIdAllocator, EXPCL_PANDA, EXPTP_PANDA);
00026 NotifyCategoryDef(uniqueIdAllocator, "");
00027 
00028 #ifndef NDEBUG //[
00029   // Non-release build:
00030   #define uniqueIdAllocator_debug(msg) \
00031   if (uniqueIdAllocator_cat.is_debug()) { \
00032     uniqueIdAllocator_cat->debug() << msg << endl; \
00033   } else {}
00034 
00035   #define uniqueIdAllocator_info(msg) \
00036     uniqueIdAllocator_cat->info() << msg << endl
00037 
00038   #define uniqueIdAllocator_warning(msg) \
00039     uniqueIdAllocator_cat->warning() << msg << endl
00040 #else //][
00041   // Release build:
00042   #define uniqueIdAllocator_debug(msg) ((void)0)
00043   #define uniqueIdAllocator_info(msg) ((void)0)
00044   #define uniqueIdAllocator_warning(msg) ((void)0)
00045 #endif //]
00046 
00047 #define audio_error(msg) \
00048   audio_cat->error() << msg << endl
00049 
00050 ////////////////////////////////////////////////////////////////////
00051 //     Function: 
00052 //       Access: 
00053 //  Description: Create a free id pool in the range [min:max].
00054 ////////////////////////////////////////////////////////////////////
00055 UniqueIdAllocator::
00056 UniqueIdAllocator(U32 min, U32 max)
00057   : _min(min), _max(max) {
00058   uniqueIdAllocator_debug("UniqueIdAllocator("<<min<<", "<<max<<")");
00059   _size=_max-_min+1; // +1 because min and max are inclusive.
00060   nassertv(_size); // size must be > 0.
00061   _table=new U32[_size];
00062   nassertv(_table); // This should be redundant if new throws an exception.
00063   for (U32 i=0; i<_size; ++i) {
00064     _table[i]=i+1;
00065   }
00066   _table[_size-1]=IndexEnd;
00067   _next_free=0;
00068   _last_free=_size-1;
00069   _free=_size;
00070 }
00071 
00072 ////////////////////////////////////////////////////////////////////
00073 //     Function: 
00074 //       Access: 
00075 //  Description: 
00076 ////////////////////////////////////////////////////////////////////
00077 UniqueIdAllocator::
00078 ~UniqueIdAllocator() {
00079   uniqueIdAllocator_debug("~UniqueIdAllocator()");
00080   delete [] _table;
00081 }
00082 
00083 
00084 ////////////////////////////////////////////////////////////////////
00085 //     Function: 
00086 //       Access: 
00087 //  Description: Receive an id between _min and _max (that were passed
00088 //               to the constructor).
00089 //               IndexEnd is returned if no ids are available.
00090 ////////////////////////////////////////////////////////////////////
00091 U32 UniqueIdAllocator::
00092 allocate() {
00093   if (_next_free==IndexEnd) {
00094     // ...all ids allocated.
00095     uniqueIdAllocator_warning("allocate Error: no more free ids.");
00096     return IndexEnd;
00097   }
00098   U32 id=_min+_next_free;
00099   _next_free=_table[_next_free];
00100   #ifndef NDEBUG //[
00101     _table[id-_min]=IndexAllocated;
00102   #endif //]
00103   --_free;
00104   uniqueIdAllocator_debug("allocate() returning "<<id);
00105   return id;
00106 }
00107 
00108 
00109 ////////////////////////////////////////////////////////////////////
00110 //     Function: 
00111 //       Access: 
00112 //  Description: Free an allocated index (index must be between _min
00113 //               and _max that were passed to the constructor).
00114 ////////////////////////////////////////////////////////////////////
00115 void UniqueIdAllocator::
00116 free(U32 index) {
00117   uniqueIdAllocator_debug("free("<<index<<")");
00118   nassertv(index>=_min); // Attempt to free out-of-range id.
00119   nassertv(index<=_max); // Attempt to free out-of-range id.
00120   index=index-_min; // Convert to _table index.
00121   nassertv(_table[index]==IndexAllocated); // Attempt to free non-allocated id.
00122   _table[index]=IndexEnd; // Mark this element as the end of the list.
00123   _table[_last_free]=index;
00124   if (_next_free==IndexEnd) {
00125     // ...the free list was empty.
00126     _next_free=index;
00127   }
00128   _last_free=index;
00129   ++_free;
00130 }
00131 
00132 
00133 ////////////////////////////////////////////////////////////////////
00134 //     Function: 
00135 //       Access: 
00136 //  Description: return what percentage of the pool is used.  The 
00137 //               range is 0 to 1.0, so 75% would be 0.75, for example.
00138 ////////////////////////////////////////////////////////////////////
00139 float UniqueIdAllocator::
00140 percent_used() const {
00141   return float(_size-_free)/_size;
00142 }
00143 
00144 
00145 ////////////////////////////////////////////////////////////////////
00146 //     Function: 
00147 //       Access: 
00148 //  Description: ...intended for debugging only.
00149 ////////////////////////////////////////////////////////////////////
00150 void UniqueIdAllocator::
00151 output(ostream& os, bool verbose) const {
00152   os  <<"[_next_free: "<<long(_next_free)
00153       <<"; _last_free: "<<long(_last_free)
00154       <<"; _size: "<<_size
00155       <<"; _free: "<<_free
00156       <<"; used: "<<_size-_free
00157       <<"; %used: "<<float(_size-_free)/_size;
00158   if (verbose) {
00159     os <<";\n     ";
00160     for (U32 i=0; i<_size; ++i) {
00161       os<<long(_table[i])<<", ";
00162     }
00163   }
00164   os<<"]"<<endl;
00165 }
00166 

Generated on Fri May 2 00:43:47 2003 for Panda by doxygen1.3