00001
00023 #ifndef GALOIS_RUNTIME_INSBAG_H
00024 #define GALOIS_RUNTIME_INSBAG_H
00025
00026 #include "Galois/util/Accumulator.h"
00027 #include "Galois/Runtime/mm/mem.h"
00028 #include <list>
00029
00030 #include <boost/functional.hpp>
00031 #include <boost/iterator/transform_iterator.hpp>
00032
00033 namespace GaloisRuntime {
00034
00035 template< class T>
00036 class galois_insert_bag {
00037
00038 class InsBagTag;
00039 typedef boost::intrusive::list_base_hook<boost::intrusive::tag<InsBagTag>,
00040 boost::intrusive::link_mode<boost::intrusive::normal_link>
00041 > InsBagBaseHook;
00042
00043 struct holder : public InsBagBaseHook {
00044 T data;
00045 T& getData() { return data; }
00046 };
00047
00048 typedef boost::intrusive::list<holder,
00049 boost::intrusive::base_hook<InsBagBaseHook>,
00050 boost::intrusive::constant_time_size<false>
00051 > ListTy;
00052
00053 struct splicer {
00054 void operator()(ListTy& lhs, ListTy& rhs) {
00055 if (!rhs.empty())
00056 lhs.splice(lhs.begin(), rhs);
00057 }
00058 };
00059
00060 Galois::GReducible<ListTy, splicer> heads;
00061
00062
00063
00064 GaloisRuntime::MM::FixedSizeAllocator allocSrc;
00065
00066 public:
00067 galois_insert_bag()
00068 :allocSrc(sizeof(holder))
00069 {}
00070
00071 ~galois_insert_bag() {
00072 ListTy& L = heads.get();
00073 while (!L.empty()) {
00074 holder* H = &L.front();
00075 L.pop_front();
00076 allocSrc.deallocate(H);
00077 }
00078 }
00079
00080 typedef T value_type;
00081 typedef const T& const_reference;
00082 typedef T& reference;
00083
00084 typedef typename boost::transform_iterator<boost::mem_fun_ref_t<T&,holder>, typename ListTy::iterator> iterator;
00085
00086 iterator begin() {
00087 return boost::make_transform_iterator(heads.get().begin(), boost::mem_fun_ref(&holder::getData));
00088 }
00089 iterator end() {
00090 return boost::make_transform_iterator(heads.get().end(), boost::mem_fun_ref(&holder::getData));
00091 }
00092
00093
00094 reference push(const T& val) {
00095 holder* h = (holder*)allocSrc.allocate(sizeof(holder));
00096 new ((void *)&h->data) T(val);
00097 heads.get().push_front(*h);
00098 return h->data;
00099 }
00100
00101 };
00102 }
00103 #endif