activemq-cpp-3.8.2
PriorityQueue.h
Go to the documentation of this file.
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #ifndef _DECAF_UTIL_PRIORITYQUEUE_H_
19 #define _DECAF_UTIL_PRIORITYQUEUE_H_
20 
21 #include <decaf/util/Config.h>
22 #include <decaf/util/Collection.h>
24 #include <decaf/util/Iterator.h>
25 #include <decaf/util/Comparator.h>
27 
28 #include <decaf/lang/Math.h>
29 #include <decaf/lang/Pointer.h>
32 
33 #include <memory>
34 
35 namespace decaf {
36 namespace util {
37 
39  protected:
40 
41  static const int DEFAULT_CAPACITY;
42  static const int DEFAULT_CAPACITY_RATIO;
43 
44  virtual ~PriorityQueueBase() {}
45  };
46 
77  template< typename E >
78  class PriorityQueue : public AbstractQueue<E>, private PriorityQueueBase {
79  private:
80 
81  int _size;
82  int capacity;
83  E* elements;
85 
86  private:
87 
88  class PriorityQueueIterator : public Iterator<E> {
89  private:
90 
91  PriorityQueueIterator( const PriorityQueueIterator& );
92  PriorityQueueIterator& operator= ( const PriorityQueueIterator& );
93 
94  private:
95 
96  int position;
97  bool allowRemove;
98  PriorityQueue* queue;
99 
100  public:
101 
102  PriorityQueueIterator( PriorityQueue* queue ) : position( 0 ), allowRemove( false ), queue( queue ) {}
103 
104  virtual E next() {
105 
106  if( !hasNext() ) {
108  __FILE__, __LINE__,
109  "No more elements to Iterate over." );
110  }
111 
112  allowRemove = true;
113  return queue->elements[position++];
114  }
115 
116  virtual bool hasNext() const {
117  return position < queue->_size;
118  }
119 
120  virtual void remove() {
121 
122  if( !allowRemove ) {
124  __FILE__, __LINE__,
125  "No more elements to Iterate over." );
126  }
127 
128  allowRemove = false;
129  queue->removeAt( position-- );
130  }
131  };
132 
133  class ConstPriorityQueueIterator : public PriorityQueueIterator {
134  private:
135 
136  ConstPriorityQueueIterator( const ConstPriorityQueueIterator& );
137  ConstPriorityQueueIterator& operator= ( const ConstPriorityQueueIterator& );
138 
139  public:
140 
141  ConstPriorityQueueIterator( const PriorityQueue* queue ) :
142  PriorityQueueIterator( const_cast<PriorityQueue*>( queue ) ) {}
143 
144  virtual void remove() {
146  __FILE__, __LINE__,
147  "PriorityQueue::Iterator::remove - Not Valid on a Const Iterator" );
148  }
149  };
150 
151  friend class PriorityQueueIterator;
152 
153  public:
154 
158  PriorityQueue() : AbstractQueue<E>(), _size( 0 ), capacity( 0 ), elements( NULL ), _comparator() {
159  this->initQueue( DEFAULT_CAPACITY, new comparators::Less<E>() );
160  }
161 
168  PriorityQueue( int initialCapacity ) :
169  AbstractQueue<E>(), _size( 0 ), capacity( 0 ), elements( NULL ), _comparator() {
170 
171  this->initQueue( initialCapacity, new comparators::Less<E>() );
172  }
173 
186  PriorityQueue( int initialCapacity, Comparator<E>* comparator ) :
187  AbstractQueue<E>(), _size( 0 ), capacity( 0 ), elements( NULL ), _comparator() {
188 
189  if( comparator == NULL ) {
191  __FILE__, __LINE__, "Passed Comparator Cannot be NULL." );
192  }
193 
194  this->initQueue( initialCapacity, comparator );
195  }
196 
203  PriorityQueue( const Collection<E>& source ) :
204  AbstractQueue<E>(), _size( 0 ), capacity( 0 ), elements( NULL ), _comparator() {
205 
206  this->getFromCollection( source );
207  }
208 
216  PriorityQueue( const PriorityQueue<E>& source ) :
217  AbstractQueue<E>(), _size( 0 ), capacity( 0 ), elements( NULL ), _comparator() {
218 
219  this->getFromPriorityQueue( source );
220  }
221 
222  virtual ~PriorityQueue() {
223  delete [] elements;
224  }
225 
232  PriorityQueue<E>& operator= ( const Collection<E>& source ) {
233  this->getFromCollection( source );
234  return *this;
235  }
236 
243  PriorityQueue<E>& operator= ( const PriorityQueue<E>& source ) {
244  this->getFromPriorityQueue( source );
245  return *this;
246  }
247 
248  public:
249 
251  return new PriorityQueueIterator( this );
252  }
253 
255  return new ConstPriorityQueueIterator( this );
256  }
257 
258  virtual int size() const {
259  return this->_size;
260  }
261 
262  virtual void clear() {
263 
264  // TODO - Provide a more efficient way to clear the array without reallocating it
265  // we should keep the size it grew to since if reused it could get that big
266  // again and reallocating all that memory could be to slow.
267 
268  delete [] this->elements;
269 
270  this->elements = new E[DEFAULT_CAPACITY];
271  this->capacity = DEFAULT_CAPACITY;
272  this->_size = 0;
273  }
274 
275  virtual bool offer( const E& value ) {
276 
277  // TODO - Check for Null and throw exception
278 
279  increaseCapacity( _size + 1 );
280  elements[_size++] = value;
281  upHeap();
282  return true;
283  }
284 
285  virtual bool poll( E& result ) {
286 
287  if( this->isEmpty() ) {
288  return false;
289  }
290 
291  result = elements[0];
292  removeAt( 0 );
293  return true;
294  }
295 
296  virtual bool peek( E& result ) const {
297 
298  if( this->isEmpty() ) {
299  return false;
300  }
301 
302  result = elements[0];
303  return true;
304  }
305 
306  virtual E remove() {
307 
308  if( !this->isEmpty() ) {
309  E result = elements[0];
310  removeAt( 0 );
311  return result;
312  }
313 
315  __FILE__, __LINE__, "Unable to remove specified element from the Queue." );
316  }
317 
318  virtual bool remove( const E& value ) {
319 
320  int targetIndex = 0;
321  for( targetIndex = 0; targetIndex < _size; targetIndex++ ) {
322  if( 0 == _comparator->compare( value, elements[targetIndex] ) ) {
323  break;
324  }
325  }
326 
327  if( _size == 0 || _size == targetIndex ) {
328  return false;
329  }
330 
331  removeAt( targetIndex );
332  return true;
333  }
334 
335  virtual bool add( const E& value ) {
336 
337  try {
338  return offer( value );
339  }
345  }
346 
355  return this->_comparator;
356  }
357 
358  private:
359 
360  void initQueue( int initialSize, Comparator<E>* comparator ) {
361  this->elements = new E[initialSize];
362  this->capacity = initialSize;
363  this->_size = 0;
364  this->_comparator.reset( comparator );
365  }
366 
367  void upHeap() {
368 
369  int current = _size - 1;
370  int parent = ( current - 1 ) / 2;
371 
372  while( current != 0 && _comparator->compare( elements[current], elements[parent] ) < 0 ) {
373 
374  // swap the two
375  E tmp = elements[current];
376  elements[current] = elements[parent];
377  elements[parent] = tmp;
378 
379  // update parent and current positions.
380  current = parent;
381  parent = ( current - 1 ) / 2;
382  }
383  }
384 
385  void downHeap( int pos ) {
386 
387  int current = pos;
388  int child = 2 * current + 1;
389 
390  while( child < _size && !this->isEmpty() ) {
391 
392  // compare the children if they exist
393  if( child + 1 < _size && _comparator->compare( elements[child + 1], elements[child] ) < 0 ) {
394  child++;
395  }
396 
397  // compare selected child with parent
398  if( _comparator->compare( elements[current], elements[child] ) < 0 ) {
399  break;
400  }
401 
402  // swap the two
403  E tmp = elements[current];
404  elements[current] = elements[child];
405  elements[child] = tmp;
406 
407  // update child and current positions
408  current = child;
409  child = 2 * current + 1;
410  }
411  }
412 
413  void getFromPriorityQueue( const PriorityQueue<E>& c ) {
414  initCapacity( c );
415  _comparator = c.comparator();
416  for( int ix = 0; ix < c.size(); ++ix ) {
417  this->elements[ix] = c.elements[ix];
418  }
419  _size = c.size();
420  }
421 
422  void getFromCollection( const Collection<E>& c ) {
423  initCapacity( c );
424  _comparator.reset( new comparators::Less<E>() );
425  std::auto_ptr< Iterator<E> > iter( c.iterator() );
426  while( iter->hasNext() ) {
427  this->offer( iter->next() );
428  }
429  }
430 
431  void removeAt( int index ) {
432  _size--;
433  elements[index] = elements[_size];
434  downHeap(index);
435  elements[_size] = E();
436  }
437 
438  void initCapacity( const Collection<E>& c ) {
439 
440  delete [] elements;
441  _size = 0;
442 
443  if( c.isEmpty() ) {
444  capacity = 1;
445  elements = new E[capacity];
446  } else {
447  capacity = (int) lang::Math::ceil( (double)c.size() * 1.1 );
448  elements = new E[capacity];
449  }
450  }
451 
452  void increaseCapacity( int size ) {
453 
454  if( size > capacity ) {
455  E* newElements = new E[ size * DEFAULT_CAPACITY_RATIO ];
456 
457  for( int ix = 0; ix < capacity; ix++ ) {
458  newElements[ix] = elements[ix];
459  }
460 
461  delete [] elements;
462 
463  elements = newElements;
464  capacity = size * DEFAULT_CAPACITY_RATIO;
465  }
466  }
467 
468  };
469 
470 }}
471 
472 #endif /* _DECAF_UTIL_PRIORITYQUEUE_H_ */
void reset(T *value=NULL)
Resets the Pointer to hold the new value.
Definition: Pointer.h:161
virtual bool offer(const E &value)
Inserts the specified element into the queue provided that the condition allows such an operation...
Definition: PriorityQueue.h:275
The root interface in the collection hierarchy.
Definition: Collection.h:68
#define DECAF_CATCH_RETHROW(type)
Macro for catching and rethrowing an exception of a given type.
Definition: ExceptionDefines.h:27
virtual bool poll(E &result)
Gets and removes the element in the head of the queue.
Definition: PriorityQueue.h:285
An unbounded priority queue based on a binary heap algorithm.
Definition: PriorityQueue.h:78
virtual decaf::util::Iterator< E > * iterator()
Definition: PriorityQueue.h:250
#define NULL
Definition: Config.h:33
virtual bool isEmpty() const =0
decaf::lang::Pointer< Comparator< E > > comparator() const
obtains a Copy of the Pointer instance that this PriorityQueue is using to compare the elements in th...
Definition: PriorityQueue.h:354
PriorityQueue()
Creates a Priority Queue with the default initial capacity.
Definition: PriorityQueue.h:158
virtual int size() const =0
Returns the number of elements in this collection.
virtual void clear()
Removes all of the elements from this collection (optional operation).The collection will be empty af...
Definition: PriorityQueue.h:262
virtual ~PriorityQueueBase()
Definition: PriorityQueue.h:44
Defines an object that can be used to iterate over the elements of a collection.
Definition: Iterator.h:34
Definition: UnsupportedOperationException.h:32
PriorityQueue(const PriorityQueue< E > &source)
Creates a PriorityQueue containing the elements in the specified priority queue.
Definition: PriorityQueue.h:216
static const int DEFAULT_CAPACITY_RATIO
Definition: PriorityQueue.h:42
virtual decaf::util::Iterator< E > * iterator()=0
virtual bool add(const E &value)
Returns true if this collection changed as a result of the call.(Returns false if this collection doe...
Definition: PriorityQueue.h:335
PriorityQueue(const Collection< E > &source)
Creates a PriorityQueue containing the elements in the specified Collection.
Definition: PriorityQueue.h:203
Simple Less Comparator that compares to elements to determine if the first is less than the second...
Definition: Less.h:37
Definition: IllegalArgumentException.h:31
Definition: IllegalStateException.h:32
static const int DEFAULT_CAPACITY
Definition: PriorityQueue.h:41
PriorityQueue(int initialCapacity)
Creates a Priority Queue with the capacity value supplied.
Definition: PriorityQueue.h:168
PriorityQueue(int initialCapacity, Comparator< E > *comparator)
Creates a Priority Queue with the default initial capacity.
Definition: PriorityQueue.h:186
virtual decaf::util::Iterator< E > * iterator() const
Definition: PriorityQueue.h:254
#define DECAF_CATCHALL_THROW(type)
A catch-all that throws a known exception.
Definition: ExceptionDefines.h:50
Definition: NullPointerException.h:32
#define DECAF_API
Definition: Config.h:29
Definition: NoSuchElementException.h:31
virtual bool peek(E &result) const
Gets but not removes the element in the head of the queue.
Definition: PriorityQueue.h:296
Decaf&#39;s implementation of a Smart Pointer that is a template on a Type and is Thread Safe if the defa...
Definition: Pointer.h:53
Definition: PriorityQueue.h:38
virtual ~PriorityQueue()
Definition: PriorityQueue.h:222
static double ceil(double value)
Returns the natural logarithm (base e) of a double value.
virtual int size() const
Returns the number of elements in this collection.
Definition: PriorityQueue.h:258
This class provides skeletal implementations of some Queue operations.
Definition: AbstractQueue.h:47
Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements...
Definition: AprPool.h:25
#define DECAF_CATCH_EXCEPTION_CONVERT(sourceType, targetType)
Macro for catching an exception of one type and then rethrowing as another type.
Definition: ExceptionDefines.h:39