00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef GALOIS_SPARSEBITVECTOR_H
00023 #define GALOIS_SPARSEBITVECTOR_H
00024
00025 #include "Galois/Runtime/ll/SimpleLock.h"
00026
00027 #include <vector>
00028 #include <string>
00029 #include <ostream>
00030
00031 namespace Galois {
00032
00039 struct SparseBitVector {
00040 typedef unsigned long WORD;
00041 typedef Galois::Runtime::LL::SimpleLock<true> LockType;
00042 static const unsigned wordsize = sizeof(WORD)*8;
00043
00044 struct OneWord {
00045 WORD bits;
00046 unsigned base;
00047 struct OneWord *next;
00048 LockType kulup;
00049
00050 bool set(unsigned oo) {
00051 WORD oribits = bits;
00052 bits |= ((WORD)1 << oo);
00053 return bits != oribits;
00054 }
00055
00056 OneWord(unsigned bb, unsigned oo) {
00057 base = bb;
00058 set(oo);
00059 next = 0;
00060 }
00061
00062 OneWord() { }
00063
00064 unsigned unify(OneWord *second) {
00065 if (second) {
00066 WORD oribits = count();
00067 bits |= second->bits;
00068 return count() - oribits;
00069 }
00070 return 0;
00071 }
00072 unsigned count() {
00073 unsigned numElements = 0;
00074 WORD powerof2 = 1;
00075
00076 for (unsigned ii = 0; ii < wordsize; ++ii) {
00077 if (bits & powerof2) {
00078 ++numElements;
00079 }
00080 powerof2 <<= 1;
00081 }
00082 return numElements;
00083 }
00084 inline bool isSubsetEq(OneWord *second) {
00085 return (bits & second->bits) == bits;
00086 }
00087 OneWord *clone() {
00088 OneWord *newword = new OneWord();
00089 newword->base = base;
00090 newword->bits = bits;
00091 newword->next = 0;
00092 return newword;
00093 }
00094 OneWord *cloneAll() {
00095 OneWord *newlist = clone();
00096 OneWord *ptr2;
00097
00098 for (OneWord *newlistptr = newlist, *ptr = next; ptr;) {
00099
00100 newlistptr->next = ptr->clone();
00101 ptr2 = ptr->next;
00102
00103 ptr = ptr2;
00104 newlistptr = newlistptr->next;
00105 }
00106 return newlist;
00107 }
00108 void getAllSetBits(std::vector<unsigned> &setbits) {
00109 WORD powerof2 = 1;
00110 unsigned bitno = 0;
00111
00112 for (unsigned ii = 0; ii < wordsize; ++ii) {
00113 if (bits & powerof2) {
00114 setbits.push_back(base*wordsize + bitno);
00115 }
00116 powerof2 <<= 1;
00117 ++bitno;
00118 }
00119 }
00120 void lock() {
00121 kulup.lock();
00122 }
00123 void unlock() {
00124 kulup.unlock();
00125 }
00126 };
00127
00128 OneWord *head;
00129 LockType headkulup;
00130
00131 SparseBitVector() {
00132 init(0);
00133 }
00134 void init() {
00135 init(0);
00136 }
00137 void init(unsigned nelements) {
00138 head = 0;
00139 }
00140 void lock() {
00141 headkulup.lock();
00142 }
00143 void unlock() {
00144 headkulup.unlock();
00145 }
00146 bool set(unsigned bit) {
00147 unsigned base, offset;
00148 getOffsets(bit, base, offset);
00149
00150 OneWord *ptr, *prev;
00151 ptr = head;
00152 prev = 0;
00153 for (; ptr && ptr->base <= base; ptr = ptr->next) {
00154 if (ptr->base == base) {
00155 return ptr->set(offset);
00156 }
00157 prev = ptr;
00158 }
00159 OneWord *newword = new OneWord(base, offset);
00160 if (prev) {
00161
00162 newword->next = prev->next;
00163 prev->next = newword;
00164
00165 } else {
00166
00167 newword->next = head;
00168 head = newword;
00169
00170 }
00171 return true;
00172 }
00173 unsigned unify(SparseBitVector &second) {
00174 unsigned nchanged = 0;
00175 OneWord *prev = 0, *ptrone, *ptrtwo;
00176 for (ptrone = head, ptrtwo = second.head; ptrone && ptrtwo;) {
00177 if (ptrone->base == ptrtwo->base) {
00178
00179 nchanged += ptrone->unify(ptrtwo);
00180 prev = ptrone; ptrone = ptrone->next;
00181 ptrtwo = ptrtwo->next;
00182
00183 } else if (ptrone->base < ptrtwo->base) {
00184 prev = ptrone;
00185
00186 ptrone = ptrone->next;
00187
00188 } else {
00189 OneWord *newword = ptrtwo->clone();
00190 newword->next = ptrone;
00191 if (prev) {
00192
00193 prev->next = newword;
00194
00195 prev = newword;
00196 } else {
00197
00198 head = prev = newword;
00199
00200 }
00201 ptrtwo = ptrtwo->next;
00202 }
00203 }
00204 if (ptrtwo) {
00205 OneWord *remaining = ptrtwo->cloneAll();
00206 if (prev) {
00207
00208 prev->next = remaining;
00209
00210 } else if (ptrtwo) {
00211
00212 head = remaining;
00213
00214 }
00215 }
00216 return nchanged;
00217 }
00218 bool isSubsetEq(SparseBitVector &second) {
00219 OneWord *ptrone, *ptrtwo;
00220 for (ptrone = head, ptrtwo = second.head; ptrone && ptrtwo; ptrone = ptrone->next) {
00221 if (ptrone->base == ptrtwo->base) {
00222 if (!ptrone->isSubsetEq(ptrtwo)) {
00223 return false;
00224 }
00225 ptrtwo = ptrtwo->next;
00226 } else if (ptrone->base > ptrtwo->base) {
00227 return false;
00228 }
00229 }
00230 if (ptrone) {
00231 return false;
00232 }
00233 return true;
00234 }
00235 inline void getOffsets(unsigned bit, unsigned &ventry, unsigned &wbit) {
00236 ventry = bit / wordsize;
00237 wbit = bit % wordsize;
00238 }
00239 unsigned count() {
00240 unsigned nbits = 0;
00241 for (OneWord *ptr = head; ptr; ptr = ptr->next) {
00242 nbits += ptr->count();
00243 }
00244 return nbits;
00245 }
00246 unsigned getAllSetBits(std::vector<unsigned> &setbits) {
00247 unsigned nnodes = 0;
00248 for (OneWord *ptr = head; ptr; ptr = ptr->next) {
00249 ptr->getAllSetBits(setbits);
00250 ++nnodes;
00251 }
00252 return nnodes;
00253 }
00254 void print(std::ostream& out, std::string prefix = std::string("")) {
00255 std::vector<unsigned> setbits;
00256 unsigned nnodes = getAllSetBits(setbits);
00257 out << "Elements(" << nnodes << "): ";
00258 for (std::vector<unsigned>::iterator ii = setbits.begin(); ii != setbits.end(); ++ii) {
00259 out << prefix << *ii << ", ";
00260 }
00261 out << "\n";
00262 }
00263 };
00264 }
00265
00266 #endif // _GALOIS_SPARSEBITVECTOR_H