1 //abstraction used in burst tries to allow tries to contain either tries or terms as children 2 3 4 5 struct trieElem 6 { 7 bool isTrie; 8 void* myVal; 9 10 trieElem* next; 11 }; 12 13 template<class T, class S> class BTrieIterator; 14 15 template<class T, class S> 16 class BurstTerm 17 { 18 public: BurstTerm(int myLength)19 BurstTerm(int myLength) 20 { 21 length = myLength; 22 exps = new S[length]; 23 } 24 BurstTerm(const T & newCoef,S * newExps,int start,int myLength,int myDegree)25 BurstTerm(const T& newCoef, S* newExps, int start, int myLength, 26 int myDegree) 27 { 28 degree = myDegree; 29 length = myLength - start; 30 exps = new S[length]; 31 for (int i = start; i < myLength; i++) 32 { 33 exps[i - start] = newExps[i]; 34 } 35 coef = newCoef; 36 next = NULL; 37 } 38 ~BurstTerm()39 ~BurstTerm() 40 { 41 //cout << "Destroying term" << endl; 42 //if (length > 0 && exps) 43 if (exps) 44 { 45 delete[] exps; 46 } 47 } 48 lessThan(BurstTerm<T,S> * other,bool & equal)49 bool lessThan(BurstTerm<T, S>* other, bool &equal) 50 { 51 equal = false; 52 if (degree < other->degree) 53 { 54 return true; 55 } 56 if (degree > other->degree) 57 { 58 return false; 59 } 60 for (int i = 0; i < length && i < other->length; i++) 61 { 62 //cout << "Comparing " << exps[i] << " v. " << other->exps[i] << endl; 63 if (exps[i] < other->exps[i]) 64 { 65 return true; 66 } 67 if (exps[i] > other->exps[i]) 68 { 69 return false; 70 } 71 } 72 assert(length == other->length); 73 /* 74 * too general, shouldn't be encountered 75 if (length < other->length) { return true; } 76 if (length > other->length) { return false; } 77 */ 78 equal = true; 79 return false; 80 } 81 82 BurstTerm<T, S>* next; 83 84 T coef; 85 S* exps; 86 int length; 87 int degree; 88 }; //BurstTerm 89 90 template<class T, class S> 91 class BurstContainer 92 { 93 public: BurstContainer()94 BurstContainer() 95 { 96 //cout << "New container" << endl; 97 firstTerm = NULL; 98 termCount = 0; 99 } 100 ~BurstContainer()101 ~BurstContainer() 102 { 103 //cout << "Destroying container (" << termCount << " terms) ..." << endl; 104 BurstTerm<T, S> *temp, *old; 105 106 107 //temp = firstTerm; 108 for(old = firstTerm; old; old = temp) 109 { 110 temp = old->next; 111 delete old; 112 } 113 //for (int i = 0; i < termCount; i++) 114 //{ 115 // old = temp->next; 116 // delete temp; 117 // temp = old; 118 //} 119 //assert(old == NULL); 120 //Brandon Aug 3 2010. I'm trying to find the source of a memory leak. The old for loop does not pass the assert on my test polynomial/polytope. 121 //I updated to the uncommented for-loop. TODO: find out if there is a serious flaw if the termCount != the number of items in the linked list. 122 } 123 insertTerm(const T & newCoef,S * newExps,int start,int myLength,int myDegree)124 void insertTerm(const T& newCoef, S* newExps, int start, int myLength, 125 int myDegree) 126 { 127 //cout << "Inserting term into container" << endl; 128 if (firstTerm == NULL) 129 { 130 firstTerm = new BurstTerm<T, S> (newCoef, newExps, start, myLength, 131 myDegree); 132 termCount++; 133 return; 134 } 135 136 bool equal; 137 BurstTerm<T, S>* newTerm = new BurstTerm<T, S> (newCoef, newExps, 138 start, myLength, myDegree); 139 if (newTerm->lessThan(firstTerm, equal)) 140 { 141 newTerm->next = firstTerm; 142 firstTerm = newTerm; 143 termCount++; 144 return; 145 } 146 if (equal) 147 { 148 firstTerm->coef += newTerm->coef; 149 delete newTerm; 150 return; 151 } 152 153 BurstTerm<T, S> *curTerm = firstTerm; 154 BurstTerm<T, S> *oldTerm; 155 156 while (curTerm && curTerm->lessThan(newTerm, equal)) 157 { 158 oldTerm = curTerm; 159 curTerm = curTerm->next; 160 } 161 if (equal) 162 { 163 curTerm->coef += newTerm->coef; 164 delete newTerm; 165 return; 166 } 167 168 if (curTerm == NULL) 169 { 170 oldTerm->next = newTerm; 171 } else //oldTerm < newTerm < curTerm 172 { 173 oldTerm->next = newTerm; 174 newTerm->next = curTerm; 175 } 176 termCount++; 177 } 178 burst()179 BurstTrie<T, S>* burst() 180 { 181 BurstTrie<T, S>* myTrie = new BurstTrie<T, S> (); 182 BurstTerm<T, S>* curTerm = firstTerm; 183 BurstTerm<T, S>* oldTerm; 184 for (int i = 0; i < termCount; i++) 185 { 186 myTrie->insertTerm(curTerm->coef, curTerm->exps, 0, 187 curTerm->length, curTerm->degree); 188 oldTerm = curTerm->next; 189 curTerm = oldTerm; 190 } 191 return myTrie; 192 } 193 getTerm(int index)194 BurstTerm<T, S>* getTerm(int index) 195 { 196 assert(index < termCount); 197 BurstTerm<T, S>* myTerm = firstTerm; 198 for (int i = 0; i < index; i++) 199 { 200 myTerm = myTerm->next; 201 } 202 return myTerm; 203 } 204 205 int termCount; 206 friend class BTrieIterator<T, S> ; 207 private: 208 BurstTerm<T, S>* firstTerm; 209 }; //BurstContainer 210 211 template<class T, class S> 212 class BurstTrie 213 { 214 public: BurstTrie()215 BurstTrie() 216 { 217 //curIndex = -1; 218 range = NULL; 219 firstElem = NULL; 220 } 221 ~BurstTrie()222 ~BurstTrie() 223 { 224 //cout << "Destroying trie" << endl; 225 if (range) 226 { 227 delete[] range; 228 } 229 trieElem *temp = firstElem; 230 trieElem *old; 231 while (temp != NULL) 232 { 233 //cout << "Destroying trie element.." << endl; 234 //destroy element container or trie 235 if (temp->isTrie) 236 { 237 delete ((BurstTrie<T, S>*) temp->myVal); 238 } else 239 { 240 delete ((BurstContainer<T, S>*) temp->myVal); 241 } 242 old = temp->next; 243 //destroy trieElem 244 free(temp); 245 temp = old; 246 }//while 247 248 249 }//~BurstTrie() 250 insertTerm(const T & newCoef,S * newExps,int start,int myLength,int myDegree)251 void insertTerm(const T& newCoef, S* newExps, int start, int myLength, 252 int myDegree) 253 { 254 assert(myLength > 0); 255 /*cout << "Inserting term into trie: " << newCoef; 256 for (int i = start; i < myLength; i++) 257 { 258 cout << ", " << newExps[i]; 259 } 260 cout << endl;*/ 261 if (range == NULL) 262 { 263 range = new S[2]; 264 range[0] = range[1] = newExps[0]; 265 firstElem = (trieElem*) malloc(sizeof(trieElem)); 266 firstElem->next = NULL; 267 firstElem->myVal = new BurstContainer<T, S> (); 268 firstElem->isTrie = false; 269 } else 270 { 271 checkRange(newExps[start]); 272 } 273 274 trieElem *curElem = firstElem; 275 for (S i = range[0]; i < newExps[start]; i++) 276 { 277 curElem = curElem->next; 278 } 279 280 if (curElem->isTrie) 281 { 282 ((BurstTrie<T, S>*) curElem->myVal)->insertTerm(newCoef, newExps, 283 start + 1, myLength, myDegree); 284 } else 285 { 286 BurstContainer<T, S>* temp = (BurstContainer<T, S>*) curElem->myVal; 287 //cout << "Trie element is a container (" << temp->termCount << " elements)" << endl; 288 if (temp->termCount == BURST_MAX && (myLength - start) > 1) 289 { 290 //cout << "Bursting container..." << endl; 291 BurstTrie<T, S>* newTrie = temp->burst(); 292 //cout << "Burst trie created, deleting container" << endl; 293 delete temp; 294 curElem->isTrie = true; 295 curElem->myVal = newTrie; 296 newTrie->insertTerm(newCoef, newExps, start + 1, myLength, 297 myDegree); 298 } else 299 { 300 temp->insertTerm(newCoef, newExps, start + 1, myLength, 301 myDegree); 302 } 303 } 304 } 305 checkRange(const S & myVal)306 void checkRange(const S& myVal) 307 { 308 if (myVal < range[0]) //new minimum 309 { 310 trieElem *temp = (trieElem*) malloc(sizeof(trieElem)); //new first element for myVal 311 trieElem *old = temp; 312 temp->next = NULL; 313 temp->myVal = new BurstContainer<T, S> (); 314 temp->isTrie = false; 315 for (S i = myVal + 1; i < range[0]; i++) 316 { 317 //create new element 318 temp->next = (trieElem*) malloc(sizeof(trieElem)); 319 //advance to it 320 temp = temp->next; 321 //set pointer 322 temp->next = NULL; 323 //allocate container 324 temp->myVal = new BurstContainer<T, S> (); 325 temp->isTrie = false; 326 } 327 temp->next = firstElem; 328 //set new first element 329 firstElem = old; 330 range[0] = myVal; 331 } else if (myVal > range[1]) //new maximum 332 { 333 trieElem *temp = firstElem; 334 for (S i = range[0]; i < range[1]; i++) 335 { 336 temp = temp->next; 337 } 338 for (S i = range[1]; i < myVal; i++) 339 { 340 temp->next = (trieElem*) malloc(sizeof(trieElem)); 341 temp = temp->next; 342 temp->next = NULL; 343 temp->myVal = new BurstContainer<T, S> (); 344 temp->isTrie = false; 345 } 346 range[1] = myVal; 347 } 348 } 349 350 friend class BTrieIterator<T, S> ; 351 private: 352 S* range; //S can be a class or a primitve 353 trieElem *firstElem; //first element in the trie 354 }; //BurstTrie 355