00001
00026 #ifndef GALOIS_PRIORITYQUEUE_H
00027 #define GALOIS_PRIORITYQUEUE_H
00028
00029 #include "Galois/Runtime/ll/PaddedLock.h"
00030 #include "Galois/Runtime/ll/CompilerSpecific.h"
00031
00032 #include <vector>
00033 #include <algorithm>
00034 #include <set>
00035
00036 #include "Galois/Mem.h"
00037
00038 namespace Galois {
00039
00044 template <typename T, typename Cmp=std::less<T>, typename Alloc=Galois::GFixedAllocator<T> >
00045 class ThreadSafeOrderedSet {
00046 typedef std::set<T, Cmp, Alloc> Set;
00047
00048 public:
00049 typedef Set container_type;
00050 typedef typename container_type::value_type value_type;
00051 typedef typename container_type::reference reference;
00052 typedef typename container_type::const_reference const_reference;
00053 typedef typename container_type::pointer pointer;
00054 typedef typename container_type::size_type size_type;
00055 typedef typename container_type::const_iterator iterator;
00056 typedef typename container_type::const_iterator const_iterator;
00057 typedef typename container_type::const_reverse_iterator reverse_iterator;
00058 typedef typename container_type::const_reverse_iterator const_reverse_iterator;
00059 typedef Galois::Runtime::LL::SimpleLock<true> Lock_ty;
00060
00061 private:
00062 GALOIS_ATTRIBUTE_ALIGN_CACHE_LINE Lock_ty mutex;
00063 Set orderedSet;
00064
00065 public:
00066 explicit ThreadSafeOrderedSet(const Cmp& cmp=Cmp(), const Alloc& alloc=Alloc()):
00067 orderedSet(cmp, alloc)
00068 {}
00069
00070 template <typename Iter>
00071 ThreadSafeOrderedSet(Iter b, Iter e, const Cmp& cmp=Cmp(), const Alloc& alloc=Alloc())
00072 : orderedSet(cmp, alloc)
00073 {
00074 for (; b != e; ++b) {
00075 orderedSet.insert(*b);
00076 }
00077 }
00078
00079 bool empty() const {
00080 mutex.lock();
00081 bool ret = orderedSet.empty();
00082 mutex.unlock();
00083
00084 return ret;
00085 }
00086
00087 size_type size() const {
00088 mutex.lock();
00089 size_type sz = orderedSet.size();
00090 mutex.unlock();
00091
00092 return sz;
00093 }
00094
00095 value_type top() const {
00096 mutex.lock();
00097 value_type x = *orderedSet.begin();
00098 mutex.unlock();
00099 return x;
00100 }
00101
00102 bool find(const value_type& x) const {
00103 mutex.lock();
00104 bool ret = (orderedSet.find(x) != orderedSet.end());
00105 mutex.unlock();
00106 return ret;
00107 }
00108
00109 void push(const value_type& x) {
00110 mutex.lock();
00111 orderedSet.insert(x);
00112 mutex.unlock();
00113 }
00114
00115 value_type pop() {
00116 mutex.lock();
00117 value_type x = *orderedSet.begin();
00118 orderedSet.erase(orderedSet.begin());
00119 mutex.unlock();
00120 return x;
00121 }
00122
00123 bool remove(const value_type& x) {
00124 mutex.lock();
00125 bool ret = false;
00126
00127 if (x == *orderedSet.begin()) {
00128 orderedSet.erase(orderedSet.begin());
00129 ret = true;
00130 } else {
00131 size_type s = orderedSet.erase(x);
00132 ret = (s > 0);
00133 }
00134 mutex.unlock();
00135
00136 return ret;
00137 }
00138
00139 const_iterator begin() const { return orderedSet.begin(); }
00140 const_iterator end() const { return orderedSet.end(); }
00141 };
00142
00143 template <typename T, typename Cmp=std::less<T>, typename Cont=std::vector<T> >
00144 class MinHeap {
00145 public:
00146 typedef Cont container_type;
00147
00148 typedef typename container_type::value_type value_type;
00149 typedef typename container_type::reference reference;
00150 typedef typename container_type::const_reference const_reference;
00151 typedef typename container_type::pointer pointer;
00152 typedef typename container_type::size_type size_type;
00153 typedef typename container_type::const_iterator iterator;
00154 typedef typename container_type::const_iterator const_iterator;
00155 typedef typename container_type::const_reverse_iterator reverse_iterator;
00156 typedef typename container_type::const_reverse_iterator const_reverse_iterator;
00157
00158
00159 protected:
00160 struct RevCmp {
00161 Cmp cmp;
00162
00163 explicit RevCmp(const Cmp& cmp): cmp(cmp) {}
00164
00165 bool operator()(const T& left, const T& right) const {
00166 return !cmp(left, right);
00167 }
00168 };
00169
00170 Cont container;
00171 RevCmp revCmp;
00172
00173 const_reference top_internal() const {
00174 assert(!container.empty());
00175 return container.front();
00176 }
00177
00178 value_type pop_internal() {
00179 assert(!container.empty());
00180 std::pop_heap(container.begin(), container.end(), revCmp);
00181
00182 value_type x = container.back();
00183 container.pop_back();
00184
00185 return x;
00186 }
00187
00188 public:
00189 explicit MinHeap(const Cmp& cmp=Cmp(), const Cont& container=Cont())
00190 : container(container), revCmp(cmp)
00191 {}
00192
00193 template <typename Iter>
00194 MinHeap(Iter b, Iter e, const Cmp& cmp=Cmp())
00195 : container(b, e), revCmp(cmp)
00196 {
00197 std::make_heap(container.begin(), container.end());
00198 }
00199
00200 bool empty() const {
00201 return container.empty();
00202 }
00203
00204 size_type size() const {
00205 return container.size();
00206 }
00207
00208 const_reference top() const {
00209 return container.front();
00210 }
00211
00212 void push(const value_type& x) {
00213 container.push_back(x);
00214 std::push_heap(container.begin(), container.end(), revCmp);
00215 }
00216
00217 value_type pop() {
00218 assert(!container.empty());
00219 std::pop_heap(container.begin(), container.end(), revCmp);
00220
00221 value_type x = container.back();
00222 container.pop_back();
00223 return x;
00224 }
00225
00226 bool remove(const value_type& x) {
00227 bool ret = false;
00228
00229
00230 if (x == top()) {
00231 pop();
00232 ret = true;
00233 } else {
00234 typename container_type::iterator nend =
00235 std::remove(container.begin(), container.end(), x);
00236
00237 ret = (nend != container.end());
00238 container.erase(nend, container.end());
00239
00240 std::make_heap(container.begin(), container.end(), revCmp);
00241 }
00242
00243 return ret;
00244 }
00245
00246 bool find(const value_type& x) const {
00247 return (std::find(begin(), end(), x) != end());
00248 }
00249
00250 const_iterator begin() const { return container.begin(); }
00251 const_iterator end() const { return container.end(); }
00252
00253 void reserve(size_type s) {
00254 container.reserve(s);
00255 }
00256 };
00257
00261 template <typename T, typename Cmp=std::less<T> >
00262 class ThreadSafeMinHeap {
00263 public:
00264 typedef MinHeap<T, Cmp> container_type;
00265
00266 typedef typename container_type::value_type value_type;
00267 typedef typename container_type::reference reference;
00268 typedef typename container_type::const_reference const_reference;
00269 typedef typename container_type::pointer pointer;
00270 typedef typename container_type::size_type size_type;
00271 typedef typename container_type::const_iterator iterator;
00272 typedef typename container_type::const_iterator const_iterator;
00273 typedef typename container_type::const_reverse_iterator reverse_iterator;
00274 typedef typename container_type::const_reverse_iterator const_reverse_iterator;
00275
00276 protected:
00277 typedef Galois::Runtime::LL::SimpleLock<true> Lock_ty;
00278
00279 GALOIS_ATTRIBUTE_ALIGN_CACHE_LINE Lock_ty mutex;
00280 container_type heap;
00281
00282 public:
00283 explicit ThreadSafeMinHeap(const Cmp& cmp=Cmp())
00284 : heap(cmp)
00285 {}
00286
00287 template <typename Iter>
00288 ThreadSafeMinHeap(Iter b, Iter e, const Cmp& cmp=Cmp())
00289 : heap(b, e, cmp)
00290 {}
00291
00292
00293 bool empty() const {
00294 mutex.lock();
00295 bool ret = heap.empty();
00296 mutex.unlock();
00297
00298 return ret;
00299 }
00300
00301 size_type size() const {
00302 mutex.lock();
00303 size_type sz = heap.size();
00304 mutex.unlock();
00305
00306 return sz;
00307 }
00308
00309
00310
00311
00312 value_type top() const {
00313 mutex.lock();
00314 value_type x = heap.top();
00315 mutex.unlock();
00316
00317 return x;
00318 }
00319
00320 void push(const value_type& x) {
00321 mutex.lock();
00322 heap.push(x);
00323 mutex.unlock();
00324 }
00325
00326 value_type pop() {
00327 mutex.lock();
00328 value_type x = heap.pop();
00329 mutex.unlock();
00330 return x;
00331 }
00332
00333 bool remove(const value_type& x) {
00334
00335 mutex.lock();
00336 bool ret = heap.remove(x);
00337 mutex.unlock();
00338
00339 return ret;
00340 }
00341
00342 bool find(const value_type& x) const {
00343 mutex.lock();
00344 bool ret = heap.find(x);
00345 mutex.unlock();
00346
00347 return ret;
00348 }
00349
00350
00351 const_iterator begin() const { return heap.begin(); }
00352 const_iterator end() const { return heap.end(); }
00353
00354 void reserve(size_type s) {
00355 heap.reserve(s);
00356 }
00357 };
00358
00359 }
00360
00361 #endif