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