LimitedHeap.h
Go to the documentation of this file.
1 #ifndef __GfxTL_LIMITEDHEAP_HEADER__
2 #define __GfxTL_LIMITEDHEAP_HEADER__
3 #include <algorithm>
4 #include <functional>
5 #include <vector>
6 #include <GfxTL/FlatCopyVector.h>
8 #include <functional>
9 
10 namespace GfxTL
11 {
12  template< class T, class PredicateT = std::less< T >,
13  template< class > class ContainerT = FlatCopyVector >
15  : public ContainerT< T >
16  {
17  public:
18  typedef typename ContainerT< T >::value_type value_type;
19  typedef typename ContainerT< T >::size_type size_type;
20  typedef PredicateT PredicateType;
21  typedef ContainerT< T > BaseType;
22 
24  : _limit(-1)
25  , _instances(0)
26  {}
27 
29  : _limit(limit)
30  , _instances(0)
31  {
32  BaseType::reserve(limit);
33  }
34 
36  : m_pred(pred)
37  , _limit(-1)
38  , _instances(0)
39  {
40  BaseType::reserve(_limit);
41  }
42 
43  LimitedHeap(size_type limit, const PredicateType& pred)
44  : m_pred(pred)
45  , _limit(limit)
46  , _instances(0)
47  {
48  BaseType::reserve(limit);
49  }
50 
51  void Limit(size_type limit)
52  {
53  _limit = limit;
54  BaseType::reserve(limit + 1);
55  }
56 
57  size_type Limit() const
58  {
59  return _limit;
60  }
61 
62  void Predicate(const PredicateType& pred)
63  {
64  m_pred = pred;
65  }
66 
67  const PredicateType& Predicate() const
68  {
69  return m_pred;
70  }
71 
72  void clear()
73  {
74  BaseType::clear();
75  _instances = 0;
76  }
77 
78  void MakeHeap()
79  {
80  size_type iend = BaseType::size();
81  for (size_type i = BaseType::size() >> 1; i > 0; --i)
82  {
83  Heapify(i - 1, iend);
84  }
85  }
86 
87  void SortHeap()
88  {
89  if (!BaseType::size())
90  {
91  return;
92  }
93  for (size_type i = BaseType::size() - 1; i > 0; --i)
94  {
95  T tmp = BaseType::at(i);
96  BaseType::at(i) = BaseType::at(0);
97  BaseType::at(0) = tmp;
98  Heapify(0, i);
99  }
100  }
101 
102  void AssertHeap()
103  {
104  if (BaseType::size() < _limit)
105  {
106  MakeHeap();
107  }
108  }
109 
110  void PushHeap(const value_type& t)
111  {
112  if (BaseType::size() < _limit)
113  {
114  BaseType::push_back(t);
115  if (BaseType::size() == _limit)
116  {
117  MakeHeap();
118  _instances = CountInstances(0);
119  }
120  }
121  else
122  {
123  if (m_pred(BaseType::front(), t)) // front < t
124  {
125  return; // t > front
126  }
127  if (m_pred(t, BaseType::front())) // t < front?
128  {
129  if (_instances > 1)
130  {
131  if (BaseType::size() + 1 - _instances >= _limit)
132  {
133  // remove instances
134  for (size_type i = 0; i < _instances; ++i)
135  {
136  std::swap(BaseType::front(), BaseType::back());
137  BaseType::pop_back();
138  Heapify(0, BaseType::size());
139  }
140  BaseType::push_back(t);
141  BubbleDown();
142  _instances = CountInstances(0);
143  return;
144  }
145  BaseType::push_back(t);
146  BubbleDown();
147  return;
148  }
149  BaseType::front() = t;
150  Heapify(0, BaseType::size());
151  _instances = CountInstances(0);
152  return;
153  }
154  // t == front;
155  BaseType::push_back(t);
156  BubbleDown();
157  ++_instances;
158  }
159  }
160 
161  private:
162  void Heapify(size_type i, size_type iend)
163  {
164  using namespace std;
165  size_type max;
166  while ((max = (i << 1) + 1) < iend)
167  {
168  if (max + 1 < iend && m_pred(BaseType::at(max), BaseType::at(max + 1)))
169  {
170  ++max;
171  }
172  if (!m_pred(BaseType::at(i), BaseType::at(max)))
173  {
174  break;
175  }
176  std::swap(BaseType::at(i), BaseType::at(max));
177  i = max;
178  }
179  }
180 
181  void BubbleDown()
182  {
183  using namespace std;
184  if (BaseType::size() == 1)
185  {
186  return;
187  }
188  size_type i = BaseType::size() - 1, j;
189  while (i && m_pred(BaseType::at(j = ((i + 1) >> 1) - 1), BaseType::at(i)))
190  {
191  std::swap(BaseType::at(i), BaseType::at(j));
192  i = j;
193  }
194  }
195 
196  size_type CountInstances(size_type i) const
197  {
198  size_type child = (i << 1) + 1;
199  if (child >= BaseType::size())
200  {
201  return 1;
202  }
203  size_type instances = 0;
204  if (!m_pred(BaseType::at(child), BaseType::at(i)))
205  {
206  instances = CountInstances(child);
207  }
208  ++child;
209  if (child >= BaseType::size())
210  {
211  return 1 + instances;
212  }
213  if (!m_pred(BaseType::at(child), BaseType::at(i)))
214  {
215  instances += CountInstances(child);
216  }
217  return 1 + instances;
218  }
219 
220  private:
221  PredicateType m_pred;
222  size_type _limit;
223  size_type _instances;
224  };
225 
226  template< class T, template< class > class ContainerT = FlatCopyVector >
228  : public ContainerT< T >
229  {
230  public:
231  typedef typename ContainerT< T >::value_type value_type;
232  typedef typename ContainerT< T >::size_type size_type;
233  typedef ContainerT< T > BaseType;
234 
236  : _limit(-1)
237  {}
238 
240  : _limit(limit)
241  {
242  BaseType::reserve(limit);
243  }
244 
245  void Limit(size_type limit)
246  {
247  _limit = limit;
248  BaseType::reserve(limit + 1);
249  }
250 
251  size_type Limit() const
252  {
253  return _limit;
254  }
255 
256  void MakeHeap()
257  {
258  size_type iend = BaseType::size();
259  for (size_type i = BaseType::size() >> 1; i > 0; --i)
260  {
261  Heapify(i - 1, iend);
262  }
263  }
264 
265  void SortHeap()
266  {
267  if (!BaseType::size())
268  {
269  return;
270  }
271  for (size_type i = BaseType::size() - 1; i > 0; --i)
272  {
273  T tmp = BaseType::at(i);
274  BaseType::at(i) = BaseType::at(0);
275  BaseType::at(0) = tmp;
276  Heapify(0, i);
277  }
278  }
279 
280  void AssertHeap()
281  {
282  if (BaseType::size() < _limit)
283  {
284  MakeHeap();
285  }
286  }
287 
288  void PushHeap(const value_type& t)
289  {
290  if (BaseType::size() < _limit)
291  {
292  BaseType::push_back(t);
293  if (BaseType::size() == _limit)
294  {
295  MakeHeap();
296  }
297  }
298  else
299  {
300  if (t >= BaseType::front())
301  {
302  return;
303  }
304  BaseType::front() = t;
305  Heapify(0, BaseType::size());
306  }
307  }
308 
309  private:
310  void Heapify(size_type i, size_type iend)
311  {
312  size_type max;
313  while ((max = (i << 1) + 1) < iend)
314  {
315  if (max + 1 < iend && BaseType::at(max) < BaseType::at(max + 1))
316  {
317  ++max;
318  }
319  if (BaseType::at(i) >= BaseType::at(max))
320  {
321  break;
322  }
323  std::swap(BaseType::at(i), BaseType::at(max));
324  i = max;
325  }
326  }
327 
328  void BubbleDown()
329  {
330  if (BaseType::size() == 1)
331  {
332  return;
333  }
334  size_type i = BaseType::size() - 1, j;
335  while (i && BaseType::at(i) > BaseType::at(j = ((i + 1) >> 1) - 1))
336  {
337  std::swap(BaseType::at(i), BaseType::at(j));
338  i = j;
339  }
340  }
341 
342  private:
343  size_type _limit;
344  };
345 };
346 
347 #endif
GfxTL::LimitedHeap::clear
void clear()
Definition: LimitedHeap.h:72
GfxTL::LimitedHeap::Limit
size_type Limit() const
Definition: LimitedHeap.h:57
GfxTL::AssumeUniqueLimitedHeap::BaseType
ContainerT< T > BaseType
Definition: LimitedHeap.h:233
GfxTL::LimitedHeap::Predicate
const PredicateType & Predicate() const
Definition: LimitedHeap.h:67
GfxTL::AssumeUniqueLimitedHeap
Definition: LimitedHeap.h:227
StdContainerAdaptor.h
GfxTL::AssumeUniqueLimitedHeap::PushHeap
void PushHeap(const value_type &t)
Definition: LimitedHeap.h:288
GfxTL::max
MatrixXX< C, R, T > max(const MatrixXX< C, R, T > &a, const MatrixXX< C, R, T > &b)
Definition: MatrixXX.h:581
GfxTL::LimitedHeap::LimitedHeap
LimitedHeap(size_type limit, const PredicateType &pred)
Definition: LimitedHeap.h:43
GfxTL::LimitedHeap::SortHeap
void SortHeap()
Definition: LimitedHeap.h:87
GfxTL::FlatCopyVector::value_type
T value_type
Definition: FlatCopyVector.h:14
GfxTL::LimitedHeap::MakeHeap
void MakeHeap()
Definition: LimitedHeap.h:78
GfxTL::AssumeUniqueLimitedHeap::MakeHeap
void MakeHeap()
Definition: LimitedHeap.h:256
armarx::armem::client::util::swap
void swap(SubscriptionHandle &first, SubscriptionHandle &second)
Definition: SubscriptionHandle.cpp:66
GfxTL::AssumeUniqueLimitedHeap::SortHeap
void SortHeap()
Definition: LimitedHeap.h:265
GfxTL::AssumeUniqueLimitedHeap::AssumeUniqueLimitedHeap
AssumeUniqueLimitedHeap()
Definition: LimitedHeap.h:235
GfxTL::LimitedHeap::LimitedHeap
LimitedHeap(const PredicateType &pred)
Definition: LimitedHeap.h:35
GfxTL::AssumeUniqueLimitedHeap::Limit
void Limit(size_type limit)
Definition: LimitedHeap.h:245
GfxTL::LimitedHeap::BaseType
ContainerT< T > BaseType
Definition: LimitedHeap.h:21
FlatCopyVector.h
GfxTL::AssumeUniqueLimitedHeap::size_type
ContainerT< T >::size_type size_type
Definition: LimitedHeap.h:232
GfxTL::FlatCopyVector::FlatCopyVector
FlatCopyVector()
Definition: FlatCopyVector.h:25
GfxTL
Definition: AABox.h:8
GfxTL::AssumeUniqueLimitedHeap::Limit
size_type Limit() const
Definition: LimitedHeap.h:251
GfxTL::AssumeUniqueLimitedHeap::AssumeUniqueLimitedHeap
AssumeUniqueLimitedHeap(size_type limit)
Definition: LimitedHeap.h:239
GfxTL::FlatCopyVector::size_type
size_t size_type
Definition: FlatCopyVector.h:13
GfxTL::AssumeUniqueLimitedHeap::AssertHeap
void AssertHeap()
Definition: LimitedHeap.h:280
std
Definition: Application.h:66
GfxTL::LimitedHeap::LimitedHeap
LimitedHeap(size_type limit)
Definition: LimitedHeap.h:28
GfxTL::LimitedHeap
Definition: LimitedHeap.h:14
GfxTL::LimitedHeap::Predicate
void Predicate(const PredicateType &pred)
Definition: LimitedHeap.h:62
GfxTL::LimitedHeap::AssertHeap
void AssertHeap()
Definition: LimitedHeap.h:102
GfxTL::LimitedHeap::LimitedHeap
LimitedHeap()
Definition: LimitedHeap.h:23
GfxTL::LimitedHeap::PredicateType
PredicateT PredicateType
Definition: LimitedHeap.h:20
GfxTL::AssumeUniqueLimitedHeap::value_type
ContainerT< T >::value_type value_type
Definition: LimitedHeap.h:231
T
float T
Definition: UnscentedKalmanFilterTest.cpp:35
GfxTL::LimitedHeap::value_type
ContainerT< T >::value_type value_type
Definition: LimitedHeap.h:18
GfxTL::LimitedHeap::size_type
ContainerT< T >::size_type size_type
Definition: LimitedHeap.h:19
GfxTL::LimitedHeap::PushHeap
void PushHeap(const value_type &t)
Definition: LimitedHeap.h:110
GfxTL::LimitedHeap::Limit
void Limit(size_type limit)
Definition: LimitedHeap.h:51