cgma
|
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