00001 #ifndef GALOIS_GRAPHNODEBAG_H 00002 #define GALOIS_GRAPHNODEBAG_H 00003 00004 #include "Galois/Accumulator.h" 00005 #include "Galois/LargeArray.h" 00006 #include "Galois/Bag.h" 00007 00008 namespace Galois { 00009 00013 template<unsigned int BlockSize = 0> 00014 class GraphNodeBag { 00015 typedef Galois::InsertBag<size_t, BlockSize> Bag; 00016 typedef Galois::LargeArray<bool> Bitmask; 00017 00018 Bag bag; 00019 Galois::GAccumulator<size_t> counts; 00020 Galois::GAccumulator<size_t> numNodes; 00021 Bitmask bitmask; 00022 size_t size; 00023 bool isDense; 00024 00025 struct InitializeSmall { 00026 GraphNodeBag* self; 00027 void operator()(size_t n) { 00028 self->bitmask[n] = 0; 00029 } 00030 }; 00031 00032 struct InitializeBig { 00033 GraphNodeBag* self; 00034 void operator()(unsigned id, unsigned total) { 00035 typedef typename Bitmask::iterator It; 00036 std::pair<It,It> p = Galois::block_range(self->bitmask.begin(), self->bitmask.end(), id, total); 00037 std::fill(p.first, p.second, 0); 00038 } 00039 }; 00040 00041 struct Densify { 00042 GraphNodeBag* self; 00043 void operator()(size_t n) { 00044 self->bitmask[n] = true; 00045 } 00046 }; 00047 public: 00048 GraphNodeBag(size_t n): size(n), isDense(false) { } 00049 00050 typedef typename Bag::iterator iterator; 00051 typedef typename Bag::local_iterator local_iterator; 00052 00053 iterator begin() { return bag.begin(); } 00054 iterator end() { return bag.end(); } 00055 local_iterator local_begin() { return bag.local_begin(); } 00056 local_iterator local_end() { return bag.local_end(); } 00057 00058 void pushDense(size_t n, size_t numEdges) { 00059 assert(isDense); 00060 00061 if (!bitmask[n]) { 00062 bitmask[n] = true; 00063 push(n, numEdges); 00064 } 00065 } 00066 00067 void push(size_t n, size_t numEdges) { 00068 bag.push(n); 00069 numNodes += 1; 00070 counts += 1 + numEdges; 00071 } 00072 00073 size_t getCount() { return counts.reduce(); } 00074 00075 size_t getSize() { return numNodes.reduce(); } 00076 00077 void clear() { 00078 if (isDense) { 00079 if (numNodes.reduce() < bitmask.size() / 4) { 00080 InitializeSmall fn = { this }; 00081 Galois::do_all_local(bag, fn); 00082 } else { 00083 InitializeBig fn = { this }; 00084 Galois::on_each(fn); 00085 } 00086 } 00087 bag.clear(); 00088 counts.reset(); 00089 numNodes.reset(); 00090 00091 isDense = false; 00092 } 00093 00094 bool contains(size_t n) { 00095 assert(isDense); 00096 return bitmask[n]; 00097 } 00098 00099 bool empty() const { return bag.empty(); } 00100 00101 void densify() { 00102 isDense = true; 00103 if (bitmask.size() == 0) { 00104 bitmask.create(size); 00105 } 00106 00107 Densify fn = { this }; 00108 Galois::do_all_local(bag, fn); 00109 } 00110 }; 00111 00117 template<unsigned int BlockSize = 0> 00118 class GraphNodeBagPair { 00119 GraphNodeBag<BlockSize> bag1; 00120 GraphNodeBag<BlockSize> bag2; 00121 int curp; 00122 public: 00123 typedef GraphNodeBag<BlockSize> bag_type; 00124 00125 GraphNodeBagPair(size_t n): bag1(n), bag2(n), curp(0) { } 00126 00127 GraphNodeBag<BlockSize>& cur() { return (*this)[curp]; } 00128 GraphNodeBag<BlockSize>& next() { return (*this)[(curp+1) & 1]; } 00129 void swap() { 00130 curp = (curp + 1) & 1; 00131 next().clear(); 00132 } 00133 GraphNodeBag<BlockSize>& operator[](int i) { 00134 if (i == 0) 00135 return bag1; 00136 else 00137 return bag2; 00138 } 00139 }; 00140 00141 } 00142 #endif