00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef NVBLASTFIXEDPRIORITYQUEUE_H
00030 #define NVBLASTFIXEDPRIORITYQUEUE_H
00031
00032 #include "NvBlastAssert.h"
00033 #include "NvBlastMemory.h"
00034
00035 namespace Nv
00036 {
00037
00038 namespace Blast
00039 {
00040
00062 template <typename A>
00063 struct Less
00064 {
00065 bool operator()(const A& a, const A& b) const
00066 {
00067 return a < b;
00068 }
00069 };
00070
00071
00072 template<class Element, class Comparator = Less<Element> >
00073 class FixedPriorityQueue : protected Comparator
00074 {
00075 public:
00076 FixedPriorityQueue(const Comparator& less = Comparator()) : Comparator(less), mHeapSize(0)
00077 {
00078 }
00079
00080 ~FixedPriorityQueue()
00081 {
00082 }
00083
00084 static size_t requiredMemorySize(uint32_t capacity)
00085 {
00086 return align16(sizeof(FixedPriorityQueue<Element, Comparator>)) + align16(capacity * sizeof(Element));
00087 }
00088
00090 const Element top() const
00091 {
00092 return data()[0];
00093 }
00094
00096 Element top()
00097 {
00098 return data()[0];
00099 }
00100
00102 bool empty() const
00103 {
00104 return (mHeapSize == 0);
00105 }
00106
00108 void clear()
00109 {
00110 mHeapSize = 0;
00111 }
00112
00114 void push(const Element& value)
00115 {
00116 uint32_t newIndex;
00117 uint32_t parentIndex = parent(mHeapSize);
00118
00119 for (newIndex = mHeapSize; newIndex > 0 && compare(value, data()[parentIndex]); newIndex = parentIndex, parentIndex= parent(newIndex))
00120 {
00121 data()[ newIndex ] = data()[parentIndex];
00122 }
00123 data()[newIndex] = value;
00124 mHeapSize++;
00125 NVBLAST_ASSERT(valid());
00126 }
00127
00129 Element pop()
00130 {
00131 NVBLAST_ASSERT(mHeapSize > 0);
00132 uint32_t i, child;
00133
00134 uint32_t tempHs = mHeapSize-1;
00135 mHeapSize = tempHs;
00136 Element min = data()[0];
00137 Element last = data()[tempHs];
00138
00139 for (i = 0; (child = left(i)) < tempHs; i = child)
00140 {
00141
00142 const uint32_t rightChild = child + 1;
00143
00144 child += ((rightChild < tempHs) & compare((data()[rightChild]), (data()[child]))) ? 1 : 0;
00145
00146 if(compare(last, data()[child]))
00147 break;
00148
00149 data()[i] = data()[child];
00150 }
00151 data()[ i ] = last;
00152
00153 NVBLAST_ASSERT(valid());
00154 return min;
00155 }
00156
00158 bool valid() const
00159 {
00160 const Element& min = data()[0];
00161 for(uint32_t i=1; i<mHeapSize; ++i)
00162 {
00163 if(compare(data()[i], min))
00164 return false;
00165 }
00166
00167 return true;
00168 }
00169
00171 uint32_t size() const
00172 {
00173 return mHeapSize;
00174 }
00175
00176 private:
00177 uint32_t mHeapSize;
00178
00179 NV_FORCE_INLINE Element* data()
00180 {
00181 return (Element*)((char*)this + sizeof(FixedPriorityQueue<Element, Comparator>));
00182 }
00183
00184 NV_FORCE_INLINE Element* data() const
00185 {
00186 return (Element*)((char*)this + sizeof(FixedPriorityQueue<Element, Comparator>));
00187 }
00188
00189 bool compare(const Element& a, const Element& b) const
00190 {
00191 return Comparator::operator()(a,b);
00192 }
00193
00194 static uint32_t left(uint32_t nodeIndex)
00195 {
00196 return (nodeIndex << 1) + 1;
00197 }
00198
00199 static uint32_t parent(uint32_t nodeIndex)
00200 {
00201 return (nodeIndex - 1) >> 1;
00202 }
00203
00204 FixedPriorityQueue<Element, Comparator>& operator = (const FixedPriorityQueue<Element, Comparator>);
00205 };
00206
00207 }
00208 }
00209
00210 #endif // ifndef NVBLASTFIXEDPRIORITYQUEUE_H