Galois
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
PriorityQueue.h
Go to the documentation of this file.
1 /*
2  * This file belongs to the Galois project, a C++ library for exploiting
3  * parallelism. The code is being released under the terms of the 3-Clause BSD
4  * License (a copy is located in LICENSE.txt at the top-level directory).
5  *
6  * Copyright (C) 2018, The University of Texas at Austin. All rights reserved.
7  * UNIVERSITY EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES CONCERNING THIS
8  * SOFTWARE AND DOCUMENTATION, INCLUDING ANY WARRANTIES OF MERCHANTABILITY,
9  * FITNESS FOR ANY PARTICULAR PURPOSE, NON-INFRINGEMENT AND WARRANTIES OF
10  * PERFORMANCE, AND ANY WARRANTY THAT MIGHT OTHERWISE ARISE FROM COURSE OF
11  * DEALING OR USAGE OF TRADE. NO WARRANTY IS EITHER EXPRESS OR IMPLIED WITH
12  * RESPECT TO THE USE OF THE SOFTWARE OR DOCUMENTATION. Under no circumstances
13  * shall University be liable for incidental, special, indirect, direct or
14  * consequential damages or loss of profits, interruption of business, or
15  * related expenses which may arise from use of Software or Documentation,
16  * including but not limited to those resulting from defects in Software and/or
17  * Documentation, or loss or inaccuracy of data of any kind.
18  */
19 
20 #ifndef GALOIS_PRIORITYQUEUE_H
21 #define GALOIS_PRIORITYQUEUE_H
22 
23 #include <algorithm>
24 #include <set>
25 #include <vector>
26 
27 #include "galois/config.h"
28 #include "galois/Mem.h"
31 
32 namespace galois {
33 
39 template <typename T, typename Cmp = std::less<T>,
40  typename Alloc = galois::FixedSizeAllocator<T>>
42  typedef std::set<T, Cmp, Alloc> Set;
43 
44 public:
45  typedef Set container_type;
47  typedef typename container_type::reference reference;
48  typedef typename container_type::const_reference const_reference;
49  typedef typename container_type::pointer pointer;
50  typedef typename container_type::size_type size_type;
51  typedef typename container_type::const_iterator iterator;
52  typedef typename container_type::const_iterator const_iterator;
53  typedef typename container_type::const_reverse_iterator reverse_iterator;
54  typedef
55  typename container_type::const_reverse_iterator const_reverse_iterator;
57 
58 private:
60  Set orderedSet;
61 
62 public:
63  template <typename _T, typename _Cmp = std::less<_T>,
64  typename _Alloc = galois::FixedSizeAllocator<_T>>
65  using retype =
66  ThreadSafeOrderedSet<_T, _Cmp,
67  _Alloc>; // FIXME: loses Alloc and Cmp types
68 
69  explicit ThreadSafeOrderedSet(const Cmp& cmp = Cmp(),
70  const Alloc& alloc = Alloc())
71  : orderedSet(cmp, alloc) {}
72 
73  template <typename Iter>
74  ThreadSafeOrderedSet(Iter b, Iter e, const Cmp& cmp = Cmp(),
75  const Alloc& alloc = Alloc())
76  : orderedSet(cmp, alloc) {
77  for (; b != e; ++b) {
78  orderedSet.insert(*b);
79  }
80  }
81 
82  bool empty() const {
83  mutex.lock();
84  bool ret = orderedSet.empty();
85  mutex.unlock();
86 
87  return ret;
88  }
89 
90  size_type size() const {
91  mutex.lock();
92  size_type sz = orderedSet.size();
93  mutex.unlock();
94 
95  return sz;
96  }
97 
98  value_type top() const {
99  mutex.lock();
100  value_type x = *orderedSet.begin();
101  mutex.unlock();
102  return x;
103  }
104 
105  bool find(const value_type& x) const {
106  mutex.lock();
107  bool ret = (orderedSet.find(x) != orderedSet.end());
108  mutex.unlock();
109  return ret;
110  }
111 
112  // for compatibility with various stl types
113  inline void push_back(const value_type& x) { this->push(x); }
114  inline void insert(const value_type& x) { this->push(x); }
115 
116  bool push(const value_type& x) {
117  mutex.lock();
118  auto p = orderedSet.insert(x);
119  mutex.unlock();
120  return p.second;
121  }
122 
124  mutex.lock();
125  value_type x = *orderedSet.begin();
126  orderedSet.erase(orderedSet.begin());
127  mutex.unlock();
128  return x;
129  }
130 
131  bool remove(const value_type& x) {
132  mutex.lock();
133  bool ret = false;
134 
135  if (x == *orderedSet.begin()) {
136  orderedSet.erase(orderedSet.begin());
137  ret = true;
138  } else {
139  size_type s = orderedSet.erase(x);
140  ret = (s > 0);
141  }
142  mutex.unlock();
143 
144  return ret;
145  }
146 
147  void clear() {
148  mutex.lock();
149  orderedSet.clear();
150  mutex.unlock();
151  }
152 
153  const_iterator begin() const { return orderedSet.begin(); }
154  const_iterator end() const { return orderedSet.end(); }
155 };
156 
157 template <typename T, typename Cmp = std::less<T>,
158  typename Cont = std::vector<T, runtime::Pow_2_BlockAllocator<T>>>
159 class MinHeap {
160 public:
162  typedef Cont container_type;
163 
165  typedef typename container_type::reference reference;
166  typedef typename container_type::const_reference const_reference;
167  typedef typename container_type::pointer pointer;
168  typedef typename container_type::size_type size_type;
169  typedef typename container_type::const_iterator iterator;
170  typedef typename container_type::const_iterator const_iterator;
171  typedef typename container_type::const_reverse_iterator reverse_iterator;
172  typedef
173  typename container_type::const_reverse_iterator const_reverse_iterator;
174  // typedef typename container_type::const_iterator iterator;
175 
176 protected:
177  struct RevCmp {
178  Cmp cmp;
179 
180  explicit RevCmp(const Cmp& cmp) : cmp(cmp) {}
181 
182  bool operator()(const T& left, const T& right) const {
183  return cmp(right, left);
184  }
185  };
186 
187  Cont container;
188  RevCmp revCmp;
189 
191  assert(!container.empty());
192  return container.front();
193  }
194 
196  assert(!container.empty());
197  std::pop_heap(container.begin(), container.end(), revCmp);
198 
199  value_type x = container.back();
200  container.pop_back();
201 
202  return x;
203  }
204 
205 public:
206  explicit MinHeap(const Cmp& cmp = Cmp(), const Cont& container = Cont())
207  : container(container), revCmp(cmp) {}
208 
209  template <typename Iter>
210  MinHeap(Iter b, Iter e, const Cmp& cmp = Cmp())
211  : container(b, e), revCmp(cmp) {
212  std::make_heap(container.begin(), container.end());
213  }
214 
215  bool empty() const { return container.empty(); }
216 
217  size_type size() const { return container.size(); }
218 
219  const_reference top() const { return container.front(); }
220 
221  // for compatibility with various stl types
222  inline void push_back(const value_type& x) { this->push(x); }
223  inline void insert(const value_type& x) { this->push(x); }
224 
225  void push(const value_type& x) {
226  container.push_back(x);
227  std::push_heap(container.begin(), container.end(), revCmp);
228  }
229 
231  assert(!container.empty());
232  std::pop_heap(container.begin(), container.end(), revCmp);
233 
234  value_type x = container.back();
235  container.pop_back();
236  return x;
237  }
238 
239  bool remove(const value_type& x) {
240  bool ret = false;
241 
242  // TODO: write a better remove method
243  if (x == top()) {
244  pop();
245  ret = true;
246  } else {
247  typename container_type::iterator nend =
248  std::remove(container.begin(), container.end(), x);
249 
250  ret = (nend != container.end());
251  container.erase(nend, container.end());
252 
253  std::make_heap(container.begin(), container.end(), revCmp);
254  }
255 
256  return ret;
257  }
258 
259  bool find(const value_type& x) const {
260  return (std::find(begin(), end(), x) != end());
261  }
262 
263  void clear() { container.clear(); }
264 
265  const_iterator begin() const { return container.begin(); }
266  const_iterator end() const { return container.end(); }
267 
268  void reserve(size_type s) { container.reserve(s); }
269 };
270 
274 template <typename T, typename Cmp = std::less<T>>
276 public:
278 
287  typedef
289 
290 protected:
292 
295 
296 public:
297  explicit ThreadSafeMinHeap(const Cmp& cmp = Cmp()) : heap(cmp) {}
298 
299  template <typename Iter>
300  ThreadSafeMinHeap(Iter b, Iter e, const Cmp& cmp = Cmp()) : heap(b, e, cmp) {}
301 
302  bool empty() const {
303  mutex.lock();
304  bool ret = heap.empty();
305  mutex.unlock();
306 
307  return ret;
308  }
309 
310  size_type size() const {
311  mutex.lock();
312  size_type sz = heap.size();
313  mutex.unlock();
314 
315  return sz;
316  }
317 
318  // can't return a reference, because the reference may not be pointing
319  // to a valid location due to vector doubling in size and moving to
320  // another memory location
321  value_type top() const {
322  mutex.lock();
323  value_type x = heap.top();
324  mutex.unlock();
325 
326  return x;
327  }
328 
329  // for compatibility with various stl types
330  inline void push_back(const value_type& x) { this->push(x); }
331  inline void insert(const value_type& x) { this->push(x); }
332 
333  void push(const value_type& x) {
334  mutex.lock();
335  heap.push(x);
336  mutex.unlock();
337  }
338 
340  mutex.lock();
341  value_type x = heap.pop();
342  mutex.unlock();
343  return x;
344  }
345 
346  bool remove(const value_type& x) {
347  // TODO: write a better remove method
348  mutex.lock();
349  bool ret = heap.remove(x);
350  mutex.unlock();
351 
352  return ret;
353  }
354 
355  bool find(const value_type& x) const {
356  mutex.lock();
357  bool ret = heap.find(x);
358  mutex.unlock();
359 
360  return ret;
361  }
362 
363  void clear() {
364  mutex.lock();
365  heap.clear();
366  mutex.unlock();
367  }
368 
369  // TODO: can't use in parallel context
370  const_iterator begin() const { return heap.begin(); }
371  const_iterator end() const { return heap.end(); }
372 
373  void reserve(size_type s) { heap.reserve(s); }
374 };
375 
376 } // namespace galois
377 
378 #endif
size_type size() const
Definition: PriorityQueue.h:217
container_type::const_reverse_iterator reverse_iterator
Definition: PriorityQueue.h:171
void reserve(size_type s)
Definition: PriorityQueue.h:268
galois::substrate::SimpleLock Lock_ty
Definition: PriorityQueue.h:291
container_type::reference reference
Definition: PriorityQueue.h:165
container_type::const_reverse_iterator reverse_iterator
Definition: PriorityQueue.h:286
Thread-safe min heap.
Definition: PriorityQueue.h:275
const_iterator begin() const
Definition: PriorityQueue.h:153
container_type::pointer pointer
Definition: PriorityQueue.h:49
bool operator()(const T &left, const T &right) const
Definition: PriorityQueue.h:182
const_iterator end() const
Definition: PriorityQueue.h:266
ThreadSafeMinHeap(const Cmp &cmp=Cmp())
Definition: PriorityQueue.h:297
Cmp cmp
Definition: PriorityQueue.h:178
const_reference top() const
Definition: PriorityQueue.h:219
Cont container_type
Definition: PriorityQueue.h:162
value_type top() const
Definition: PriorityQueue.h:98
bool remove(const value_type &x)
Definition: PriorityQueue.h:239
void reserve(size_type s)
Definition: PriorityQueue.h:373
void push_back(const value_type &x)
Definition: PriorityQueue.h:222
Cont container
Definition: PriorityQueue.h:187
size_type size() const
Definition: PriorityQueue.h:90
container_type::const_iterator iterator
Definition: PriorityQueue.h:284
const_iterator end() const
Definition: PriorityQueue.h:154
container_type::const_iterator iterator
Definition: PriorityQueue.h:51
value_type pop_internal()
Definition: PriorityQueue.h:195
container_type::const_reverse_iterator const_reverse_iterator
Definition: PriorityQueue.h:288
container_type::value_type value_type
Definition: PriorityQueue.h:164
constexpr int GALOIS_CACHE_LINE_SIZE
Definition: CompilerSpecific.h:37
Thread-safe ordered set.
Definition: PriorityQueue.h:41
container_type::const_iterator const_iterator
Definition: PriorityQueue.h:285
Definition: PriorityQueue.h:177
const_reference top_internal() const
Definition: PriorityQueue.h:190
void unlock() const
Definition: SimpleLock.h:68
galois::substrate::SimpleLock Lock_ty
Definition: PriorityQueue.h:56
container_type::const_iterator iterator
Definition: PriorityQueue.h:169
container_type::const_reverse_iterator const_reverse_iterator
Definition: PriorityQueue.h:55
Definition: PriorityQueue.h:159
container_type::const_reverse_iterator const_reverse_iterator
Definition: PriorityQueue.h:173
void push(const value_type &x)
Definition: PriorityQueue.h:333
ThreadSafeOrderedSet(Iter b, Iter e, const Cmp &cmp=Cmp(), const Alloc &alloc=Alloc())
Definition: PriorityQueue.h:74
container_type::const_reference const_reference
Definition: PriorityQueue.h:48
void insert(const value_type &x)
Definition: PriorityQueue.h:331
container_type::reference reference
Definition: PriorityQueue.h:47
void push_back(const value_type &x)
Definition: PriorityQueue.h:330
MinHeap< T, Cmp > container_type
Definition: PriorityQueue.h:277
bool find(const value_type &x) const
Definition: PriorityQueue.h:259
container_type::pointer pointer
Definition: PriorityQueue.h:282
container_type::size_type size_type
Definition: PriorityQueue.h:50
Set container_type
Definition: PriorityQueue.h:45
bool empty() const
Definition: PriorityQueue.h:215
Definition: runtime/Mem.h:864
container_type::value_type value_type
Definition: PriorityQueue.h:279
container_type::size_type size_type
Definition: PriorityQueue.h:283
const_iterator end() const
Definition: PriorityQueue.h:371
container_type::const_iterator const_iterator
Definition: PriorityQueue.h:170
container_type heap
Definition: PriorityQueue.h:294
value_type top() const
Definition: PriorityQueue.h:321
container_type::size_type size_type
Definition: PriorityQueue.h:168
void * alloc()
Definition: PerThreadStorage.cpp:42
value_type pop()
Definition: PriorityQueue.h:123
const_iterator begin() const
Definition: PriorityQueue.h:370
RevCmp(const Cmp &cmp)
Definition: PriorityQueue.h:180
void clear()
Definition: PriorityQueue.h:147
runtime::Pow_2_BlockAllocator< T > alloc_type
Definition: PriorityQueue.h:161
void insert(const value_type &x)
Definition: PriorityQueue.h:223
MinHeap(const Cmp &cmp=Cmp(), const Cont &container=Cont())
Definition: PriorityQueue.h:206
container_type::const_iterator const_iterator
Definition: PriorityQueue.h:52
container_type::const_reference const_reference
Definition: PriorityQueue.h:281
value_type pop()
Definition: PriorityQueue.h:230
bool find(const value_type &x) const
Definition: PriorityQueue.h:105
void lock() const
Definition: SimpleLock.h:55
container_type::pointer pointer
Definition: PriorityQueue.h:167
SimpleLock is a spinlock.
Definition: SimpleLock.h:36
size_type size() const
Definition: PriorityQueue.h:310
container_type::reference reference
Definition: PriorityQueue.h:280
container_type::const_reference const_reference
Definition: PriorityQueue.h:166
void clear()
Definition: PriorityQueue.h:263
container_type::value_type value_type
Definition: PriorityQueue.h:46
ThreadSafeOrderedSet(const Cmp &cmp=Cmp(), const Alloc &alloc=Alloc())
Definition: PriorityQueue.h:69
const_iterator begin() const
Definition: PriorityQueue.h:265
void insert(const value_type &x)
Definition: PriorityQueue.h:114
value_type pop()
Definition: PriorityQueue.h:339
Lock_ty mutex
Definition: PriorityQueue.h:293
ThreadSafeMinHeap(Iter b, Iter e, const Cmp &cmp=Cmp())
Definition: PriorityQueue.h:300
container_type::const_reverse_iterator reverse_iterator
Definition: PriorityQueue.h:53
bool push(const value_type &x)
Definition: PriorityQueue.h:116
bool empty() const
Definition: PriorityQueue.h:82
void clear()
Definition: PriorityQueue.h:363
void push_back(const value_type &x)
Definition: PriorityQueue.h:113
T value_type
Definition: Executor_ParaMeter.h:111
bool empty() const
Definition: PriorityQueue.h:302
void push(const value_type &x)
Definition: PriorityQueue.h:225
RevCmp revCmp
Definition: PriorityQueue.h:188
bool find(const value_type &x) const
Definition: PriorityQueue.h:355