Overture  Version 25
PriorityQueue.h
Go to the documentation of this file.
1 #ifndef __OV_PRIORITY_QUEUE__
2 #define __OV_PRIORITY_QUEUE__
3 
4 
5 template<class T> class PriorityQueueTemplate;
6 template<class T> class PriorityQueueTemplateiterator;
7 template<class T> class PriorityQueueTemplate_constiterator;
8 
9 template<typename T>
11 {
12  friend class PriorityQueueTemplate<T>;
14 public:
16  { }
17 
18  PriorityQueueTemplateiterator ( const typename list<T>::iterator & it )
19  { listIter = it; }
20 
22  { listIter = it.listIter; }
23 
25  { listIter++; return *this; }
26 
28  { return PriorityQueueTemplateiterator<T>(listIter++); }
29 
30  T &operator*()
31  { return *listIter; }
32 
33  const T &operator*() const
34  { return *listIter; }
35 
37  { return listIter == i.listIter; }
38 
40  { return listIter != i.listIter; }
41 
42 private:
43  typename list<T>::iterator listIter;
44 
45 };
46 
47 template<typename T>
49 {
50  friend class PriorityQueueTemplate<T>;
52 
53 public:
55  { }
56 
57  PriorityQueueTemplate_constiterator ( const typename list<T>::const_iterator & it )
58  { listIter = it; }
59 
61  { listIter = it.listIter; }
62 
64  { listIter++; return *this; }
65 
67  { return PriorityQueueTemplate_constiterator<T>(listIter++); }
68 
69  const T &operator*() const
70  { return *listIter; }
71 
73  { return listIter == i.listIter; }
74 
76  { return listIter != i.listIter; }
77 
78 private:
79  typename list<T>::const_iterator listIter;
80 
81 };
82 
83 template<class T>
85 {
86 public:
89 
92 
94  { theQueue.erase(i.listIter); }
95 
96  typename PriorityQueueTemplate<T>::iterator insert(T& data, double priority)
97  { theQueue.push_back(data); return PriorityQueueTemplateiterator<T>((--theQueue.end()));}
98 
100  { return PriorityQueueTemplateiterator<T>(theQueue.begin()); }
101 
103  { return PriorityQueueTemplateiterator<T>(theQueue.end()); }
104 
105 #if 0
106  PriorityQueueTemplate<T>::const_iterator insert(T& data, double priority) const
107  { theQueue.push_back(T); return PriorityQueueTemplate_constiterator<T>(--(theQueue.end()));}
108 #endif
109 
111  { return PriorityQueueTemplate_constiterator<T>(theQueue.begin()); }
112 
114  { return PriorityQueueTemplate_constiterator<T>(theQueue.end()); }
115 
116  void clear()
117  { theQueue.clear(); }
118 
119  bool empty() const
120  { return theQueue.empty() ; }
121 
122  int size() const
123  { return theQueue.size(); }
124 
125 private:
126  list<T> theQueue;
127 };
128 
129 
130 //
131 // __ov_batchQueue_struct is a utility structure for the priority batch queue
132 // it is used to maintin both the batch itself and this priority bounds
133 //
134 template<class T>
136 {
140 };
141 
142 template<class T> class PriorityBatchQueue;
143 template<class T> class PriorityBatchQueueIterator;
144 template<class T> class PriorityBatchQueueConstIterator;
145 
146 //
147 // iterator for a PriorityBatchQueue
148 //
149 template<class T>
151 {
152  friend class PriorityBatchQueue<T>;
153 
154 public:
156  { refQueue=NULL; }
157 
159  { refQueue = it_.refQueue; batch=it_.batch; it = it_.it; }
160 
162  {
163  if ( refQueue==NULL ) throw "cannot increment uninitialized iterator";
164  if ( batch!=refQueue->end() )
165  {
166  if ( it != (*batch).queue.end() )
167  it++;
168  else
169  {
170  batch++;
171  if ( batch!=refQueue->end() ) it = (*batch).queue.begin();
172  }
173  if ( batch!=refQueue->end() )
174  if ( it == (*batch).queue.end() ) ++(*this);
175  }
176 
177  return *this;
178  }
179 
181  { refQueue = it_.refQueue; batch=it_.batch; it = it_.it; return *this;}
183  { refQueue = it_.refQueue; batch=it_.batch; it = it_.it; return *this;}
184 
186  {
187  PriorityBatchQueueIterator oldIt = *this;
188 
189  ++(*this);
190 #if 0
191  if ( refQueue==NULL ) throw "cannot increment uninitialized iterator";
192  if ( batch!=refQueue->end() )
193  if ( it != (*batch).queue.end() )
194  it++;
195  else
196  {
197  batch++;
198  if ( batch!=refQueue->end() ) it = (*batch).queue.begin();
199  }
200 #endif
201  return oldIt;
202  }
203 
204  T &operator*()
205  { return *it; }
206 
207  const T &operator*() const
208  { return *it; }
209 
211  {
212  bool areEqual = true;
213  areEqual = (refQueue == i.refQueue);
214  if ( areEqual && refQueue!=NULL )
215  {
216  if ( (areEqual = (batch == i.batch)) )
217  if ( areEqual && batch!=refQueue->end() ) areEqual = (it==i.it);
218  }
219 
220  return areEqual;
221  }
222 
224  {
225  return ! ( (*this)==i );
226  }
227 
228 
229 private:
230 
231  list< __ov_batchQueue_struct<T> > *refQueue;
232  typename list< __ov_batchQueue_struct<T> >::iterator batch;
234 
235 };
236 
237 //
238 // const_iterator for a PriorityBatchQueue
239 //
240 template<class T>
242 {
243  friend class PriorityBatchQueue<T>;
244 
245 public:
247  { refQueue=NULL; }
248 
250  { refQueue = it_.refQueue; batch=it_.batch; it = it_.it; }
251 
253  { refQueue = it_.refQueue; batch=it_.batch; it = it_.it; return *this; }
254 
255 
257  {
258  if ( refQueue==NULL ) throw "cannot increment uninitialized iterator";
259  if ( batch!=refQueue->end() )
260  {
261  if ( it != (*batch).queue.end() )
262  it++;
263  else
264  {
265  batch++;
266  if ( batch!=refQueue->end() ) it = (*batch).queue.begin();
267  }
268  if ( batch!=refQueue->end() )
269  if ( it==(*batch).queue.end() ) ++(*this);
270  }
271  return *this;
272  }
273 
275  {
276  PriorityBatchQueueConstIterator oldIt = *this;
277 
278  ++(*this);
279 #if 0
280  if ( refQueue==NULL ) throw "cannot increment uninitialized iterator";
281  if ( batch!=refQueue->end() )
282  if ( it != (*batch).queue.end() )
283  it++;
284  else
285  {
286  batch++;
287  if ( batch!=refQueue->end() ) it = (*batch).queue.begin();
288  }
289 #endif
290 
291  return oldIt;
292  }
293 
294  T &operator*()
295  { return (T&)(*it); }
296 
297  const T &operator*() const
298  { return *it; }
299 
301  {
302  bool areEqual = true;
303  areEqual = (refQueue == i.refQueue);
304  if ( areEqual && refQueue!=NULL )
305  {
306  if ( (areEqual = (batch == i.batch)) )
307  if ( areEqual && batch!=refQueue->end() ) areEqual = (it==i.it);
308  }
309 
310  return areEqual;
311  }
312 
314  {
315  return ! ( (*this)==i );
316  }
317 
318 private:
319  list< __ov_batchQueue_struct<T> > *refQueue;
320  typename list< __ov_batchQueue_struct<T> >::const_iterator batch;
322 };
323 
324 //
325 // A priority batch queue.
326 // this class encapsulates a queue where items are inserted with a particular
327 // priority but are placed in batches of similar priority. Iterations through
328 // the queue start at the highest priority batch iterate through it, and then
329 // continue with the next batch and so on. Within a batch, items are stuck
330 // in a FIFO queue encapsulated by PriorityQueueTemplate (above).
331 //
332 template<class T>
333 class PriorityBatchQueue
334 {
335  friend class PriorityBatchQueueIterator<T>;
337 
338 public:
339  PriorityBatchQueue( real priorityBoundPercent_=.25 ) : priorityBoundPercent(priorityBoundPercent_), maxP(-REAL_MAX), minP(REAL_MAX) { }
340  PriorityBatchQueue( const PriorityBatchQueue<T> &pQ ) : queues(pQ.queues), priorityBoundPercent(priorityBoundPercent), maxP(-REAL_MAX), minP(REAL_MAX) { }
342 
345 
347  {
348  (*(i.batch)).queue.erase(i.it);
349  if ((*(i.batch)).queue.empty()) queues.erase(i.batch);
350  i.refQueue = 0;
351  }
352 
353  double maxPriority() const
354  {
355  return maxP;
356  }
357 
358  double minPriority() const
359  {
360  return minP;
361  }
362 
364  {
365  T data = *i;
366  typename PriorityBatchQueue<T>::iterator retiter = i;
367  ++retiter;
368  erase(i);
369  i = insert(data, newPriority);
370 
371  return retiter;
372  }
373 
374  typename PriorityBatchQueue<T>::iterator insert(T& data, double priority)
375  {
376 
377  minP = min((double)minP,priority);
378  maxP = max((double)maxP,priority);
379 
380  //cout<<"inserting with priority "<<priority<<endl;
381  typename list< __ov_batchQueue_struct<T> >::iterator insBatch=queues.begin();
382 
384 
385  if ( insBatch!=queues.end() )
386  {
387  while ( insBatch!=queues.end() )
388  {
389  if ( priority>(*insBatch).priorityBegin ||
390  ( priority<=(*insBatch).priorityBegin && priority>(*insBatch).priorityEnd ) )
391  break;
392 
393  insBatch++;
394  }
395  }
396 
397  real pa = (1.+ priorityBoundPercent)*priority;
398  real pb = (1.- priorityBoundPercent)*priority;
399 
400  bool createNew = insBatch==queues.end() ? true : ( priority>(*insBatch).priorityBegin ? true : false );
401 
402  //if ( insBatch!=queues.end() ) cout<<"priority , priorityBegin "<<priority<<" "<<(*insBatch).priorityBegin<<endl;
403 
404  if ( createNew )
405  {
406  __ov_batchQueue_struct<T> newQStruct;
407  newQStruct.priorityBegin = max(pa,pb);
408  newQStruct.priorityEnd = (insBatch==queues.end()) ?
409  min(pa,pb) : min(min(pa,pb),(*insBatch).priorityBegin);
410  queues.insert( insBatch, newQStruct );
411  insBatch--;
412  i = (*insBatch).queue.insert(data,priority);
413  }
414  else //if ( priority>=(*insBatch).priorityBegin && priority<(*insBatch).priorityEnd )
415  {
416  i = (*insBatch).queue.insert(data,priority);
417  }
418 
419  typename PriorityBatchQueue<T>::iterator newIter;
420  newIter.refQueue = (list< __ov_batchQueue_struct<T> > *) &queues;
421  newIter.batch = insBatch;
422  newIter.it = i;
423 
424  // cout<<"batch queue size "<<queues.size()<<endl;
425  return newIter;
426  }
427 
429  {
431  ib.batch = queues.begin();
432  ib.refQueue = &queues;
433  if (queues.begin()!=queues.end()) ib.it = (*(ib.batch)).queue.begin();
434  return ib;
435  }
436 
438  {
440  ie.batch = queues.end();
441  ie.refQueue = &queues;
442  return ie;
443  }
444 
445 #if 0
446  PriorityBatchQueue<T>::const_iterator insert(T& data, double priority) const
447  {
448  }
449 #endif
450 
452  {
454  ib.batch = queues.begin();
455  ib.refQueue = ( list< __ov_batchQueue_struct<T> > * )&queues;
456  if (queues.begin()!=queues.end()) ib.it = (*(ib.batch)).queue.begin();
457  return ib;
458  }
459 
461  {
463  ie.batch = queues.end();
464  ie.refQueue = ( list< __ov_batchQueue_struct<T> > * )&queues;
465  return ie;
466  }
467 
468  void clear()
469  {
470  for ( typename list< __ov_batchQueue_struct<T> >::iterator i=queues.begin(); i!=queues.end(); i++ ) (*i).queue.clear();
471  queues.clear();
472  }
473 
474  bool empty() const
475  { return queues.empty(); }
476 
477  int size() const
478  {
479  int s=0;
480  for ( typename list< __ov_batchQueue_struct<T> >::const_iterator i=queues.begin(); i!=queues.end(); i++ )
481  s+=(*i).queue.size();
482  return s;
483  }
484 
485  int numberOfBatches() const
486  { return queues.size(); }
487 
488 private:
489  list< __ov_batchQueue_struct<T> > queues;
490  real priorityBoundPercent;
491  real maxP;
492  real minP;
493 };
494 
495 #endif