2 * Copyright (c) 1999-2005 Mark D. Hill and David A. Wood
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #include "mem/gems_common/Vector.hh"
34 typedef unsigned int HeapIndex;
40 PrioHeap() { init(); }
46 void init() { m_current_size = 0; }
47 int size() const { return m_current_size; }
48 void insert(const TYPE& key);
49 const TYPE& peekMin() const;
50 const TYPE& peekElement(int index) const;
52 void print(ostream& out) const;
55 bool verifyHeap() const;
56 bool verifyHeap(HeapIndex index) const;
59 // Private copy constructor and assignment operator
60 PrioHeap(const PrioHeap& obj);
61 PrioHeap<TYPE>& operator=(const PrioHeap& obj);
63 // Data Members (m_ prefix)
65 HeapIndex m_current_size;
68 // Output operator declaration
70 ostream& operator<<(ostream& out, const PrioHeap<TYPE>& obj);
72 // ******************* Helper Functions *******************
74 HeapIndex get_parent(HeapIndex i)
81 HeapIndex get_right(HeapIndex i)
88 HeapIndex get_left(HeapIndex i)
95 void prio_heap_swap(TYPE& n1, TYPE& n2)
102 // ******************* Definitions *******************
104 template <class TYPE>
105 void PrioHeap<TYPE>::insert(const TYPE& key)
108 // grow the vector size
110 m_heap.setSize(m_current_size+1);
112 if(m_current_size == 1){ // HACK: need to initialize index 0 to avoid purify UMCs
117 while ((i > 1) && (node_less_then_eq(key, m_heap[get_parent(i)]))) {
118 m_heap[i] = m_heap[get_parent(i)];
122 // assert(verifyHeap());
125 template <class TYPE>
126 const TYPE& PrioHeap<TYPE>::peekMin() const
129 return m_heap[1]; // 1, not 0, is the first element
132 template <class TYPE>
133 const TYPE& PrioHeap<TYPE>::peekElement(int index) const
136 return m_heap[index];
139 template <class TYPE>
140 TYPE PrioHeap<TYPE>::extractMin()
144 TYPE temp = m_heap[1]; // 1, not 0, is the first element
145 m_heap[1] = m_heap[m_current_size];
151 template <class TYPE>
152 bool PrioHeap<TYPE>::verifyHeap() const
154 return verifyHeap(1);
157 template <class TYPE>
158 bool PrioHeap<TYPE>::verifyHeap(HeapIndex index) const
160 // Recursively verify that each node is <= its parent
161 if(index > m_current_size) {
163 } else if (index == 1) {
165 verifyHeap(get_right(index)) &&
166 verifyHeap(get_left(index));
167 } else if (node_less_then_eq(m_heap[get_parent(index)], m_heap[index])) {
169 verifyHeap(get_right(index)) &&
170 verifyHeap(get_left(index));
172 // Heap property violation
177 template <class TYPE>
178 void PrioHeap<TYPE>::heapify()
180 HeapIndex current_node = 1;
181 HeapIndex left, right, smallest;
182 // HeapIndex size = m_current_size;
185 left = get_left(current_node);
186 right = get_right(current_node);
188 // Find the smallest of the current node and children
189 if (left <= m_current_size && node_less_then_eq(m_heap[left], m_heap[current_node])) {
192 smallest = current_node;
195 if (right <= m_current_size && node_less_then_eq(m_heap[right], m_heap[smallest])) {
199 // Check to see if we are done
200 if (smallest == current_node) {
204 // Not done, heapify on the smallest child
205 prio_heap_swap(m_heap[current_node], m_heap[smallest]);
206 current_node = smallest;
209 // assert(verifyHeap());
212 template <class TYPE>
213 void PrioHeap<TYPE>::print(ostream& out) const
215 Vector<TYPE> copyHeap(m_heap);
217 // sort copyHeap (inefficient, but will not be done often)
219 for(HeapIndex i=0;i<m_current_size; i++){
220 for(HeapIndex j=0; j< m_current_size; j++){
221 if(copyHeap[i].m_time < copyHeap[j].m_time){
222 prio_heap_swap(copyHeap[i], copyHeap[j]);
227 out << "[PrioHeap: ";
229 for(HeapIndex i=1; i<= m_current_size; i++){
232 if(i != m_current_size-1){
240 // Output operator definition
241 template <class TYPE>
242 ostream& operator<<(ostream& out, const PrioHeap<TYPE>& obj)