1 #ifndef teca_priority_queue_h
2 #define teca_priority_queue_h
4 #include "teca_config.h"
21 template<
typename key_t>
22 using mapped_key_t = std::map<key_t, unsigned long>;
24 using contiguous_key_t = std::vector<unsigned long>;
31 template<
typename key_t,
typename priority_t>
34 using key_map_t = mapped_key_t<key_t>;
36 mapped_key_priority(std::map<key_t, priority_t> &mp) : m_map(&mp)
39 priority_t operator()(key_t i)
40 {
return (*m_map)[i]; }
42 std::map<key_t, priority_t> *m_map;
45 template<
typename key_t,
typename priority_t>
48 using key_map_t = contiguous_key_t;
50 contiguous_key_priority(
const std::vector<priority_t> &vec) :
54 priority_t operator()(key_t i)
57 const priority_t *m_vec;
61 template <
typename key_t,
typename lookup_t,
typename comp_t=std::less<>,
62 typename key_map_t=contiguous_key_t>
66 template<
typename key_t,
typename lookup_t,
typename ...Types >
67 using p_teca_priority_queue = std::shared_ptr<
113 template <
typename key_t,
typename lookup_t,
114 typename comp_t,
typename key_map_t>
123 static p_teca_priority_queue<key_t, lookup_t, comp_t, key_map_t>
124 New(lookup_t &lookup,
unsigned long init_size=256,
125 unsigned long block_size=256)
127 p_teca_priority_queue<key_t, lookup_t,
128 comp_t, key_map_t> ptr(
130 key_t, lookup_t, comp_t, key_map_t>(
131 lookup, init_size, block_size));
136 bool empty() {
return m_end == 0; }
140 void push(
const key_t &key);
146 void modified(
const key_t &key);
156 void to_stream(std::ostream &os,
bool priorities =
true);
166 template<
typename u = key_map_t>
168 unsigned long block_size,
169 typename std::enable_if<std::is_same<
170 std::vector<unsigned long>, u>::value>::type * = 0);
172 template<
typename u = key_map_t>
174 unsigned long block_size,
175 typename std::enable_if<std::is_same<
176 std::map<key_t,unsigned long>, u>::value>::type * = 0);
179 template<
typename u = key_map_t>
180 void grow(
unsigned long n,
181 typename std::enable_if<std::is_same<
182 std::vector<unsigned long>, u>::value>::type * = 0);
185 template<
typename u = key_map_t>
186 void grow(
unsigned long n,
187 typename std::enable_if<std::is_same<
188 std::map<key_t, unsigned long>, u>::value>::type * = 0);
192 void up_heapify(
unsigned long id);
196 void down_heapify(
unsigned long id);
199 void swap(
unsigned long i,
unsigned long j);
202 unsigned long left_child(
unsigned long a_id)
205 unsigned long right_child(
unsigned long a_id)
206 {
return a_id*2 + 1; }
208 unsigned long parent(
unsigned long a_id)
214 std::vector<key_t> m_ids;
216 unsigned long m_size;
218 unsigned long m_block_size;
223 template <
typename key_t,
typename lookup_t,
224 typename comp_t,
typename key_map_t>
226 comp_t, key_map_t>::push(
const key_t &key)
233 this->grow(m_size + m_block_size);
240 this->up_heapify(m_end);
244 template <
typename key_t,
typename lookup_t,
245 typename comp_t,
typename key_map_t>
247 comp_t, key_map_t>::clear()
256 template <
typename key_t,
typename lookup_t,
257 typename comp_t,
typename key_map_t>
259 comp_t, key_map_t>::modified(
const key_t &key)
262 unsigned long id = m_locs[key];
264 this->up_heapify(
id);
265 this->down_heapify(
id);
269 template <
typename key_t,
typename lookup_t,
270 typename comp_t,
typename key_map_t>
272 comp_t, key_map_t>::pop()
274 key_t id_1 = m_ids[1];
277 this->swap(1, m_end);
279 this->down_heapify(1);
285 template <
typename key_t,
typename lookup_t,
286 typename comp_t,
typename key_map_t>
288 comp_t, key_map_t>::peak()
294 template <
typename key_t,
typename lookup_t,
295 typename comp_t,
typename key_map_t>
297 comp_t, key_map_t>::to_stream(std::ostream &os,
bool priorities)
299 long log_end = std::log2(m_end);
300 long n_rows = log_end + 1;
302 for (
long i = 0; i < n_rows; ++i)
307 long n_elem = 1 << i;
308 long isp = (1 << (n_rows - 1 - i)) - 1;
309 long bsp = 2*isp + 1;
311 for (
long j = 0; j < isp; ++j)
314 for (
long j = 0; (j < n_elem) && (q < m_end); ++j)
317 os << m_lookup(m_ids[++q]);
320 for (
long k = 0; k < bsp; ++k)
329 template <
typename key_t,
typename lookup_t,
330 typename comp_t,
typename key_map_t>
334 unsigned long init_size,
unsigned long block_size,
335 typename std::enable_if<std::is_same<
336 std::vector<unsigned long>, u>::value>::type *) :
337 m_lookup(lookup), m_size(init_size), m_end(0),
338 m_block_size(block_size)
340 m_ids.resize(init_size);
341 m_locs.resize(init_size);
345 template <
typename key_t,
typename lookup_t,
346 typename comp_t,
typename key_map_t>
350 unsigned long init_size,
unsigned long block_size,
351 typename std::enable_if<std::is_same<
352 std::map<key_t,unsigned long>, u>::value>::type *) :
353 m_lookup(lookup), m_size(init_size), m_end(0),
354 m_block_size(block_size)
356 m_ids.resize(init_size);
360 template <
typename key_t,
typename lookup_t,
361 typename comp_t,
typename key_map_t>
364 comp_t, key_map_t>::grow(
unsigned long n,
365 typename std::enable_if<std::is_same<
366 std::vector<unsigned long>, u>::value>::type *)
374 template <
typename key_t,
typename lookup_t,
375 typename comp_t,
typename key_map_t>
378 comp_t, key_map_t>::grow(
unsigned long n,
379 typename std::enable_if<std::is_same<
380 std::map<key_t, unsigned long>, u>::value>::type *)
388 template <
typename key_t,
typename lookup_t,
389 typename comp_t,
typename key_map_t>
391 comp_t, key_map_t>::up_heapify(
unsigned long id)
399 unsigned long id_p = parent(
id);
400 if (comp(m_lookup(m_ids[
id]), m_lookup(m_ids[id_p])))
401 this->swap(
id, id_p);
404 this->up_heapify(id_p);
408 template <
typename key_t,
typename lookup_t,
409 typename comp_t,
typename key_map_t>
411 comp_t, key_map_t>::down_heapify(
unsigned long id)
418 unsigned long lc = left_child(
id);
424 unsigned long smallc = lc;
425 unsigned long rc = right_child(
id);
427 smallc = comp(m_lookup(m_ids[lc]),
428 m_lookup(m_ids[rc])) ? lc : rc;
431 if (comp(m_lookup(m_ids[
id]), m_lookup(m_ids[smallc])))
435 this->swap(
id, smallc);
436 this->down_heapify(smallc);
440 template <
typename key_t,
typename lookup_t,
441 typename comp_t,
typename key_map_t>
443 comp_t, key_map_t>::swap(
unsigned long i,
unsigned long j)
445 key_t key_i = m_ids[i];
446 key_t key_j = m_ids[j];
455 template <
typename key_t,
typename lookup_t,
typename ... Args>
456 std::ostream &
operator<<(std::ostream &os, p_teca_priority_queue<key_t, lookup_t, Args ...> &q)