1 #ifndef teca_priority_queue_h
2 #define teca_priority_queue_h
19 template<
typename key_t>
20 using mapped_key_t = std::map<key_t, unsigned long>;
22 using contiguous_key_t = std::vector<unsigned long>;
29 template<
typename key_t,
typename priority_t>
30 struct mapped_key_priority
32 using key_map_t = mapped_key_t<key_t>;
34 mapped_key_priority(std::map<key_t, priority_t> &mp) : m_map(&mp)
37 priority_t operator()(key_t i)
38 {
return (*m_map)[i]; }
40 std::map<key_t, priority_t> *m_map;
43 template<
typename key_t,
typename priority_t>
44 struct contiguous_key_priority
46 using key_map_t = contiguous_key_t;
48 contiguous_key_priority(
const std::vector<priority_t> &vec) :
52 priority_t operator()(key_t i)
55 const priority_t *m_vec;
59 template <
typename key_t,
typename lookup_t,
typename comp_t=std::less<>,
60 typename key_map_t=contiguous_key_t>
64 template<
typename key_t,
typename lookup_t,
typename ...Types >
65 using p_teca_priority_queue = std::shared_ptr<
111 template <
typename key_t,
typename lookup_t,
112 typename comp_t,
typename key_map_t>
121 static p_teca_priority_queue<key_t, lookup_t, comp_t, key_map_t>
122 New(lookup_t &lookup,
unsigned long init_size=256,
123 unsigned long block_size=256)
125 p_teca_priority_queue<key_t, lookup_t,
126 comp_t, key_map_t> ptr(
128 key_t, lookup_t, comp_t, key_map_t>(
129 lookup, init_size, block_size));
134 bool empty() {
return m_end == 0; }
138 void push(
const key_t &key);
144 void modified(
const key_t &key);
154 void to_stream(std::ostream &os,
bool priorities =
true);
164 template<
typename u = key_map_t>
166 unsigned long block_size,
167 typename std::enable_if<std::is_same<
168 std::vector<unsigned long>, u>::value>::type * = 0);
170 template<
typename u = key_map_t>
172 unsigned long block_size,
173 typename std::enable_if<std::is_same<
174 std::map<key_t,unsigned long>, u>::value>::type * = 0);
177 template<
typename u = key_map_t>
178 void grow(
unsigned long n,
179 typename std::enable_if<std::is_same<
180 std::vector<unsigned long>, u>::value>::type * = 0);
183 template<
typename u = key_map_t>
184 void grow(
unsigned long n,
185 typename std::enable_if<std::is_same<
186 std::map<key_t, unsigned long>, u>::value>::type * = 0);
190 void up_heapify(
unsigned long id);
194 void down_heapify(
unsigned long id);
197 void swap(
unsigned long i,
unsigned long j);
200 unsigned long left_child(
unsigned long a_id)
203 unsigned long right_child(
unsigned long a_id)
204 {
return a_id*2 + 1; }
206 unsigned long parent(
unsigned long a_id)
212 std::vector<key_t> m_ids;
214 unsigned long m_size;
216 unsigned long m_block_size;
221 template <
typename key_t,
typename lookup_t,
222 typename comp_t,
typename key_map_t>
224 comp_t, key_map_t>::push(
const key_t &key)
231 this->grow(m_size + m_block_size);
238 this->up_heapify(m_end);
242 template <
typename key_t,
typename lookup_t,
243 typename comp_t,
typename key_map_t>
245 comp_t, key_map_t>::clear()
254 template <
typename key_t,
typename lookup_t,
255 typename comp_t,
typename key_map_t>
257 comp_t, key_map_t>::modified(
const key_t &key)
260 unsigned long id = m_locs[key];
262 this->up_heapify(
id);
263 this->down_heapify(
id);
267 template <
typename key_t,
typename lookup_t,
268 typename comp_t,
typename key_map_t>
270 comp_t, key_map_t>::pop()
272 key_t id_1 = m_ids[1];
275 this->swap(1, m_end);
277 this->down_heapify(1);
283 template <
typename key_t,
typename lookup_t,
284 typename comp_t,
typename key_map_t>
286 comp_t, key_map_t>::peak()
292 template <
typename key_t,
typename lookup_t,
293 typename comp_t,
typename key_map_t>
295 comp_t, key_map_t>::to_stream(std::ostream &os,
bool priorities)
297 long log_end = std::log2(m_end);
298 long n_rows = log_end + 1;
300 for (
long i = 0; i < n_rows; ++i)
305 long n_elem = 1 << i;
306 long isp = (1 << (n_rows - 1 - i)) - 1;
307 long bsp = 2*isp + 1;
309 for (
long j = 0; j < isp; ++j)
312 for (
long j = 0; (j < n_elem) && (q < m_end); ++j)
315 os << m_lookup(m_ids[++q]);
318 for (
long k = 0; k < bsp; ++k)
327 template <
typename key_t,
typename lookup_t,
328 typename comp_t,
typename key_map_t>
332 unsigned long init_size,
unsigned long block_size,
333 typename std::enable_if<std::is_same<
334 std::vector<unsigned long>, u>::value>::type *) :
335 m_lookup(lookup), m_size(init_size), m_end(0),
336 m_block_size(block_size)
338 m_ids.resize(init_size);
339 m_locs.resize(init_size);
343 template <
typename key_t,
typename lookup_t,
344 typename comp_t,
typename key_map_t>
348 unsigned long init_size,
unsigned long block_size,
349 typename std::enable_if<std::is_same<
350 std::map<key_t,unsigned long>, u>::value>::type *) :
351 m_lookup(lookup), m_size(init_size), m_end(0),
352 m_block_size(block_size)
354 m_ids.resize(init_size);
358 template <
typename key_t,
typename lookup_t,
359 typename comp_t,
typename key_map_t>
362 comp_t, key_map_t>::grow(
unsigned long n,
363 typename std::enable_if<std::is_same<
364 std::vector<unsigned long>, u>::value>::type *)
372 template <
typename key_t,
typename lookup_t,
373 typename comp_t,
typename key_map_t>
376 comp_t, key_map_t>::grow(
unsigned long n,
377 typename std::enable_if<std::is_same<
378 std::map<key_t, unsigned long>, u>::value>::type *)
386 template <
typename key_t,
typename lookup_t,
387 typename comp_t,
typename key_map_t>
389 comp_t, key_map_t>::up_heapify(
unsigned long id)
397 unsigned long id_p = parent(
id);
398 if (comp(m_lookup(m_ids[
id]), m_lookup(m_ids[id_p])))
399 this->swap(
id, id_p);
402 this->up_heapify(id_p);
406 template <
typename key_t,
typename lookup_t,
407 typename comp_t,
typename key_map_t>
409 comp_t, key_map_t>::down_heapify(
unsigned long id)
416 unsigned long lc = left_child(
id);
422 unsigned long smallc = lc;
423 unsigned long rc = right_child(
id);
425 smallc = comp(m_lookup(m_ids[lc]),
426 m_lookup(m_ids[rc])) ? lc : rc;
429 if (comp(m_lookup(m_ids[
id]), m_lookup(m_ids[smallc])))
433 this->swap(
id, smallc);
434 this->down_heapify(smallc);
438 template <
typename key_t,
typename lookup_t,
439 typename comp_t,
typename key_map_t>
441 comp_t, key_map_t>::swap(
unsigned long i,
unsigned long j)
443 key_t key_i = m_ids[i];
444 key_t key_j = m_ids[j];
453 template <
typename key_t,
typename lookup_t,
typename ... Args>
454 std::ostream &
operator<<(std::ostream &os, p_teca_priority_queue<key_t, lookup_t, Args ...> &q)