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