diff --git a/src/storage/BitVector.h b/src/storage/BitVector.h index 87e2b8fac..c50f10a29 100644 --- a/src/storage/BitVector.h +++ b/src/storage/BitVector.h @@ -97,14 +97,13 @@ public: * @param length The number of bits the bit vector should be able to hold. * @param initTrue The initial value of the first |length| bits. */ - BitVector(uint_fast64_t length, bool initTrue = false) : endIterator(*this, length, length, false) { + BitVector(uint_fast64_t length, bool initTrue = false) : bitCount(length), endIterator(*this, length, length, false), truncateMask((1ll << (bitCount & mod64mask)) - 1ll) { // Check whether the given length is valid. if (length == 0) { LOG4CPLUS_ERROR(logger, "Trying to create bit vector of size 0."); throw mrmc::exceptions::invalid_argument("Trying to create a bit vector of size 0."); } - bitCount = length; // Compute the correct number of buckets needed to store the given number of bits bucketCount = length >> 6; if ((length & mod64mask) != 0) { @@ -132,7 +131,7 @@ public: * Copy Constructor. Performs a deep copy of the given bit vector. * @param bv A reference to the bit vector to be copied. */ - BitVector(const BitVector &bv) : bucketCount(bv.bucketCount), bitCount(bv.bitCount), endIterator(*this, bitCount, bitCount, false) { + BitVector(const BitVector &bv) : bucketCount(bv.bucketCount), bitCount(bv.bitCount), endIterator(*this, bitCount, bitCount, false), truncateMask((1ll << (bitCount & mod64mask)) - 1ll) { LOG4CPLUS_WARN(logger, "Invoking copy constructor."); bucketArray = new uint64_t[bucketCount]; std::copy(bv.bucketArray, bv.bucketArray + bucketCount, bucketArray); @@ -161,9 +160,9 @@ public: } bucketCount = bv.bucketCount; bitCount = bv.bitCount; - this->bucketArray = new uint64_t[bucketCount]; - std::copy(bv.bucketArray, bv.bucketArray + bucketCount, this->bucketArray); - updateEndIterator(); + bucketArray = new uint64_t[bucketCount]; + std::copy(bv.bucketArray, bv.bucketArray + bucketCount, bucketArray); + updateSizeChange(); return *this; } @@ -190,7 +189,7 @@ public: tempArray[i] = 0; } - updateEndIterator(); + updateSizeChange(); // Dispose of the old bit vector and set the new one. delete[] this->bucketArray; @@ -244,7 +243,6 @@ public: result.bucketArray[i] = this->bucketArray[i] & bv.bucketArray[i]; } - result.truncateLastBucket(); return result; } @@ -263,7 +261,6 @@ public: this->bucketArray[i] &= bv.bucketArray[i]; } - truncateLastBucket(); return *this; } @@ -507,17 +504,17 @@ private: */ void truncateLastBucket() { if ((bitCount & mod64mask) != 0) { - uint64_t mask = ((1ll << (bitCount & mod64mask)) - 1ll); - bucketArray[bucketCount - 1] = bucketArray[bucketCount - 1] & mask; + bucketArray[bucketCount - 1] = bucketArray[bucketCount - 1] & truncateMask; } } /*! - * Updates the end iterator to the correct past-the-end position. Needs - * to be called whenever the size of the bit vector changed. + * Updates internal structures in case the size of the bit vector changed. Needs to be called + * after the size of the bit vector changed. */ - void updateEndIterator() { + void updateSizeChange() { endIterator.currentIndex = bitCount; + truncateMask = (1ll << (bitCount & mod64mask)) - 1ll; } /*! The number of 64-bit buckets we use as internal storage. */ @@ -534,6 +531,8 @@ private: /*! A bit mask that can be used to reduce a modulo operation to a logical "and". */ static const uint_fast64_t mod64mask = (1 << 6) - 1; + + uint64_t truncateMask; }; } // namespace storage