cgma
ArrayBasedContainer.cpp
Go to the documentation of this file.
00001 //- Class: ArrayBasedContainer
00002 //- Owner: Paul Kinney
00003 //- Checked by:
00004 //- Version: $Id: 
00005 
00006 #include "ArrayBasedContainer.hpp"
00007 #include "CubitDefines.h"
00008 #include <cstring>
00009 #include <cassert>
00010 
00011 unsigned int ArrayBasedContainer::currentAllocatedMemory = 0;
00012 unsigned int ArrayBasedContainer::maxAllocatedMemory = 0;
00013 
00014 //- Constructor: Create a list with initial size {increment}. The list
00015 //- will be grown by {increment} each time it is filled. Memory for the
00016 //- list is not allocated until the first element is inserted using
00017 //- {insertLink}. 
00018 //- If {increment} is zero, the default increment ({INCREMENT}) will be used
00019 //- From an efficiency standpoint, it is very important that the 
00020 //- increment be set large enough to reduce the number of list 
00021 //- growths, but small enough to not waste memory.
00022 //- It is more efficient to sligthly overestimate the increment than 
00023 //- to underestimate the increment.
00024 ArrayBasedContainer::ArrayBasedContainer ( int increment )
00025 {
00026   if ( increment > 0)
00027     {
00028       listIncrement = increment;
00029     }
00030   else
00031     {
00032       listIncrement = INCREMENT;
00033     }
00034   itemCount  = 0;
00035   listLength = 0;
00036   listArray  = 0;
00037   poolAllocated = CUBIT_FALSE;
00038   listIsSorted  = CUBIT_FALSE;
00039 }
00040 
00041 //- Copy Constructor
00042 //- Uses memory from ArrayMemory if size is default
00043 ArrayBasedContainer::ArrayBasedContainer(const ArrayBasedContainer& from)
00044 {
00045   listLength = from.listLength;
00046   listIncrement = from.listIncrement;
00047   poolAllocated = from.poolAllocated;
00048   listIsSorted  = from.listIsSorted;
00049   listArray = NULL;
00050 
00051   if (listLength)
00052     {
00053       if (listLength == INCREMENT && (int)listIncrement == INCREMENT) {
00054     listArray = (void **)new ArrayMemory;
00055     poolAllocated = CUBIT_TRUE;
00056       }
00057       else {
00058     listArray = new void* [listLength];
00059     poolAllocated = CUBIT_FALSE;
00060     currentAllocatedMemory += listLength;
00061     if (currentAllocatedMemory > maxAllocatedMemory)
00062       maxAllocatedMemory = currentAllocatedMemory;
00063       }
00064       assert(listArray != 0);
00065     }
00066 
00067   itemCount     = from.itemCount;
00068 
00069   if (itemCount)
00070     memcpy (listArray, from.listArray, itemCount*sizeof(void*));
00071 }
00072 
00073 ArrayBasedContainer::~ArrayBasedContainer()
00074 {
00075     if ( listLength )
00076     { 
00077       if (poolAllocated) {
00078     delete ((ArrayMemory*) listArray);
00079       }
00080       else {
00081         delete [] listArray;
00082     currentAllocatedMemory -= listLength;
00083       }
00084       listArray = NULL;
00085     }
00086 }
00087 
00088 
00089 void ArrayBasedContainer::lengthen_list()
00090 {
00091   void **tempArray = 0;
00092   if (listLength == 0 && (int)listIncrement == INCREMENT)
00093   {
00094     poolAllocated = CUBIT_TRUE;
00095     listArray = (void **)new ArrayMemory;
00096     assert(listArray != 0);
00097     listLength = listIncrement;
00098     return;
00099   }
00100   
00101   // Normal allocation from here to end.
00102 
00103   tempArray = new void* [listLength + listIncrement];
00104   currentAllocatedMemory += (listLength + listIncrement);
00105   if (currentAllocatedMemory > maxAllocatedMemory)
00106     maxAllocatedMemory = currentAllocatedMemory;
00107   assert(tempArray != 0);
00108   
00109   // copy the old stuff into the new array
00110   if (listLength)
00111   {
00112     memcpy ( tempArray, listArray, listLength*sizeof(void*) );
00113     // delete the old array
00114     if (poolAllocated)
00115     {
00116       delete ((ArrayMemory*) listArray);
00117     }
00118     else {
00119       delete [] listArray;
00120       currentAllocatedMemory -= listLength;
00121     }
00122   }
00123   
00124   // set the new equal to the old
00125   listArray = tempArray;
00126   
00127   // update data
00128   poolAllocated = CUBIT_FALSE;
00129   listLength += listIncrement;
00130   listIncrement *= 2;
00131   listIncrement = listIncrement > 1000000 ? 1000000 : listIncrement;
00132 }
00133 
00134 ArrayBasedContainer&
00135 ArrayBasedContainer::operator=(const ArrayBasedContainer& from)
00136 {
00137   if (this == &from)
00138     return *this;
00139   
00140   // See if the existing listArray length is equal to the from listArray
00141   // length. If it is, we can reuse it without deleting and newing.
00142   if (listLength != from.listLength) {
00143     if (listLength) {
00144       if (poolAllocated) {
00145     delete ((ArrayMemory*) listArray);
00146       } else {
00147     delete [] listArray;
00148     currentAllocatedMemory -= listLength;
00149       }
00150     }
00151     
00152     listLength = from.listLength;
00153     if (listLength)
00154       {
00155     if (listLength == INCREMENT && (int)listIncrement == INCREMENT)
00156       {
00157     listArray = (void **)new ArrayMemory;
00158     poolAllocated = CUBIT_TRUE;
00159       }
00160     else
00161       {
00162         listArray = new void* [listLength];
00163         poolAllocated = CUBIT_FALSE;
00164         currentAllocatedMemory += listLength;
00165         if (currentAllocatedMemory > maxAllocatedMemory)
00166           maxAllocatedMemory = currentAllocatedMemory;
00167       }
00168     assert(listArray != 0);
00169       }
00170   }
00171   itemCount = from.itemCount;
00172   listIncrement = from.listIncrement;
00173   listIsSorted  = from.listIsSorted;
00174   
00175   if (itemCount)
00176     memcpy (listArray, from.listArray, itemCount*sizeof(void*));
00177   
00178   return *this;
00179 }
00180 
00181 ArrayBasedContainer&
00182               ArrayBasedContainer::operator+=(const ArrayBasedContainer& from)
00183 {
00184   int tmp_itemCount = itemCount + from.itemCount;
00185   if (tmp_itemCount >= listLength)
00186     {
00187       if ((listLength + (int)listIncrement) < tmp_itemCount)
00188     {
00189       listIncrement = tmp_itemCount - listLength;
00190     }
00191       lengthen_list();
00192     }
00193   if (from.itemCount == 1)
00194     {
00195       listArray[itemCount] = from.listArray[0];
00196     }
00197   else
00198     {
00199       if (from.itemCount)
00200     memcpy (&listArray[itemCount], from.listArray,
00201         from.itemCount*sizeof(void*));
00202     }
00203   itemCount += from.itemCount;
00204   listIsSorted  = listIsSorted && from.listIsSorted;
00205   return *this;
00206 }
00207 
00208 ArrayBasedContainer& 
00209 ArrayBasedContainer::operator-=(const ArrayBasedContainer& from)
00210 {
00211   if ( !itemCount )
00212     return *this;
00213   int i, j;
00214   void *item;
00215   for ( i = 0; i < itemCount; i++ )
00216   {
00217     item = listArray[i];
00218     for ( j = from.itemCount; j--; )
00219       if ( from.listArray[j] == item ) 
00220       {
00221         listArray[i] = NULL;
00222         break;
00223       }
00224   }
00225     // compress, virtual
00226   compress();
00227   return *this;
00228 }
00229 
00230 void ArrayBasedContainer::compress()
00231 {
00232   int i, j;
00233   void *item;
00234   for ( i = j = 0; i < itemCount; i++ )
00235     if ((item = listArray[i]) != NULL) // = is ok
00236       listArray[j++] = item;
00237 }
00238 
00239 unsigned int ArrayBasedContainer::current_allocated_memory()
00240 {
00241   return currentAllocatedMemory;
00242 }
00243 
00244 unsigned int ArrayBasedContainer::maximum_allocated_memory()
00245 {
00246   return maxAllocatedMemory;
00247 }
00248 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines