| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359 |
- //-------------------------------------------------------------------------------------------------------
- // Copyright (C) Microsoft. All rights reserved.
- // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
- //-------------------------------------------------------------------------------------------------------
- #include "CommonDataStructuresPch.h"
- BVFixed::BVFixed(BVFixed * initBv) :
- len(initBv->Length())
- {
- this->Copy(initBv);
- }
- BVFixed::BVFixed(BVIndex length, bool initialSet) :
- len(length)
- {
- Assert(length != 0);
- if (initialSet)
- {
- this->SetAll();
- }
- else
- {
- this->ClearAll();
- }
- }
- size_t
- BVFixed::GetAllocSize(BVIndex length)
- {
- Assert(length != 0);
- return sizeof(BVFixed) + sizeof(BVUnit) * BVFixed::WordCount(length);
- }
- void
- BVFixed::Init(BVIndex length)
- {
- Assert(length != 0);
- len = length;
- }
- BVIndex
- BVFixed::WordCount(BVIndex length)
- {
- Assert(length != 0);
- return ((length - 1) >> BVUnit::ShiftValue) + 1;
- }
- BVIndex
- BVFixed::WordCount() const
- {
- return WordCount(Length());
- }
- const BVUnit *
- BVFixed::BitsFromIndex(BVIndex i) const
- {
- AssertRange(i);
- return &this->data[BVUnit::Position(i)];
- }
- BVUnit *
- BVFixed::BitsFromIndex(BVIndex i)
- {
- AssertRange(i);
- return &this->data[BVUnit::Position(i)];
- }
- const BVUnit *
- BVFixed::BeginUnit() const
- {
- return &this->data[0];
- }
- const BVUnit *
- BVFixed::EndUnit() const
- {
- return &this->data[WordCount()];
- }
- BVUnit *
- BVFixed::BeginUnit()
- {
- return &this->data[0];
- }
- BVUnit *
- BVFixed::EndUnit()
- {
- return &this->data[WordCount()];
- }
- BVIndex
- BVFixed::GetNextBit(BVIndex i) const
- {
- AssertRange(i);
- const BVUnit * chunk = BitsFromIndex(i);
- BVIndex base = BVUnit::Floor(i);
- BVIndex offset = chunk->GetNextBit(BVUnit::Offset(i));
- if(-1 != offset)
- {
- return base + offset;
- }
- while(++chunk != this->EndUnit())
- {
- base += BVUnit::BitsPerWord;
- offset = chunk->GetNextBit();
- if(-1 != offset)
- {
- return base + offset;
- }
- }
- return BVInvalidIndex;
- }
- void
- BVFixed::AssertRange(BVIndex i) const
- {
- AssertMsg(i < this->Length(), "index out of bound");
- }
- void
- BVFixed::AssertBV(const BVFixed *bv) const
- {
- AssertMsg(NULL != bv, "Cannot operate on NULL bitvector");
- }
- BVIndex
- BVFixed::Length() const
- {
- return this->len;
- }
- void
- BVFixed::SetAll()
- {
- memset(&this->data[0], -1, WordCount() * sizeof(BVUnit));
- ClearEnd();
- }
- void
- BVFixed::ClearAll()
- {
- ZeroMemory(&this->data[0], WordCount() * sizeof(BVUnit));
- }
- BOOLEAN
- BVFixed::TestAndSet(BVIndex i)
- {
- AssertRange(i);
- BVUnit * bvUnit = this->BitsFromIndex(i);
- BVIndex offset = BVUnit::Offset(i);
- BOOLEAN bit = bvUnit->Test(offset);
- bvUnit->Set(offset);
- return bit;
- }
- BOOLEAN
- BVFixed::TestAndClear(BVIndex i)
- {
- AssertRange(i);
- BVUnit * bvUnit = this->BitsFromIndex(i);
- BVIndex offset = BVUnit::Offset(i);
- BOOLEAN bit = bvUnit->Test(offset);
- bvUnit->Clear(offset);
- return bit;
- }
- BOOLEAN
- BVFixed::operator[](BVIndex i) const
- {
- AssertRange(i);
- return this->Test(i);
- }
- void
- BVFixed::Or(const BVFixed*bv)
- {
- AssertBV(bv);
- this->for_each(bv, &BVUnit::Or);
- }
- //
- // Xors the two bit vectors and returns the count of bits which are different.
- //
- uint
- BVFixed::DiffCount(const BVFixed*bv) const
- {
- const BVUnit *i, *j;
- uint count = 0;
- for(i = this->BeginUnit(), j = bv->BeginUnit();
- i != this->EndUnit() && j != bv->EndUnit();
- i++, j++)
- {
- count += i->DiffCount(*j);
- }
- // Assumes that the default value of is 0
- while(i != this->EndUnit())
- {
- count += i->Count();
- i++;
- }
- while(j != bv->EndUnit())
- {
- count += j->Count();
- j++;
- }
- return count;
- }
- void
- BVFixed::OrComplimented(const BVFixed*bv)
- {
- AssertBV(bv);
- this->for_each(bv, &BVUnit::OrComplimented);
- ClearEnd();
- }
- void
- BVFixed::And(const BVFixed*bv)
- {
- AssertBV(bv);
- this->for_each(bv, &BVUnit::And);
- }
- void
- BVFixed::Minus(const BVFixed*bv)
- {
- AssertBV(bv);
- this->for_each(bv, &BVUnit::Minus);
- }
- void
- BVFixed::Copy(const BVFixed*bv)
- {
- AssertBV(bv);
- Assert(len >= bv->len);
- #if 1
- js_memcpy_s(&this->data[0], WordCount() * sizeof(BVUnit), &bv->data[0], bv->WordCount() * sizeof(BVUnit));
- #else
- this->for_each(bv, &BVUnit::Copy);
- #endif
- }
- void
- BVFixed::CopyBits(const BVFixed * bv, BVIndex i)
- {
- AssertBV(bv);
- BVIndex offset = BVUnit::Offset(i);
- BVIndex position = BVUnit::Position(i);
- BVIndex len = bv->WordCount() - position;
- BVIndex copylen = min(WordCount(), len);
- if (offset == 0)
- {
- js_memcpy_s(&this->data[0], copylen * sizeof(BVUnit), &bv->data[BVUnit::Position(i)], copylen * sizeof(BVUnit));
- }
- else
- {
- BVIndex pos = position;
- for (BVIndex j = 0; j < copylen; j++)
- {
- Assert(pos < bv->WordCount());
- this->data[j] = bv->data[pos];
- this->data[j].ShiftRight(offset);
- pos++;
- if (pos >= bv->WordCount())
- {
- break;
- }
- BVUnit temp = bv->data[pos];
- temp.ShiftLeft(BVUnit::BitsPerWord - offset);
- this->data[j].Or(temp);
- }
- }
- #if DBG
- for (BVIndex curr = i; curr < i + this->Length(); curr++)
- {
- Assert(this->Test(curr - i) == bv->Test(curr));
- }
- #endif
- }
- void
- BVFixed::ComplimentAll()
- {
- for(BVIndex i=0; i < this->WordCount(); i++)
- {
- this->data[i].ComplimentAll();
- }
- ClearEnd();
- }
- void
- BVFixed::ClearEnd()
- {
- uint offset = BVUnit::Offset(this->Length());
- if (offset != 0)
- {
- Assert((((uint64)1 << BVUnit::Offset(this->Length())) - 1) == BVUnit::GetTopBitsClear(this->Length()));
- this->data[this->WordCount() - 1].And(BVUnit::GetTopBitsClear(this->Length()));
- }
- }
- BVIndex
- BVFixed::Count() const
- {
- BVIndex sum = 0;
- for (BVIndex i=0; i < this->WordCount(); i++)
- {
- sum += this->data[i].Count();
- }
- Assert(sum <= this->Length());
- return sum;
- }
- JsUtil::FBVEnumerator
- BVFixed::BeginSetBits()
- {
- return JsUtil::FBVEnumerator(this->BeginUnit(), this->EndUnit());
- }
- bool BVFixed::IsAllClear() const
- {
- bool isClear = true;
- for (BVIndex i=0; i < this->WordCount(); i++)
- {
- isClear = this->data[i].IsEmpty() && isClear;
- if(!isClear)
- {
- break;
- }
- }
- return isClear;
- }
- #if DBG_DUMP
- void
- BVFixed::Dump() const
- {
- bool hasBits = false;
- Output::Print(_u("[ "));
- for(BVIndex i=0; i < this->WordCount(); i++)
- {
- hasBits = this->data[i].Dump(i * BVUnit::BitsPerWord, hasBits);
- }
- Output::Print(_u("]\n"));
- }
- #endif
|