RavEngine
Loading...
Searching...
No Matches
CmPriorityQueue.h
1// Redistribution and use in source and binary forms, with or without
2// modification, are permitted provided that the following conditions
3// are met:
4// * Redistributions of source code must retain the above copyright
5// notice, this list of conditions and the following disclaimer.
6// * Redistributions in binary form must reproduce the above copyright
7// notice, this list of conditions and the following disclaimer in the
8// documentation and/or other materials provided with the distribution.
9// * Neither the name of NVIDIA CORPORATION nor the names of its
10// contributors may be used to endorse or promote products derived
11// from this software without specific prior written permission.
12//
13// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
14// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
17// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24//
25// Copyright (c) 2008-2022 NVIDIA Corporation. All rights reserved.
26// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
27// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
28
29#ifndef CM_PRIORITY_QUEUE_H
30#define CM_PRIORITY_QUEUE_H
31
32#include "foundation/PxBasicTemplates.h"
33#include "foundation/PxAllocator.h"
34#include "foundation/PxMemory.h"
35
36namespace physx
37{
38namespace Cm
39{
40 template<class Element, class Comparator = PxLess<Element> >
41 class PriorityQueueBase : protected Comparator // inherit so that stateless comparators take no space
42 {
43 public:
44 PriorityQueueBase(const Comparator& less, Element* elements) : Comparator(less), mHeapSize(0), mDataPtr(elements)
45 {
46 }
47
49 {
50 }
51
53 PX_FORCE_INLINE const Element top() const
54 {
55 return mDataPtr[0];
56 }
57
60 {
61 return mDataPtr[0];
62 }
63
66 {
67 return (mHeapSize == 0);
68 }
69
72 {
73 mHeapSize = 0;
74 }
75
77 PX_FORCE_INLINE void push(const Element& value)
78 {
79 PxU32 newIndex;
80 PxU32 parentIndex = parent(mHeapSize);
81
82 for (newIndex = mHeapSize; newIndex > 0 && compare(value, mDataPtr[parentIndex]); newIndex = parentIndex, parentIndex= parent(newIndex))
83 {
84 mDataPtr[ newIndex ] = mDataPtr[parentIndex];
85 }
86 mDataPtr[newIndex] = value;
87 mHeapSize++;
88 PX_ASSERT(valid());
89 }
90
93 {
94 PX_ASSERT(mHeapSize > 0);
95 PxU32 i, child;
96 //try to avoid LHS
97 PxU32 tempHs = mHeapSize-1;
98 mHeapSize = tempHs;
99 Element min = mDataPtr[0];
100 Element last = mDataPtr[tempHs];
101
102 for (i = 0; (child = left(i)) < tempHs; i = child)
103 {
104 /* Find highest priority child */
105 const PxU32 rightChild = child + 1;
106
107 child += ((rightChild < tempHs) & compare((mDataPtr[rightChild]), (mDataPtr[child]))) ? 1 : 0;
108
109 if(compare(last, mDataPtr[child]))
110 break;
111
112 mDataPtr[i] = mDataPtr[child];
113 }
114 mDataPtr[ i ] = last;
115
116 PX_ASSERT(valid());
117 return min;
118 }
119
121 bool valid() const
122 {
123 const Element& min = mDataPtr[0];
124 for(PxU32 i=1; i<mHeapSize; ++i)
125 {
126 if(compare(mDataPtr[i], min))
127 return false;
128 }
129
130 return true;
131 }
132
134 PxU32 size() const
135 {
136 return mHeapSize;
137 }
138
139 protected:
140
141 PxU32 mHeapSize;
142 Element* mDataPtr;
143
144 PX_FORCE_INLINE bool compare(const Element& a, const Element& b) const
145 {
146 return Comparator::operator()(a,b);
147 }
148
149 static PX_FORCE_INLINE PxU32 left(PxU32 nodeIndex)
150 {
151 return (nodeIndex << 1) + 1;
152 }
153
154 static PX_FORCE_INLINE PxU32 parent(PxU32 nodeIndex)
155 {
156 return (nodeIndex - 1) >> 1;
157 }
158 private:
159 PriorityQueueBase<Element, Comparator>& operator = (const PriorityQueueBase<Element, Comparator>);
160 };
161
162 template <typename Element, PxU32 Capacity, typename Comparator>
163 class InlinePriorityQueue : public PriorityQueueBase<Element, Comparator>
164 {
165 Element mData[Capacity];
166 public:
167 InlinePriorityQueue(const Comparator& less = Comparator()) : PriorityQueueBase<Element, Comparator>(less, mData)
168 {
169 }
170
171 PX_FORCE_INLINE void push(Element& elem)
172 {
173 PX_ASSERT(this->mHeapSize < Capacity);
175 }
176 private:
178 };
179
180 template <typename Element, typename Comparator, typename Alloc = typename physx::PxAllocatorTraits<Element>::Type>
181 class PriorityQueue : public PriorityQueueBase<Element, Comparator>, protected Alloc
182 {
183 PxU32 mCapacity;
184 public:
185 PriorityQueue(const Comparator& less = Comparator(), PxU32 initialCapacity = 0, Alloc alloc = Alloc())
186 : PriorityQueueBase<Element, Comparator>(less, NULL), Alloc(alloc), mCapacity(initialCapacity)
187 {
188 if(initialCapacity > 0)
189 this->mDataPtr = reinterpret_cast<Element*>(Alloc::allocate(sizeof(Element)*initialCapacity, __FILE__, __LINE__));
190 }
191
193 {
194 if(this->mDataPtr)
195 this->deallocate(this->mDataPtr);
196 }
197
198 PX_FORCE_INLINE void push(Element& elem)
199 {
200 if(this->mHeapSize == mCapacity)
201 {
202 reserve((this->mHeapSize+1)*2);
203 }
205 }
206
207 PX_FORCE_INLINE PxU32 capacity()
208 {
209 return mCapacity;
210 }
211
212 PX_FORCE_INLINE void reserve(const PxU32 newCapacity)
213 {
214 if(newCapacity > mCapacity)
215 {
216 Element* newElems = reinterpret_cast<Element*>(Alloc::allocate(sizeof(Element)*newCapacity, __FILE__, __LINE__));
217 if(this->mDataPtr)
218 {
219 physx::PxMemCopy(newElems, this->mDataPtr, sizeof(Element) * this->mHeapSize);
220 Alloc::deallocate(this->mDataPtr);
221 }
222 this->mDataPtr = newElems;
223 mCapacity = newCapacity;
224 }
225 }
226
227 private:
229 };
230
231}
232}
233
234#endif
Definition CmPriorityQueue.h:164
Definition CmPriorityQueue.h:42
PX_FORCE_INLINE const Element top() const
Get the element with the highest priority.
Definition CmPriorityQueue.h:53
bool valid() const
Make sure the priority queue sort all elements correctly.
Definition CmPriorityQueue.h:121
PX_FORCE_INLINE void clear()
Empty the priority queue.
Definition CmPriorityQueue.h:71
PX_FORCE_INLINE Element top()
Get the element with the highest priority.
Definition CmPriorityQueue.h:59
PX_FORCE_INLINE void push(const Element &value)
Insert a new element into the priority queue. Only valid when size() is less than Capacity.
Definition CmPriorityQueue.h:77
PX_FORCE_INLINE bool empty() const
Check to whether the priority queue is empty.
Definition CmPriorityQueue.h:65
PX_FORCE_INLINE Element pop()
Delete the highest priority element. Only valid when non-empty.
Definition CmPriorityQueue.h:92
PxU32 size() const
Return number of elements in the priority queue.
Definition CmPriorityQueue.h:134
Definition CmPriorityQueue.h:182
#define PX_FORCE_INLINE
Definition PxPreprocessor.h:335
Sorts an array of objects in ascending order, assuming that the predicate implements the < operator:
Definition PxBoxController.h:39
PX_FORCE_INLINE void * PxMemCopy(void *dest, const void *src, PxU32 count)
Copies the bytes of one memory block to another. The memory blocks must not overlap.
Definition PxMemory.h:83