00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <Basics.H>
00026 #include <FS.H>
00027 #include <SRPC.H>
00028 #include <VestaLog.H>
00029 #include <Recovery.H>
00030 #include <BufStream.H>
00031 #include "BitVector.H"
00032
00033 using std::endl;
00034 using Basics::OBufStream;
00035
00036
00037
00038
00039 #define BV_DEBUG
00040
00041 static const Word Zero = 0UL;
00042 static const Word One = 1UL;
00043 static const Word AllOnes = ~Zero;
00044
00045
00046 static int BitsPerWd = -1;
00047 static int BytesPerWd;
00048 static int LogBitsPerWd;
00049 static int LowBitsMask;
00050 static Word *BitMask = NULL;
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 inline short WdIndex(int n) throw ()
00077
00078
00079 {
00080 return (short)(n >> LogBitsPerWd);
00081 }
00082
00083 inline short BitIndex(int n) throw ()
00084
00085 {
00086 return (short)(n & LowBitsMask);
00087 }
00088
00089 inline short WdCnt(int n) throw ()
00090
00091
00092 {
00093 return WdIndex(n + BitsPerWd - 1);
00094 }
00095
00096 class BitVectorInit {
00097 public:
00098 BitVectorInit() throw ();
00099
00100 };
00101
00102 static BitVectorInit bitVectorInit;
00103
00104
00105 class IntervalMask
00106 {
00107 private:
00108
00109
00110
00111
00112 static Word* mask;
00113
00114 public:
00115
00116
00117 static void Init()
00118 {
00119 mask = NEW_PTRFREE_ARRAY(Word, (2 * BitsPerWd) - 1);
00120 Word* mask_middle = mask + (BitsPerWd - 1);
00121 Word left, right;
00122 mask_middle[0] = left = right = AllOnes;
00123 for (int i = 1; i < BitsPerWd; i++) {
00124 mask_middle[i] = (left <<= 1);
00125 mask_middle[-i] = (right >>= 1);
00126 }
00127 }
00128
00129 Word operator[](int index)
00130 {
00131
00132 return mask[(BitsPerWd - 1) + index];
00133 }
00134 };
00135
00136 Word* IntervalMask::mask = 0;
00137
00138
00139 static IntervalMask IntrvlMask;
00140
00141 BitVectorInit::BitVectorInit() throw ()
00142
00143 {
00144 assert(BitsPerWd < 0);
00145 int i;
00146 Word wd;
00147
00148
00149 for (BitsPerWd = 0, wd = One; wd != Zero; wd <<= 1) BitsPerWd++;
00150 BytesPerWd = BitsPerWd / 8;
00151
00152
00153 for (LogBitsPerWd = 0, wd = One; wd < BitsPerWd; wd <<= 1) {
00154 LogBitsPerWd++;
00155 }
00156
00157
00158 LowBitsMask = (short)(BitsPerWd - 1);
00159
00160
00161 BitMask = NEW_PTRFREE_ARRAY(Word, BitsPerWd);
00162 for (i = 0, wd = One; i < BitsPerWd; i++, wd <<= 1) BitMask[i] = wd;
00163
00164
00165 IntervalMask::Init();
00166 }
00167
00168
00169
00170 void BitVector::Init(int sizeHint, bool doZero) throw ()
00171 {
00172 assert(this->sz == 0 && this->firstAvailWd == 0);
00173 assert(sizeHint >= 0);
00174 short wdCnt = WdCnt(sizeHint);
00175 if (wdCnt > this->numWords) {
00176 Extend(wdCnt, false);
00177 }
00178 if (doZero) {
00179 for (int i = 0; i < this->numWords; i++) {
00180 this->word[i] = Zero;
00181 }
00182 }
00183 }
00184
00185 BitVector::BitVector(const BitVector *bv) throw ()
00186 : numWords(0), firstAvailWd(0), sz(0), word((Word *)NULL)
00187 {
00188
00189 *this = *bv;
00190 }
00191
00192
00193
00194 void BitVector::Extend(short wordCnt, bool doPreserve ) throw ()
00195 {
00196 assert(wordCnt > this->numWords);
00197 short newNumWords = max(wordCnt, 2U * this->numWords);
00198 Word *newWord = NEW_PTRFREE_ARRAY(Word, newNumWords);
00199
00200
00201 if (doPreserve) {
00202
00203 if (this->word != NULL) {
00204 memcpy((char *)newWord, (char *)(this->word),
00205 this->numWords * BytesPerWd);
00206 delete this->word;
00207 }
00208
00209
00210 for (short i = this->numWords; i < newNumWords; i++) {
00211 newWord[i] = Zero;
00212 }
00213 }
00214
00215
00216 this->numWords = newNumWords;
00217 this->word = newWord;
00218 }
00219
00220 void BitVector::ExpandSz(int i, short wx) throw ()
00221 {
00222 i++;
00223 if (wx < this->numWords) {
00224
00225 this->sz = max(this->sz, i);
00226 } else {
00227
00228 Extend(wx + 1);
00229 this->sz = i;
00230 }
00231 }
00232
00233 void BitVector::ReduceSz() throw ()
00234 {
00235 short lastWd = WdCnt(this->sz) - 1;
00236 assert(lastWd < this->numWords);
00237 short i;
00238 for (i = lastWd; i >= 0 && this->word[i] == Zero; i--) ;
00239 this->sz = min(this->sz, ((int)(i+1)) * BitsPerWd);
00240 assert(this->firstAvailWd * BitsPerWd <= this->sz);
00241 }
00242
00243
00244
00245 bool BitVector::IsEmpty() const throw ()
00246 {
00247
00248 if (this->sz == 0) return true;
00249 if (this->firstAvailWd > 0) return false;
00250
00251
00252 short inUseWds = WdCnt(this->sz);
00253 assert(inUseWds > 0 && this->word != (Word *)NULL);
00254 for (short i = 0; i < inUseWds; i++) {
00255 if (this->word[i] != Zero) return false;
00256 }
00257
00258
00259
00260
00261 return true;
00262 }
00263
00264
00265
00266 static const short BitCnt[256] = {
00267 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
00268 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
00269 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
00270 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
00271 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
00272 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
00273 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
00274 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
00275 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
00276 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
00277 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
00278 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
00279 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
00280 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
00281 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
00282 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
00283 };
00284 static const int ByteMask = 0xff;
00285
00286 int BitVector::Cardinality() const throw ()
00287 {
00288
00289 if (this->sz == 0) return 0;
00290
00291
00292 short inUseWds = WdCnt(this->sz);
00293 int res = ((int)(this->firstAvailWd)) * BitsPerWd;
00294 for (short i = this->firstAvailWd; i < inUseWds; i++) {
00295 for (register Word wd = this->word[i]; wd != Zero; wd >>= 8) {
00296 res += (int)(BitCnt[wd & ByteMask]);
00297 }
00298 }
00299 return res;
00300 }
00301
00302 bool BitVector::Read(int i) const throw ()
00303 {
00304 if (i >= this->sz) return false;
00305 short wx = WdIndex(i);
00306 if (wx < this->firstAvailWd) return true;
00307 return ((this->word[wx] & BitMask[BitIndex(i)]) != Zero);
00308 }
00309
00310 Word BitVector::ReadWord(int start, short len) const throw ()
00311 {
00312 Word res;
00313 assert(len <= BitsPerWd);
00314 if (start >= this->sz) return Zero;
00315 short startWd = WdIndex(start);
00316 short startBit = BitIndex(start);
00317 assert(startWd < this->numWords);
00318 if (startBit + len <= BitsPerWd) {
00319
00320 Word mask = IntrvlMask[len - BitsPerWd];
00321 res = (this->word[startWd] >> startBit) & mask;
00322 } else {
00323
00324 short loLen = BitsPerWd - startBit;
00325 short hiLen = len - loLen;
00326 Word loMask = IntrvlMask[loLen - BitsPerWd];
00327 res = (this->word[startWd] >> startBit) & loMask;
00328 startWd++;
00329 if (startWd < WdCnt(this->sz)) {
00330 assert(startWd < this->numWords);
00331 Word hiMask = IntrvlMask[hiLen - BitsPerWd];
00332 int hiBits = this->word[startWd] & hiMask;
00333 res |= (hiBits << loLen);
00334 }
00335 }
00336 return res;
00337 }
00338
00339 void BitVector::WriteWord(int start, short len, Word val) throw ()
00340 {
00341 assert(len <= BitsPerWd);
00342 short startWd = WdIndex(start);
00343 short startBit = BitIndex(start);
00344 int end = (start + len) - 1;
00345 short endWd = WdIndex(end);
00346
00347
00348 ExpandSz(end, endWd);
00349 this->firstAvailWd = min(this->firstAvailWd, start);
00350
00351
00352 if (startWd == endWd) {
00353
00354 assert(startBit + len <= BitsPerWd);
00355 Word mask = IntrvlMask[len - BitsPerWd];
00356 val &= mask;
00357 mask <<= startBit;
00358 this->word[startWd] &= ~mask;
00359 this->word[startWd] |= (val << startBit);
00360 } else {
00361
00362 short loLen = BitsPerWd - startBit;
00363 short hiLen = len - loLen;
00364 Word loMask = IntrvlMask[BitsPerWd - loLen];
00365 Word hiMask = IntrvlMask[hiLen - BitsPerWd];
00366
00367
00368 this->word[startWd] &= ~loMask;
00369 this->word[startWd] |= (val << startBit);
00370
00371
00372 startWd++;
00373 assert(startWd < this->numWords);
00374 Word hiVal = (val >> loLen) & hiMask;
00375 this->word[startWd] &= ~hiMask;
00376 this->word[startWd] |= hiVal;
00377 }
00378 }
00379
00380 bool BitVector::Set(int i) throw ()
00381 {
00382 register short wx = WdIndex(i), bx = BitIndex(i);
00383 ExpandSz(i, wx);
00384 assert(wx < this->numWords);
00385 bool res = ((this->word[wx] & BitMask[bx]) != Zero);
00386 if (!res) { this->word[wx] |= BitMask[bx]; }
00387 return res;
00388 }
00389
00390 bool BitVector::Reset(int i) throw ()
00391 {
00392 register short wx = WdIndex(i), bx = BitIndex(i);
00393 bool res;
00394 if (i < this->sz) {
00395 assert(wx < this->numWords);
00396 res = ((this->word[wx] & BitMask[bx]) != Zero);
00397 if (res) {
00398 this->word[wx] &= ~(BitMask[bx]);
00399 this->firstAvailWd = min(this->firstAvailWd, wx);
00400 }
00401 } else {
00402 res = false;
00403 }
00404 return res;
00405 }
00406
00407 void BitVector::SetInterval(int lo, int hi) throw ()
00408 {
00409 short wxLo = WdIndex(lo), bxLo = BitIndex(lo);
00410 short wxHi = WdIndex(hi), bxHi = BitIndex(hi);
00411
00412
00413 ExpandSz(hi, wxHi);
00414 assert(wxHi < this->numWords);
00415
00416
00417 if (wxLo == wxHi) {
00418
00419 Word mask = IntrvlMask[(bxHi-bxLo+1) - BitsPerWd] << bxLo;
00420 this->word[wxLo] |= mask;
00421 } else {
00422
00423 register short i;
00424
00425
00426 if (wxLo < this->firstAvailWd ||
00427 (bxLo == 0 && wxLo == this->firstAvailWd)) {
00428
00429 i = this->firstAvailWd;
00430
00431
00432 this->firstAvailWd = max(this->firstAvailWd, wxHi);
00433 assert(this->firstAvailWd * BitsPerWd <= this->sz);
00434 } else {
00435
00436 this->word[wxLo] |= IntrvlMask[bxLo];
00437 i = wxLo + 1;
00438 }
00439
00440
00441 while (i < wxHi) {
00442 this->word[i++] = AllOnes;
00443 }
00444
00445
00446 if (i == wxHi) {
00447 this->word[i] |= IntrvlMask[(bxHi+1) - BitsPerWd];
00448 }
00449 }
00450 }
00451
00452 void BitVector::ResetInterval(int lo, int hi) throw ()
00453 {
00454
00455 hi = min(hi, this->sz - 1);
00456
00457 if (lo <= hi) {
00458 short wxLo = WdIndex(lo), bxLo = BitIndex(lo);
00459 short wxHi = WdIndex(hi), bxHi = BitIndex(hi);
00460
00461
00462 assert(wxHi < this->numWords);
00463 if (wxLo == wxHi) {
00464
00465 Word mask = IntrvlMask[(bxHi-bxLo+1) - BitsPerWd] << bxLo;
00466 this->word[wxLo] &= ~mask;
00467 } else {
00468
00469 register short i;
00470
00471
00472 this->word[wxLo] &= ~(IntrvlMask[bxLo]);
00473 i = wxLo + 1;
00474
00475
00476 while (i < wxHi) {
00477 this->word[i++] = Zero;
00478 }
00479
00480
00481 Word mask = IntrvlMask[(bxHi+1) - BitsPerWd];
00482 this->word[i] &= ~mask;
00483 }
00484
00485
00486 if (hi == this->sz - 1) {
00487 this->sz = min(this->sz, lo);
00488 }
00489
00490
00491 this->firstAvailWd = min(this->firstAvailWd, wxLo);
00492 }
00493 }
00494
00495 void BitVector::ResetAll(bool freeMem) throw ()
00496 {
00497 if (this->word != NULL) {
00498 if (freeMem) {
00499
00500 delete this->word;
00501 this->word = (Word *)NULL;
00502 this->numWords = 0;
00503 } else {
00504
00505 short wdCnt = WdCnt(this->sz);
00506 assert(wdCnt <= this->numWords);
00507 for (short i = 0; i < wdCnt; i++) {
00508 this->word[i] = Zero;
00509 }
00510 }
00511 }
00512 this->sz = 0;
00513
00514
00515 this->firstAvailWd = 0;
00516 }
00517
00518 const Word Magic = CONST_INT_64(0x07edd5e59a4e28c2);
00519 const int MagicTable[] = {
00520 63, 0, 58, 1, 59, 47, 53, 2, 60, 39, 48, 27, 54, 33, 42, 3, 61, 51, 37,
00521 40, 49, 18, 28, 20, 55, 30, 34, 11, 43, 14, 22, 4, 62, 57, 46, 52, 38, 26,
00522 32, 41, 50, 36, 17, 19, 29, 10, 13, 21, 56, 45, 25, 31, 35, 16, 9, 12, 44,
00523 24, 15, 8, 23, 7, 6, 5
00524 };
00525
00526 int BitVector::NextAvailExcept(BitVector *except, bool setIt) throw ()
00527 {
00528 int res;
00529 short maxWdExc;
00530 short wx = this->firstAvailWd;
00531
00532
00533 short maxWd = WdCnt(this->sz);
00534 while ((wx < maxWd) && (this->word[wx] == AllOnes)) wx++;
00535 this->firstAvailWd = wx;
00536
00537
00538 if (except != (BitVector *)NULL) {
00539
00540 wx = max(wx, except->firstAvailWd);
00541 maxWdExc = WdCnt(except->sz);
00542
00543
00544 short minWd = min(maxWd, maxWdExc);
00545 while ((wx < minWd) && ((this->word[wx] | except->word[wx])==AllOnes))
00546 wx++;
00547
00548
00549 if (wx == minWd) {
00550 if (maxWdExc > maxWd) {
00551 while ((wx < maxWdExc) && (except->word[wx] == AllOnes)) wx++;
00552 } else if (maxWd > maxWdExc) {
00553 while ((wx < maxWd) && (this->word[wx] == AllOnes)) wx++;
00554 }
00555 }
00556 }
00557
00558
00559 res = ((int)wx) * BitsPerWd;
00560 Word wd = (wx < maxWd) ? this->word[wx] : Zero;
00561 if (except != NULL && wx < maxWdExc) {
00562 wd |= except->word[wx];
00563 }
00564 assert(wd != AllOnes);
00565
00566
00567 short bx = 0;
00568 if (wd != Zero) {
00569
00570 wd = ~wd;
00571 assert(wd != Zero);
00572 #ifdef SLOW
00573 short maskSz = BitsPerWd >> 1;
00574 Word mask = IntrvlMask[-maskSz];
00575 while (maskSz > 0) {
00576 if (!(wd & mask)) {
00577 bx += maskSz; wd >>= maskSz;
00578 }
00579 maskSz >>= 1; mask >>= maskSz;
00580 }
00581 #endif
00582 wd = wd & ~(wd - 1);
00583 bx = MagicTable[(wd * Magic) >> (BitsPerWd - LogBitsPerWd)];
00584 res += (int)bx;
00585 }
00586
00587
00588 if (setIt) {
00589 ExpandSz(res, wx);
00590 this->word[wx] |= BitMask[bx];
00591 }
00592 return res;
00593 }
00594
00595 int BitVector::MSB() const throw ()
00596 {
00597
00598 short wx;
00599 short lastWd = WdCnt(this->sz) - 1; assert(lastWd < this->numWords);
00600 for (wx = lastWd; wx >= 0 && this->word[wx] == Zero; wx--) ;
00601
00602
00603 if (wx < 0) return -1;
00604
00605
00606 int res = ((int)wx) * BitsPerWd;
00607 Word w = this->word[wx]; assert(w != Zero);
00608 int maskSz = BitsPerWd >> 1;
00609 Word mask = IntrvlMask[maskSz];
00610 while (maskSz > 0) {
00611 if (w & mask) {
00612 res += maskSz;
00613 } else {
00614 w <<= maskSz;
00615 }
00616 maskSz >>= 1; mask <<= maskSz;
00617 }
00618 return res;
00619 }
00620
00621 void BitVector::Pack(const BitVector &m) throw ()
00622
00623 {
00624 short wdCnt = WdCnt(this->sz), mWdCnt = WdCnt(m.sz);
00625 assert(wdCnt <= this->numWords && mWdCnt <= m.numWords);
00626 short minWdCnt = min(wdCnt, mWdCnt);
00627
00628
00629 short wx = m.firstAvailWd;
00630
00631
00632 if (wx >= wdCnt) return;
00633
00634
00635 const Word ZeroBit = BitMask[0];
00636 int bx = 0; Word thisBit = ZeroBit;
00637 short mwx;
00638 for (mwx = wx; mwx < minWdCnt; mwx++) {
00639
00640
00641
00642
00643
00644 int mbx;
00645 Word mBit;
00646 Word mMask;
00647 for (mbx = 0, mMask = m.word[mwx], mBit = ZeroBit;
00648 mMask != Zero; mbx++, mMask >>= 1, mBit <<= 1) {
00649
00650
00651
00652
00653 if (mMask & ZeroBit) {
00654
00655 if (this->word[mwx] & mBit) {
00656
00657 this->word[wx] |= thisBit;
00658 } else {
00659
00660 this->word[wx] &= ~thisBit;
00661 }
00662
00663 bx++; thisBit <<= 1;
00664 if (thisBit == Zero) {
00665 bx = 0; thisBit = ZeroBit;
00666 wx++;
00667 }
00668 } else {
00669
00670 assert(!(this->word[mwx] & mBit));
00671 }
00672 }
00673
00674
00675 if (mwx == (minWdCnt - 1) && mbx < BitsPerWd) {
00676
00677 assert((this->word[mwx] & IntrvlMask[mbx]) == Zero);
00678 }
00679 }
00680 assert(mwx == minWdCnt && wx <= mwx);
00681
00682
00683 if (wx < mwx) {
00684 this->word[wx] &= ~(IntrvlMask[bx]);
00685 for (wx++; wx < mwx; wx++) this->word[wx] = Zero;
00686 }
00687 assert(wx == mwx);
00688
00689 #ifdef BV_DEBUG
00690
00691 for (; wx < wdCnt; wx++)
00692 assert(this->word[wx] == Zero);
00693 #endif
00694 }
00695
00696 BitVector& BitVector::operator = (const BitVector& bv) throw ()
00697 {
00698 short copyWds = WdCnt(bv.sz);
00699 short lastNonZero;
00700
00701
00702 if (copyWds > this->numWords) {
00703 Extend(copyWds, false);
00704
00705 lastNonZero = this->numWords;
00706 } else {
00707
00708
00709 lastNonZero = WdCnt(this->sz);
00710 }
00711 assert(copyWds <= this->numWords && lastNonZero <= this->numWords);
00712
00713
00714 this->sz = bv.sz;
00715 this->firstAvailWd = bv.firstAvailWd;
00716
00717
00718 short i;
00719 for (i = 0; i < copyWds; i++) { this->word[i] = bv.word[i]; }
00720 for (; i < lastNonZero; i++) { this->word[i] = Zero; }
00721
00722 #ifdef BV_DEBUG
00723
00724 for (; i < this->numWords; i++)
00725 assert(this->word[i] == Zero);
00726 #endif
00727
00728 return *this;
00729 }
00730
00731
00732
00733 bool operator == (const BitVector& bv1, const BitVector& bv2) throw ()
00734 {
00735 if (bv1.sz == 0) {
00736 return bv2.IsEmpty();
00737 } else if (bv2.sz == 0) {
00738 return bv1.IsEmpty();
00739 }
00740 assert((bv1.word != (Word *)NULL) && (bv2.word != (Word *)NULL));
00741 short wds1 = WdCnt(bv1.sz), wds2 = WdCnt(bv2.sz);
00742 short minWds = min(wds1, wds2);
00743 short firstWd = min(bv1.firstAvailWd, bv2.firstAvailWd);
00744
00745
00746 short i;
00747 for (i = firstWd; i < minWds; i++) {
00748 if (bv1.word[i] != bv2.word[i]) return false;
00749 }
00750
00751
00752 if (wds1 > wds2) {
00753 for (; i < wds1; i++) {
00754 if (bv1.word[i] != Zero) return false;
00755 }
00756 } else if (wds2 > wds1) {
00757 for (; i < wds2; i++) {
00758 if (bv2.word[i] != Zero) return false;
00759 }
00760 }
00761 return true;
00762 }
00763
00764 bool operator <= (const BitVector& bv1, const BitVector& bv2) throw ()
00765
00766
00767
00768
00769
00770 {
00771
00772 if (bv1.sz == 0) return true;
00773 assert(bv1.word != (Word *)NULL);
00774
00775 short wds1 = WdCnt(bv1.sz), wds2 = WdCnt(bv2.sz);
00776 short minWds = min(wds1, wds2);
00777
00778
00779
00780
00781
00782 short i;
00783 for (i = bv2.firstAvailWd; i < minWds; i++) {
00784 if (bv1.word[i] & ~(bv2.word[i])) return false;
00785 }
00786
00787
00788 for (; i < wds1; i++) {
00789 if (bv1.word[i] != Zero) return false;
00790 }
00791
00792
00793 return true;
00794 }
00795
00796 bool operator < (const BitVector& bv1, const BitVector& bv2) throw ()
00797 {
00798
00799 if (bv2.IsEmpty()) return false;
00800 if (bv1.IsEmpty()) return true;
00801 assert((bv1.word != (Word *)NULL) && (bv2.word != (Word *)NULL));
00802
00803
00804
00805
00806
00807 short i;
00808 for (i = bv1.firstAvailWd; i < bv2.firstAvailWd; i++) {
00809 if (bv1.word[i] != AllOnes) return true;
00810 }
00811
00812
00813 short wds1 = WdCnt(bv1.sz), wds2 = WdCnt(bv2.sz);
00814 short minWds = min(wds1, wds2);
00815 for (; i < minWds; i++) {
00816 if (bv1.word[i] & ~(bv2.word[i])) return false;
00817
00818 if (bv1.word[i] != bv2.word[i]) return true;
00819 }
00820
00821
00822 for (; i < wds2; i++) {
00823 if (bv2.word[i] != Zero) return true;
00824 }
00825 return false;
00826 }
00827
00828 BitVector* operator & (const BitVector& bv1, const BitVector& bv2) throw ()
00829 {
00830 int newSz = min(bv1.sz, bv2.sz);
00831 BitVector *res = NEW_CONSTR(BitVector, (newSz, false));
00832
00833
00834 res->sz = newSz;
00835 res->firstAvailWd = min(bv1.firstAvailWd, bv2.firstAvailWd);
00836 assert(res->firstAvailWd * BitsPerWd <= res->sz);
00837
00838 short i, wdCnt1 = WdCnt(bv1.sz), wdCnt2 = WdCnt(bv2.sz);
00839 if (newSz > 0) {
00840
00841 assert(res->firstAvailWd <= res->numWords);
00842 for (i = 0; i < res->firstAvailWd; i++) {
00843 res->word[i] = AllOnes;
00844 }
00845
00846
00847 short minWds = min(wdCnt1, wdCnt2);
00848 assert(minWds <= res->numWords);
00849 for (; i < minWds; i++) {
00850 res->word[i] = bv1.word[i] & bv2.word[i];
00851 }
00852 } else {
00853 assert(res->firstAvailWd == 0);
00854 i = 0;
00855 }
00856
00857
00858 for (; i < res->numWords; i++) {
00859 res->word[i] = Zero;
00860 }
00861
00862
00863 res->ReduceSz();
00864 return res;
00865 }
00866
00867 BitVector& BitVector::operator &= (const BitVector& bv) throw ()
00868 {
00869 short wdCnt = WdCnt(this->sz);
00870 if (wdCnt > 0) {
00871
00872 short wdCnt2 = WdCnt(bv.sz);
00873 this->sz = min(this->sz, bv.sz);
00874 this->firstAvailWd = min(this->firstAvailWd, bv.firstAvailWd);
00875
00876
00877 short i, minWds = min(wdCnt, wdCnt2);
00878 for (i = this->firstAvailWd; i < minWds; i++) {
00879 this->word[i] &= bv.word[i];
00880 }
00881
00882
00883 for (; i < wdCnt; i++) {
00884 this->word[i] = Zero;
00885 }
00886 ReduceSz();
00887 }
00888 return *this;
00889 }
00890
00891 BitVector* operator | (const BitVector& bv1, const BitVector& bv2) throw ()
00892 {
00893 int newSz = max(bv1.sz, bv2.sz);
00894 BitVector *res = NEW_CONSTR(BitVector, (newSz, false));
00895
00896
00897 res->sz = newSz;
00898 res->firstAvailWd = max(bv1.firstAvailWd, bv2.firstAvailWd);
00899 assert(res->firstAvailWd * BitsPerWd <= res->sz);
00900
00901 short i, wdCnt1 = WdCnt(bv1.sz), wdCnt2 = WdCnt(bv2.sz);
00902 if (newSz > 0) {
00903
00904 assert(res->firstAvailWd <= res->numWords);
00905 for (i = 0; i < res->firstAvailWd; i++) {
00906 res->word[i] = AllOnes;
00907 }
00908
00909
00910 short minWds = min(wdCnt1, wdCnt2);
00911 assert(minWds <= res->numWords);
00912 for (; i < minWds; i++) {
00913 res->word[i] = bv1.word[i] | bv2.word[i];
00914 }
00915
00916
00917 short maxWds = max(wdCnt1, wdCnt2);
00918 assert(maxWds <= res->numWords);
00919 Word *wds = (wdCnt1 > wdCnt2) ? bv1.word : bv2.word;
00920 for (; i < maxWds; i++) {
00921 res->word[i] = wds[i];
00922 }
00923 } else {
00924 assert(res->firstAvailWd == 0);
00925 i = 0;
00926 }
00927
00928
00929 for (; i < res->numWords; i++) {
00930 res->word[i] = Zero;
00931 }
00932 return res;
00933 }
00934
00935 BitVector& BitVector::operator |= (const BitVector& bv) throw ()
00936 {
00937 short wdCnt2 = WdCnt(bv.sz);
00938 if (wdCnt2 > 0) {
00939
00940 if (wdCnt2 > this->numWords) Extend(wdCnt2);
00941 assert(wdCnt2 <= this->numWords);
00942
00943
00944 this->sz = max(this->sz, bv.sz);
00945 short i = this->firstAvailWd;
00946 this->firstAvailWd = max(this->firstAvailWd, bv.firstAvailWd);
00947
00948
00949 for (; i < this->firstAvailWd; i++) {
00950 this->word[i] = AllOnes;
00951 }
00952
00953
00954 short wdCnt = WdCnt(this->sz);
00955 short minWds = min(wdCnt, wdCnt2);
00956 for (; i < minWds; i++) {
00957 this->word[i] |= bv.word[i];
00958 }
00959
00960
00961 for (; i < wdCnt2; i++) {
00962 this->word[i] = bv.word[i];
00963 }
00964 }
00965 return *this;
00966 }
00967
00968 BitVector* operator ^ (const BitVector& bv1, const BitVector& bv2) throw ()
00969 {
00970 int newSz = max(bv1.sz, bv2.sz);
00971 BitVector *res = NEW_CONSTR(BitVector, (newSz, false));
00972
00973
00974 res->sz = newSz;
00975 res->firstAvailWd = 0;
00976
00977 short i;
00978 if (newSz > 0) {
00979
00980 short wdCnt1 = WdCnt(bv1.sz), wdCnt2 = WdCnt(bv2.sz);
00981 short minWds = min(wdCnt1, wdCnt2);
00982 for (i = 0; i < minWds; i++) {
00983 res->word[i] = bv1.word[i] ^ bv2.word[i];
00984 }
00985
00986
00987 if (wdCnt1 > wdCnt2) {
00988 assert(wdCnt1 <= res->numWords);
00989 for (; i < wdCnt1; i++) {
00990 res->word[i] = bv1.word[i];
00991 }
00992 } else if (wdCnt2 > wdCnt1) {
00993 assert(wdCnt2 <= res->numWords);
00994 for (; i < wdCnt2; i++) {
00995 res->word[i] = bv2.word[i];
00996 }
00997 }
00998 } else {
00999 i = 0;
01000 }
01001
01002
01003 for (; i < res->numWords; i++) {
01004 res->word[i] = Zero;
01005 }
01006 return res;
01007 }
01008
01009 BitVector& BitVector::operator ^= (const BitVector& bv) throw ()
01010 {
01011 short wdCnt2 = WdCnt(bv.sz);
01012 if (wdCnt2 > 0) {
01013
01014 if (wdCnt2 > this->numWords) Extend(wdCnt2);
01015 assert(wdCnt2 <= this->numWords);
01016
01017
01018 this->sz = max(this->sz, bv.sz);
01019 this->firstAvailWd = 0;
01020
01021
01022 short i, wdCnt = WdCnt(this->sz);
01023 short minWds = min(wdCnt, wdCnt2);
01024 for (i = 0; i < minWds; i++) {
01025 this->word[i] ^= bv.word[i];
01026 }
01027
01028
01029 for (; i < wdCnt2; i++) {
01030 this->word[i] = bv.word[i];
01031 }
01032 }
01033 return *this;
01034 }
01035
01036 BitVector* operator - (const BitVector& bv1, const BitVector& bv2) throw ()
01037 {
01038 int newSz = bv1.sz;
01039 BitVector *res = NEW_CONSTR(BitVector, (newSz, false));
01040
01041
01042 res->sz = newSz;
01043 res->firstAvailWd = 0;
01044
01045
01046 short i, wdCnt2 = WdCnt(bv2.sz);
01047 if (newSz > 0) {
01048 short wdCnt1 = WdCnt(bv1.sz);
01049 short minWds = min(wdCnt1, wdCnt2);
01050 assert(wdCnt1 <= res->numWords);
01051 for (i = 0; i < minWds; i++) {
01052 res->word[i] = bv1.word[i] & ~(bv2.word[i]);
01053 }
01054
01055
01056 for (; i < wdCnt1; i++) {
01057 res->word[i] = bv1.word[i];
01058 }
01059 } else {
01060 i = 0;
01061 }
01062
01063
01064 for (; i < res->numWords; i++) {
01065 res->word[i] = Zero;
01066 }
01067
01068
01069 res->ReduceSz();
01070 return res;
01071 }
01072
01073 BitVector& BitVector::operator -= (const BitVector& bv) throw ()
01074 {
01075 short wdCnt2 = WdCnt(bv.sz);
01076 if (this->sz > 0 && wdCnt2 > 0) {
01077
01078 short wdCnt = WdCnt(this->sz);
01079
01080 this->firstAvailWd = 0;
01081
01082
01083 short minWds = min(wdCnt, wdCnt2);
01084 for (short i = 0; i < minWds; i++) {
01085 this->word[i] &= ~(bv.word[i]);
01086 }
01087
01088
01089 this->ReduceSz();
01090 }
01091 return *this;
01092 }
01093
01094
01095
01096 void BitVector::Log(VestaLog &log) const throw (VestaLog::Error)
01097 {
01098
01099 short numUsedWords = WdCnt(this->sz);
01100 log.write((char *)(&numUsedWords), sizeof(numUsedWords));
01101 if (numUsedWords > 0) {
01102 log.write((char *)(&(this->firstAvailWd)), sizeof(this->firstAvailWd));
01103 log.write((char *)(&(this->sz)), sizeof(this->sz));
01104 log.write((char *)(this->word), numUsedWords * BytesPerWd);
01105 }
01106 }
01107
01108 void BitVector::Recover(RecoveryReader &rd)
01109 throw (VestaLog::Error, VestaLog::Eof)
01110 {
01111 rd.readAll((char *)(&(this->numWords)), sizeof(this->numWords));
01112 if (this->numWords > 0) {
01113 rd.readAll((char *)(&(this->firstAvailWd)),sizeof(this->firstAvailWd));
01114 rd.readAll((char *)(&(this->sz)), sizeof(this->sz));
01115 this->word = NEW_PTRFREE_ARRAY(Word, this->numWords);
01116 rd.readAll((char *)(this->word), this->numWords * BytesPerWd);
01117 } else {
01118 this->firstAvailWd = 0;
01119 this->sz = 0;
01120 this->word = (Word *)NULL;
01121 }
01122 }
01123
01124 void BitVector::Write(std::ostream &ofs) const throw (FS::Failure)
01125 {
01126
01127 short numUsedWords = WdCnt(this->sz);
01128 FS::Write(ofs, (char *)(&numUsedWords), sizeof(numUsedWords));
01129 if (numUsedWords > 0) {
01130 FS::Write(ofs, (char *)(&(this->firstAvailWd)),
01131 sizeof(this->firstAvailWd));
01132 FS::Write(ofs, (char *)(&(this->sz)), sizeof(this->sz));
01133 FS::Write(ofs, (char *)(this->word), numUsedWords * BytesPerWd);
01134 }
01135 }
01136
01137 void BitVector::Read(std::istream &ifs) throw (FS::EndOfFile, FS::Failure)
01138 {
01139 FS::Read(ifs, (char *)(&(this->numWords)), sizeof(this->numWords));
01140 if (this->numWords > 0) {
01141 FS::Read(ifs, (char *)(&(this->firstAvailWd)),
01142 sizeof(this->firstAvailWd));
01143 FS::Read(ifs, (char *)(&(this->sz)), sizeof(this->sz));
01144 this->word = NEW_PTRFREE_ARRAY(Word, this->numWords);
01145 FS::Read(ifs, (char *)(this->word), this->numWords * BytesPerWd);
01146 } else {
01147 this->firstAvailWd = 0;
01148 this->sz = 0;
01149 this->word = (Word *)NULL;
01150 }
01151 }
01152
01153 void BitVector::Send(SRPC &srpc) const throw (SRPC::failure)
01154 {
01155
01156 short numUsedWords = WdCnt(this->sz);
01157 srpc.send_short(numUsedWords);
01158 if (numUsedWords > 0) {
01159 srpc.send_short(this->firstAvailWd);
01160 srpc.send_int(this->sz);
01161 srpc.send_int64_array((const Basics::int64 *) this->word,
01162 numUsedWords);
01163 }
01164 }
01165
01166 void BitVector::Recv(SRPC &srpc) throw (SRPC::failure)
01167 {
01168 this->numWords = srpc.recv_short();
01169 if (this->numWords > 0) {
01170 this->firstAvailWd = srpc.recv_short();
01171 this->sz = srpc.recv_int();
01172 int len;
01173 this->word = (Word *) srpc.recv_int64_array(len);
01174 assert(this->numWords == len);
01175 } else {
01176 this->firstAvailWd = 0;
01177 this->sz = 0;
01178 this->word = (Word *)NULL;
01179 }
01180 }
01181
01182 void BitVector::Print(std::ostream &os, int maxWidth) const throw ()
01183
01184 {
01185 assert(maxWidth >= 30);
01186
01187
01188 maxWidth -= 16;
01189
01190 short maxWd = WdCnt(this->sz);
01191 int widthWd = maxWidth / (2 * BytesPerWd);
01192 bool elided = (widthWd < maxWd);
01193 if (elided) {
01194
01195
01196 maxWidth -= 3;
01197 widthWd = maxWidth / (2 * BytesPerWd);
01198 maxWd = min(maxWd, widthWd);
01199 }
01200 if (maxWd == 0) { os << "<<Empty>>"; return; }
01201 for (short i = 0; i < maxWd; i++) {
01202 Word w = this->word[i];
01203 for (int j = 0; j < BytesPerWd; j++) {
01204 char buff[3];
01205 int printLen = sprintf(buff, "%02x", (unsigned int)(w & 0xff));
01206 assert(printLen == 2);
01207 os << buff;
01208 w >>= 8;
01209 }
01210 }
01211 if (elided) os << "...";
01212 os << " (" << this->Cardinality() << " total)";
01213 }
01214
01215 inline void Indent(std::ostream &os, int indent) throw ()
01216 {
01217 for (int i = 0; i < indent; i++) os << ' ';
01218 }
01219
01220 void ExtendRow(std::ostream &os, int indent, int maxWidth,
01221 const char *s, int &col) throw ()
01222 {
01223 int s_len = strlen(s);
01224 if (col + s_len > maxWidth) {
01225 os << endl;
01226 Indent(os, indent);
01227 col = indent;
01228 }
01229 os << s << ' ';
01230 col += (s_len + 1);
01231 }
01232
01233 void BitVector::PrintAll(std::ostream &os, int indent, int maxWidth) const throw ()
01234 {
01235 int lo = -2, prev = -2, curr, col = indent;
01236 BVIter iter(*this);
01237 Indent(os, indent);
01238 while (iter.Next( curr)) {
01239
01240 if (curr > prev + 1) {
01241
01242 if (lo >= 0) {
01243 OBufStream s;
01244 s << lo;
01245 if (prev > lo) s << '-' << prev;
01246 s << ',';
01247 ExtendRow(os, indent, maxWidth, s.str(), col);
01248 }
01249
01250 lo = curr;
01251 }
01252 prev = curr;
01253 }
01254
01255 if (prev < 0) {
01256 os << "<<Empty>>";
01257 } else {
01258
01259 OBufStream s;
01260 s << lo;
01261 if (prev > lo) s << '-' << prev;
01262 ExtendRow(os, indent, maxWidth, s.str(), col);
01263 }
01264 os << endl;
01265 }
01266
01267
01268
01269 bool BVIter::Next( int& res) throw ()
01270 {
01271 while (this->bitIndex < this->bv->sz) {
01272 Word wd = this->bv->word[this->wordIndex];
01273 if (wd == Zero) {
01274 this->bitIndex += BitsPerWd;
01275 } else {
01276 while (this->mask != Zero) {
01277 if (this->mask & wd) {
01278 this->mask <<= 1;
01279 res = this->bitIndex++;
01280 return true;
01281 }
01282 this->bitIndex++;
01283 this->mask <<= 1;
01284 }
01285 }
01286 this->wordIndex++;
01287 this->mask = One;
01288 }
01289 return false;
01290 }