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