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