00001
00023 #ifndef GALOIS_WORKLIST_ORDEREDLIST_H
00024 #define GALOIS_WORKLIST_ORDEREDLIST_H
00025
00026 #include "Galois/FlatMap.h"
00027
00028 namespace Galois {
00029 namespace WorkList {
00030
00031 template<class Compare = std::less<int>, typename T = int, bool concurrent = true>
00032 class OrderedList : private boost::noncopyable, private Runtime::LL::PaddedLock<concurrent> {
00033 typedef Galois::flat_map<T, std::deque<T>, Compare> Map;
00034
00035 Map map;
00036
00037 using Runtime::LL::PaddedLock<concurrent>::lock;
00038 using Runtime::LL::PaddedLock<concurrent>::try_lock;
00039 using Runtime::LL::PaddedLock<concurrent>::unlock;
00040
00041 public:
00042 template<bool newconcurrent>
00043 struct rethread { typedef OrderedList<Compare, T, newconcurrent> type; };
00044
00045 template<typename Tnew>
00046 struct retype { typedef OrderedList<Compare, Tnew, concurrent> type; };
00047
00048 typedef T value_type;
00049
00050 void push(value_type val) {
00051 lock();
00052 std::deque<T>& list = map[val];
00053 list.push_back(val);
00054 unlock();
00055 }
00056
00057 template<typename Iter>
00058 void push(Iter b, Iter e) {
00059 lock();
00060 while (b != e) {
00061 std::deque<T>& list = map[*b];
00062 list.push_back(*b);
00063 ++b;
00064 }
00065 unlock();
00066 }
00067
00068 template<typename RangeTy>
00069 void push_initial(RangeTy range) {
00070 if (Runtime::LL::getTID() == 0)
00071 push(range.begin(), range.end());
00072 }
00073
00074 Galois::optional<value_type> pop() {
00075 lock();
00076 if (map.empty()) {
00077 unlock();
00078 return Galois::optional<value_type>();
00079 }
00080 auto ii = map.begin();
00081 std::deque<T>& list = ii->second;
00082 Galois::optional<value_type> v(list.front());
00083 list.pop_front();
00084 if (list.empty())
00085 map.erase(ii);
00086 unlock();
00087 return v;
00088 }
00089 };
00090 GALOIS_WLCOMPILECHECK(OrderedList)
00091 }
00092 }
00093 #endif