6#include <boost/functional/hash.hpp>
22 : dataPtr(dataPtr), endIndex(endIndex) {
25 currentIndex = getNextIndexWithValue<true>(dataPtr, startIndex, endIndex);
27 currentIndex = startIndex;
38 dataPtr = other.dataPtr;
39 currentIndex = other.currentIndex;
40 endIndex = other.endIndex;
46 currentIndex = getNextIndexWithValue<true>(dataPtr, ++currentIndex, endIndex);
57 for (
size_t i = 0;
i < n; ++
i) {
58 currentIndex = getNextIndexWithValue<true>(dataPtr, ++currentIndex, endIndex);
68 return currentIndex != other.currentIndex;
72 return currentIndex == other.currentIndex;
78 : dataPtr(dataPtr), lowerBound(lowerBound) {
81 currentIndex = getNextIndexWithValue<true, true>(dataPtr, lowerBound, upperBound);
83 currentIndex = upperBound;
88 : dataPtr(other.dataPtr), currentIndex(other.currentIndex), lowerBound(other.lowerBound) {
95 dataPtr = other.dataPtr;
96 currentIndex = other.currentIndex;
97 lowerBound = other.lowerBound;
103 currentIndex = getNextIndexWithValue<true, true>(dataPtr, lowerBound, --currentIndex);
113 for (
size_t i = 0;
i < n; ++
i) {
114 currentIndex = getNextIndexWithValue<true, true>(dataPtr, lowerBound, --currentIndex);
120 return currentIndex - 1;
124 return currentIndex != other.currentIndex;
128 return currentIndex == other.currentIndex;
138 if ((length & mod64mask) != 0) {
146 truncateLastBucket();
156template<
typename InputIterator>
165BitVector::BitVector(uint64_t bucketCount, uint64_t bitCount) : bitCount(bitCount), buckets(nullptr) {
172 std::copy_n(other.buckets, other.
bucketCount(), buckets);
177 if (
this != &other) {
182 bitCount = other.bitCount;
186 std::copy_n(other.buckets, other.
bucketCount(), buckets);
194 }
else if (this->
size() > other.
size()) {
198 uint64_t* first1 = this->buckets;
199 uint64_t* last1 = this->buckets + this->
bucketCount();
200 uint64_t* first2 = other.buckets;
202 for (; first1 != last1; ++first1, ++first2) {
203 if (*first1 < *first2) {
205 }
else if (*first1 > *first2) {
214 other.buckets =
nullptr;
219 if (
this != &other) {
220 bitCount = other.bitCount;
222 delete[] this->buckets;
223 this->buckets = other.buckets;
224 other.buckets =
nullptr;
232 if (this->bitCount != other.bitCount) {
237 return std::equal(this->buckets, this->buckets + this->
bucketCount(), other.buckets);
241 return !(*
this == other);
245 STORM_LOG_ASSERT(index < bitCount,
"Invalid call to BitVector::set: written index " << index <<
" out of bounds.");
246 uint64_t bucket = index >> 6;
248 uint64_t mask = 1ull << (63 - (index & mod64mask));
250 buckets[bucket] |= mask;
252 buckets[bucket] &= ~mask;
256template<
typename InputIterator>
258 for (InputIterator it =
begin; it !=
end; ++it) {
259 this->
set(*it, value);
264 uint64_t bucket = index >> 6;
265 uint64_t mask = 1ull << (63 - (index & mod64mask));
266 return (this->buckets[bucket] & mask) == mask;
270 STORM_LOG_ASSERT(index < bitCount,
"Invalid call to BitVector::get: read index " << index <<
" out of bounds.");
271 return (*
this)[index];
275 if (newLength > bitCount) {
276 uint64_t newBucketCount = newLength >> 6;
277 if ((newLength & mod64mask) != 0) {
282 uint64_t* newBuckets =
new uint64_t[newBucketCount];
283 std::copy_n(buckets, this->
bucketCount(), newBuckets);
286 newBuckets[this->
bucketCount() - 1] |= ((1ull << (64 - (bitCount & mod64mask))) - 1ull);
293 buckets = newBuckets;
294 bitCount = newLength;
298 buckets[this->
bucketCount() - 1] |= ((1ull << (64 - (bitCount & mod64mask))) - 1ull);
300 bitCount = newLength;
302 truncateLastBucket();
304 uint64_t newBucketCount = newLength >> 6;
305 if ((newLength & mod64mask) != 0) {
312 uint64_t* newBuckets =
new uint64_t[newBucketCount];
313 std::copy_n(buckets, newBucketCount, newBuckets);
315 buckets = newBuckets;
316 bitCount = newLength;
318 bitCount = newLength;
319 truncateLastBucket();
324 STORM_LOG_ASSERT(
size() % 64 == 0,
"We expect the length of the left bitvector to be a multiple of 64.");
341 if (minimumLength > bitCount) {
343 uint64_t newLength = std::max(
static_cast<uint64_t
>(64), bitCount);
345 while (newLength < minimumLength) {
346 newLength = newLength << 1;
353 STORM_LOG_ASSERT(bitCount == other.bitCount,
"Length of the bit vectors does not match.");
355 std::transform(this->buckets, this->buckets + this->
bucketCount(), other.buckets, result.buckets,
356 [](uint64_t
const& a, uint64_t
const& b) { return a & b; });
361 STORM_LOG_ASSERT(bitCount == other.bitCount,
"Length of the bit vectors does not match.");
362 std::transform(this->buckets, this->buckets + this->
bucketCount(), other.buckets, this->buckets,
363 [](uint64_t
const& a, uint64_t
const& b) { return a & b; });
368 STORM_LOG_ASSERT(bitCount == other.bitCount,
"Length of the bit vectors does not match.");
370 std::transform(this->buckets, this->buckets + this->
bucketCount(), other.buckets, result.buckets,
371 [](uint64_t
const& a, uint64_t
const& b) { return a | b; });
376 STORM_LOG_ASSERT(bitCount == other.bitCount,
"Length of the bit vectors does not match.");
377 std::transform(this->buckets, this->buckets + this->
bucketCount(), other.buckets, this->buckets,
378 [](uint64_t
const& a, uint64_t
const& b) { return a | b; });
383 STORM_LOG_ASSERT(bitCount == other.bitCount,
"Length of the bit vectors does not match.");
385 std::transform(this->buckets, this->buckets + this->
bucketCount(), other.buckets, result.buckets,
386 [](uint64_t
const& a, uint64_t
const& b) { return a ^ b; });
387 result.truncateLastBucket();
392 STORM_LOG_ASSERT(bitCount == filter.bitCount,
"Length of the bit vectors does not match.");
399 uint64_t position = 0;
400 for (uint64_t bit : filter) {
402 result.
set(position);
409 for (uint64_t bit : (*
this)) {
421 std::transform(this->buckets, this->buckets + this->
bucketCount(), result.buckets, [](uint64_t
const& a) { return ~a; });
422 result.truncateLastBucket();
427 std::transform(this->buckets, this->buckets + this->
bucketCount(), this->buckets, [](uint64_t
const& a) {
return ~a; });
428 truncateLastBucket();
435 if (firstUnsetIndex == this->bitCount) {
439 uint64_t bucketIndex = firstUnsetIndex >> 6;
440 std::fill_n(buckets, bucketIndex, 0);
443 uint64_t& bucket = this->buckets[bucketIndex];
444 uint64_t indexInBucket = firstUnsetIndex & mod64mask;
445 if (indexInBucket > 0) {
447 uint64_t mask = ~(-1ull << (64 - indexInBucket));
452 uint64_t mask = 1ull << (63 - indexInBucket);
458 STORM_LOG_ASSERT(bitCount == other.bitCount,
"Length of the bit vectors does not match.");
461 std::transform(this->buckets, this->buckets + this->
bucketCount(), other.buckets, result.buckets,
462 [](uint64_t
const& a, uint64_t
const& b) { return (~a | b); });
463 result.truncateLastBucket();
468 STORM_LOG_ASSERT(bitCount == other.bitCount,
"Length of the bit vectors does not match.");
470 uint64_t
const* it1 = buckets;
472 uint64_t
const* it2 = other.buckets;
474 for (; it1 != ite1; ++it1, ++it2) {
475 if ((*it1 & *it2) != *it1) {
483 STORM_LOG_ASSERT(bitCount == other.bitCount,
"Length of the bit vectors does not match.");
485 uint64_t
const* it1 = buckets;
487 uint64_t
const* it2 = other.buckets;
489 for (; it1 != ite1; ++it1, ++it2) {
490 if ((*it1 & *it2) != 0) {
498 STORM_LOG_ASSERT((bitIndex & mod64mask) == 0,
"Bit index must be a multiple of 64.");
502 uint64_t index = bitIndex >> 6;
504 uint64_t
const* first1 = buckets + index;
505 uint64_t
const* first2 = other.buckets;
506 uint64_t
const* last2 = other.buckets + other.
bucketCount();
508 for (; first2 != last2; ++first1, ++first2) {
509 if (*first1 != *first2) {
518 for (uint64_t
i = 0;
i < this->
size(); ++
i) {
519 if (this->
get(inversePermutation[
i])) {
527 STORM_LOG_ASSERT(inversePermutation.size() == rowGroupIndices.size() - 1,
"Inverse permutation and row group indices do not match.");
529 uint64_t targetIndex = 0u;
530 for (
auto const sourceGroupIndex : inversePermutation) {
531 for (uint64_t sourceIndex = rowGroupIndices[sourceGroupIndex]; sourceIndex < rowGroupIndices[sourceGroupIndex + 1]; ++sourceIndex, ++targetIndex) {
532 if (this->
get(sourceIndex)) {
533 result.
set(targetIndex,
true);
537 STORM_LOG_ASSERT(targetIndex == result.
size(),
"Target index does not match the size of the result.");
542 STORM_LOG_ASSERT((bitIndex & mod64mask) == 0,
"Bit index must be a multiple of 64.");
546 uint64_t index = bitIndex >> 6;
548 uint64_t* first1 = buckets + index;
549 uint64_t
const* first2 = other.buckets;
550 uint64_t
const* last2 = other.buckets + other.
bucketCount();
552 for (; first2 != last2; ++first1, ++first2) {
559 uint64_t endPos = std::min(bitIndex + nrOfBits, bitCount);
560 for (uint64_t tmpIndex = bitIndex; tmpIndex < endPos; ++tmpIndex) {
561 set(tmpIndex, newValue);
566 uint64_t numberOfBuckets = numberOfBits >> 6;
567 uint64_t index = bitIndex >> 6;
571 std::copy(this->buckets + index, this->buckets + index + numberOfBuckets, result.buckets);
572 result.truncateLastBucket();
577 if (numberOfBits == 0) {
581 uint64_t
const firstBucket = bitIndex >> 6;
582 uint8_t
const bitIndexInFirstBucket = bitIndex & mod64mask;
583 uint8_t
const availableBitsInFirstBucket =
static_cast<uint8_t
>(64 - bitIndexInFirstBucket);
586 uint64_t result = buckets[firstBucket] << bitIndexInFirstBucket;
588 if (availableBitsInFirstBucket < numberOfBits) {
589 result |= buckets[firstBucket + 1] >> availableBitsInFirstBucket;
592 return result >> (64 - numberOfBits);
598 uint64_t bucket = bitIndex >> 6;
599 uint64_t bitIndexInBucket = bitIndex & mod64mask;
602 if (bitIndexInBucket == 0) {
605 mask = (1ull << (64 - bitIndexInBucket)) - 1ull;
608 if (bitIndexInBucket < 62) {
610 mask &= ~((1ull << (62 - (bitIndexInBucket))) - 1ull);
611 return (buckets[bucket] & mask) >> (62 - bitIndexInBucket);
614 return buckets[bucket] & mask;
621 "Integer value (" << value <<
") too large to fit in the given number of bits (" << numberOfBits <<
").");
623 uint64_t bucket = bitIndex >> 6;
624 uint64_t bitIndexInBucket = bitIndex & mod64mask;
627 if (bitIndexInBucket == 0) {
630 mask = (1ull << (64 - bitIndexInBucket)) - 1ull;
633 if (bitIndexInBucket + numberOfBits < 64) {
635 mask &= ~((1ull << (64 - (bitIndexInBucket + numberOfBits))) - 1ull);
636 buckets[bucket] = (buckets[bucket] & ~mask) | (value << (64 - (bitIndexInBucket + numberOfBits)));
637 }
else if (bitIndexInBucket + numberOfBits > 64) {
639 buckets[bucket] = (buckets[bucket] & ~mask) | (value >> (numberOfBits + (bitIndexInBucket - 64)));
643 numberOfBits -= (64 - bitIndexInBucket);
646 value <<= (64 - numberOfBits);
649 mask = ((1ull << (64 - numberOfBits)) - 1ull);
650 buckets[bucket] = (buckets[bucket] & mask) | value;
652 buckets[bucket] = (buckets[bucket] & ~mask) | value;
658 uint64_t* it = std::find_if(buckets, last, [](uint64_t
const& a) {
return a != 0; });
668 for (uint64_t
const* it = buckets; it < last; ++it) {
675 uint64_t mask = ~((1ull << (64 - (bitCount & mod64mask))) - 1ull);
676 if ((*last & mask) != mask) {
688 truncateLastBucket();
696 STORM_LOG_ASSERT(index <= bitCount,
"Invalid call to BitVector::getNumberOfSetBitsBeforeIndex: read index " << index <<
" out of bounds.");
697 uint64_t
const lastBucketIndex = index >> 6;
701 for (uint64_t
i = 0;
i < lastBucketIndex; ++
i) {
702 result += std::popcount(buckets[
i]);
706 uint8_t
const endIndexInLastBucket = index & mod64mask;
707 if (endIndexInLastBucket != 0) {
708 result += std::popcount(buckets[lastBucketIndex] >> (64 - endIndexInLastBucket));
715 std::vector<uint64_t> bitsSetBeforeIndices;
716 bitsSetBeforeIndices.reserve(this->
size());
717 uint64_t lastIndex = 0;
718 uint64_t currentNumberOfSetBits = 0;
719 for (uint64_t index : *
this) {
720 while (lastIndex <= index) {
721 bitsSetBeforeIndices.push_back(currentNumberOfSetBits);
724 ++currentNumberOfSetBits;
726 while (lastIndex < this->
size()) {
727 bitsSetBeforeIndices.push_back(currentNumberOfSetBits);
730 return bitsSetBeforeIndices;
738 return static_cast<size_t>(bitCount);
742 return sizeof(*this) +
sizeof(uint64_t) *
bucketCount();
746 size_t result = (bitCount >> 6);
747 if ((bitCount & mod64mask) != 0) {
754 STORM_LOG_ASSERT(bucketIndex <
bucketCount(),
"Invalid call to BitVector::setBucket: bucket index " << bucketIndex <<
" out of bounds.");
755 buckets[bucketIndex] = value;
757 truncateLastBucket();
762 STORM_LOG_ASSERT(bucketIndex <
bucketCount(),
"Invalid call to BitVector::getBucket: bucket index " << bucketIndex <<
" out of bounds.");
763 STORM_LOG_ASSERT(bucketIndex <
bucketCount() - 1 || (bitCount & mod64mask) == 0ull || (buckets[bucketIndex] << (bitCount & mod64mask)) == 0ull,
764 "Bitvector in invalid state: last bucket contains bits beyond bitCount.");
766 return buckets[bucketIndex] & ~((1ll << (64 - (bitCount & mod64mask))) - 1ll);
768 return buckets[bucketIndex];
795 return getNextIndexWithValue<true>(buckets, startingIndex, bitCount);
799#ifdef ASSERT_BITVECTOR
801 "The result is inconsistent with the next set index of the complement of this bitvector");
803 return getNextIndexWithValue<false>(buckets, startingIndex, bitCount);
807 return getNextIndexWithValue<true, true>(buckets, 0, endIndex);
811#ifdef ASSERT_BITVECTOR
813 "The result is inconsistent with the next set index of the complement of this bitvector");
815 return getNextIndexWithValue<false, true>(buckets, 0, endIndex);
818template<
bool Value,
bool Backward>
819uint64_t BitVector::getNextIndexWithValue(uint64_t
const* dataPtr, uint64_t startingIndex, uint64_t endIndex) {
820 if (startingIndex >= endIndex) {
821 return Backward ? startingIndex : endIndex;
824 uint64_t currentBucketIndexOffset = Backward ? endIndex - 1 : startingIndex;
825 uint_fast8_t currentBitInBucket = currentBucketIndexOffset & mod64mask;
826 uint64_t
const* bucketIt = dataPtr + (currentBucketIndexOffset >> 6);
827 currentBucketIndexOffset = (currentBucketIndexOffset >> 6 << 6);
830 uint64_t relevantBitsInBucket;
831 if constexpr (Backward) {
832 relevantBitsInBucket = -1ull << (63 - currentBitInBucket);
834 relevantBitsInBucket = -1ull >> currentBitInBucket;
836 uint64_t currentBucket = Value ? (*bucketIt & relevantBitsInBucket) : (*bucketIt | ~relevantBitsInBucket);
839 if (currentBucket == (Value ? 0ull : -1ull)) {
844 if (currentBucketIndexOffset <= startingIndex) {
846 return startingIndex;
849 currentBucketIndexOffset -= 64;
852 currentBucketIndexOffset += 64;
853 if (currentBucketIndexOffset >= endIndex) {
859 }
while ((*bucketIt) == (Value ? 0ull : -1ull));
861 currentBucket = *bucketIt;
862 currentBitInBucket =
Backward ? 63u : 0u;
865 if constexpr (!Value) {
866 currentBucket = ~currentBucket;
869 STORM_LOG_ASSERT(currentBucket != 0ull,
"Bitvector's getNextIndexWithValue method in invalid state.");
873 return std::max<uint64_t>(startingIndex,
874 currentBucketIndexOffset + 64ull - std::countr_zero(currentBucket));
877 return std::min<uint64_t>(endIndex, currentBucketIndexOffset + std::countl_zero(currentBucket));
881storm::storage::BitVector BitVector::getAsBitVector(uint64_t start, uint64_t length)
const {
883#ifdef ASSERT_BITVECTOR
886 storm::storage::BitVector result(length,
false);
888 uint64_t offset = start % 64;
889 uint64_t*
getBucket = buckets + (start / 64);
890 uint64_t* insertBucket = result.buckets;
896 for (; noBits + 64 <= length; ++
getBucket, ++insertBucket, noBits += 64) {
903 noBits += (64 - offset);
907 for (; noBits + 64 <= length; ++
getBucket, ++insertBucket, noBits += 64) {
918 uint64_t remainingBits = length - noBits;
921 getValue = (*
getBucket >> (64 - remainingBits)) << (64 - remainingBits);
924 STORM_LOG_ASSERT(insertBucket != result.buckets + result.bucketCount(),
"Bucket index incorrect.");
926 *insertBucket = getValue;
930 if (remainingBits > offset) {
934 STORM_LOG_ASSERT(insertBucket != result.buckets + result.bucketCount(),
"Bucket index incorrect.");
939#ifdef ASSERT_BITVECTOR
941 for (uint64_t
i = 0;
i < length; ++
i) {
942 if (result.get(
i) !=
get(start +
i)) {
944 STORM_LOG_ERROR(
"Getting from " << start <<
" with length " << length);
945 std::stringstream stream;
948 result.printBits(stream);
953 for (uint64_t
i = 0;
i < bitCount; ++
i) {
955 if (original.get(
i) !=
get(
i)) {
957 STORM_LOG_ERROR(
"Getting from " << start <<
" with length " << length);
958 std::stringstream stream;
961 original.printBits(stream);
972void BitVector::setFromBitVector(uint64_t start,
BitVector const& other) {
973#ifdef ASSERT_BITVECTOR
978 uint64_t offset = start % 64;
979 uint64_t* insertBucket = buckets + (start / 64);
986 for (; noBits + 64 <= other.bitCount; ++insertBucket, ++
getBucket, noBits += 64) {
992 writeValue = (*insertBucket >> (64 - offset)) << (64 - offset);
995 noBits += (64 - offset);
999 for (; noBits + 64 <= other.bitCount; ++insertBucket, noBits += 64) {
1011 uint64_t remainingBits = other.bitCount - noBits;
1018 getValue = getValue << (64 - offset);
1021 writeValue = (*insertBucket << remainingBits) >> remainingBits;
1022 if (remainingBits > offset && offset > 0) {
1032#ifdef ASSERT_BITVECTOR
1034 for (uint64_t
i = 0;
i < other.bitCount; ++
i) {
1035 if (other.get(
i) !=
get(start +
i)) {
1037 STORM_LOG_ERROR(
"Setting from " << start <<
" with length " << other.bitCount);
1038 std::stringstream stream;
1041 other.printBits(stream);
1046 for (uint64_t
i = 0;
i < bitCount; ++
i) {
1048 if (original.get(
i) !=
get(
i)) {
1050 STORM_LOG_ERROR(
"Setting from " << start <<
" with length " << other.bitCount);
1051 std::stringstream stream;
1054 original.printBits(stream);
1066 uint64_t elem1 =
getAsInt(start1, length);
1067 uint64_t elem2 =
getAsInt(start2, length);
1068 if (elem1 < elem2) {
1077 BitVector elem1 = getAsBitVector(start1, length);
1078 BitVector elem2 = getAsBitVector(start2, length);
1080 if (!(elem1 < elem2)) {
1082#ifdef ASSERT_BITVECTOR
1084 for (uint64_t
i = 0;
i < length; ++
i) {
1085 if (
get(start1 +
i) >
get(start2 +
i)) {
1088 STORM_LOG_ASSERT(
get(start1 +
i) >=
get(start2 +
i),
"Bit vector not sorted for indices " << start1 +
i <<
" and " << start2 +
i);
1094#ifdef ASSERT_BITVECTOR
1099 setFromBitVector(start1, elem2);
1100 setFromBitVector(start2, elem1);
1102#ifdef ASSERT_BITVECTOR
1105 for (uint64_t
i = 0;
i < length; ++
i) {
1106 tmp = check.get(
i + start1);
1107 check.set(
i + start1, check.get(
i + start2));
1108 check.set(
i + start2, tmp);
1113 for (uint64_t
i = 0;
i < length; ++
i) {
1114 if (
get(start1 +
i) >
get(start2 +
i)) {
1117 STORM_LOG_ASSERT(
get(start1 +
i) >=
get(start2 +
i),
"Bit vector not sorted for indices " << start1 +
i <<
" and " << start2 +
i);
1125void BitVector::truncateLastBucket() {
1126 if ((bitCount & mod64mask) != 0) {
1127 buckets[
bucketCount() - 1] &= ~((1ll << (64 - (bitCount & mod64mask))) - 1ll);
1132 out <<
"bit vector(" << bitvector.
getNumberOfSetBits() <<
"/" << bitvector.bitCount <<
") [";
1133 for (uint64_t index : bitvector) {
1134 out << index <<
" ";
1141void BitVector::printBits(std::ostream& out)
const {
1144 for (; index * 64 + 64 <= bitCount; ++index) {
1145 std::bitset<64> tmp(buckets[index]);
1150 if (index * 64 < bitCount) {
1152 std::bitset<64> tmp(buckets[index]);
1153 for (
size_t i = 0;
i + index * 64 < bitCount; ++
i) {
1162 std::size_t seed = 14695981039346656037ull;
1164 uint8_t* it =
reinterpret_cast<uint8_t*
>(bv.buckets);
1171 seed += (seed << 1) + (seed << 4) + (seed << 5) + (seed << 7) + (seed << 8) + (seed << 40);
1187inline __attribute__((always_inline)) uint64_t fmix64(uint64_t k) {
1189 k *= 0xff51afd7ed558ccdull;
1191 k *= 0xc4ceb9fe1a85ec53ull;
1197inline uint32_t
rotl32(uint32_t x, int8_t r) {
1198 return (x << r) | (x >> (32 - r));
1201inline uint64_t
rotl64(uint64_t x, int8_t r) {
1202 return (x << r) | (x >> (64 - r));
1209inline __attribute__((always_inline)) uint32_t getblock64(uint64_t
const* p,
int i) {
1217 uint8_t
const* data =
reinterpret_cast<uint8_t const*
>(bv.buckets);
1224 const uint32_t c1 = 0xcc9e2d51;
1225 const uint32_t c2 = 0x1b873593;
1230 const uint32_t* blocks =
reinterpret_cast<uint32_t const*
>(data +
static_cast<std::ptrdiff_t
>(nblocks) * 4);
1232 for (
int i = -nblocks;
i;
i++) {
1233 uint32_t k1 = getblock32(blocks,
i);
1241 h1 = h1 * 5 + 0xe6546b64;
1256 uint8_t
const* data =
reinterpret_cast<uint8_t const*
>(bv.buckets);
1263 const uint64_t c1 = 0x87c37b91114253d5ull;
1264 const uint64_t c2 = 0x4cf5ad432745937full;
1269 uint64_t
const* blocks = bv.buckets;
1271 for (
int i = 0;
i < nblocks;
i++) {
1272 uint64_t k1 = getblock64(blocks,
i * 2 + 0);
1273 uint64_t k2 = getblock64(blocks,
i * 2 + 1);
1282 h1 = h1 * 5 + 0x52dce729;
1291 h2 = h2 * 5 + 0x38495ab5;
1297 uint8_t
const* tail =
reinterpret_cast<uint8_t const*
>(data +
static_cast<std::ptrdiff_t
>(nblocks) * 16);
1305 k2 ^= ((uint64_t)tail[14]) << 48;
1308 k2 ^= ((uint64_t)tail[13]) << 40;
1311 k2 ^= ((uint64_t)tail[12]) << 32;
1314 k2 ^= ((uint64_t)tail[11]) << 24;
1317 k2 ^= ((uint64_t)tail[10]) << 16;
1320 k2 ^= ((uint64_t)tail[9]) << 8;
1323 k2 ^= ((uint64_t)tail[8]) << 0;
1331 k1 ^= ((uint64_t)tail[7]) << 56;
1334 k1 ^= ((uint64_t)tail[6]) << 48;
1337 k1 ^= ((uint64_t)tail[5]) << 40;
1340 k1 ^= ((uint64_t)tail[4]) << 32;
1343 k1 ^= ((uint64_t)tail[3]) << 24;
1346 k1 ^= ((uint64_t)tail[2]) << 16;
1349 k1 ^= ((uint64_t)tail[1]) << 8;
1352 k1 ^= ((uint64_t)tail[0]) << 0;
1385 os <<
" " << buckets[
i];
1390 std::vector<std::string> splitted;
1391 std::stringstream ss(description);
1392 ss >> std::noskipws;
1397 splitted.push_back(field);
1398 }
else if (ss.eof()) {
1401 splitted.push_back(std::string());
1407 for (uint64_t
i = 0;
i < splitted.size() - 1; ++
i) {
1408 bv.buckets[
i] = std::stoul(splitted[
i + 1]);
1414template BitVector::BitVector(uint64_t length, std::vector<uint64_t>::iterator begin, std::vector<uint64_t>::iterator end);
1415template BitVector::BitVector(uint64_t length, std::vector<uint64_t>::const_iterator begin, std::vector<uint64_t>::const_iterator end);
1418template void BitVector::set(std::vector<uint64_t>::iterator begin, std::vector<uint64_t>::iterator end,
bool value);
1419template void BitVector::set(std::vector<uint64_t>::const_iterator begin, std::vector<uint64_t>::const_iterator end,
bool value);
1430 return boost::hash_range(bitvector.buckets, bitvector.buckets + bitvector.
bucketCount());
A class that enables iterating over the indices of the bit vector whose corresponding bits are set to...
uint64_t operator*() const
Returns the index of the current bit to which this iterator points.
const_iterator & operator++()
Increases the position of the iterator to the position of the next bit that is set to true in the und...
bool operator==(const_iterator const &other) const
Compares the iterator with another iterator for equality.
const_iterator & operator+=(size_t n)
Increases the position of the iterator to the position of the n'th next bit that is set to true in th...
const_iterator & operator=(const_iterator const &other)
Assigns the contents of the given iterator to the current one via copying the former's contents.
bool operator!=(const_iterator const &other) const
Compares the iterator with another iterator for inequality.
A class that enables iterating over the indices of the bit vector whose corresponding bits are set to...
bool operator==(const_reverse_iterator const &other) const
Compares the iterator with another iterator for equality.
uint64_t operator*() const
Returns the index of the current bit to which this iterator points.
const_reverse_iterator()
Constructs a reverse iterator over the indices of the set bits in the given bit vector,...
const_reverse_iterator & operator+=(size_t n)
Lets the iterator point to the n'th previous bit with value 1.
const_reverse_iterator & operator++()
Lets the iterator point to the previous bit with value 1.
const_reverse_iterator & operator=(const_reverse_iterator const &other)
bool operator!=(const_reverse_iterator const &other) const
Compares the iterator with another iterator for inequality.
A bit vector that is internally represented as a vector of 64-bit values.
~BitVector()
Deconstructs a bit vector by deleting the underlying storage.
void complement()
Negates all bits in the bit vector.
BitVector & operator|=(BitVector const &other)
Performs a logical "or" with the given bit vector and assigns the result to the current bit vector.
uint64_t getBucket(uint64_t bucketIndex) const
Gets the bits in the given bucket.
BitVector operator^(BitVector const &other) const
Performs a logical "xor" with the given bit vector.
void setMultiple(uint64_t bitIndex, uint64_t nrOfBits, bool newValue=true)
Sets multiple bits to the given value.
bool operator<(BitVector const &other) const
Retrieves whether the current bit vector is (in some order) smaller than the given one.
const_reverse_iterator rbegin() const
Returns a reverse iterator to the indices of the set bits in the bit vector.
void fill()
Sets all bits from the bit vector.
uint64_t getNextSetIndex(uint64_t startingIndex) const
Retrieves the index of the bit that is the next bit set to true in the bit vector.
uint64_t getTwoBitsAligned(uint64_t bitIndex) const
bool isDisjointFrom(BitVector const &other) const
Checks whether none of the bits that are set in the current bit vector are also set in the given bit ...
bool full() const
Retrieves whether all bits are set in this bit vector.
std::vector< uint64_t > getNumberOfSetBitsBeforeIndices() const
Retrieves a vector that holds at position i the number of bits set before index i.
const_reverse_iterator rend() const
Returns a reverse iterator pointing at the element past the front of the bit vector.
bool hasUniqueSetBit() const
BitVector()
Constructs an empty bit vector of length 0.
const_iterator end() const
Returns an iterator pointing at the element past the back of the bit vector.
void grow(uint64_t minimumLength, bool init=false)
Enlarges the bit vector such that it holds at least the given number of bits (but possibly more).
void store(std::ostream &) const
BitVector operator%(BitVector const &filter) const
Computes a bit vector that contains only the values of the bits given by the filter.
BitVector operator|(BitVector const &other) const
Performs a logical "or" with the given bit vector.
bool empty() const
Retrieves whether no bits are set to true in this bit vector.
std::size_t getSizeInBytes() const
Returns (an approximation of) the size of the bit vector measured in bytes.
void clear()
Removes all set bits from the bit vector.
bool isSubsetOf(BitVector const &other) const
Checks whether all bits that are set in the current bit vector are also set in the given bit vector.
BitVector implies(BitVector const &other) const
Performs a logical "implies" with the given bit vector.
BitVector & operator=(BitVector const &other)
Assigns the contents of the given bit vector to the current bit vector via a deep copy.
uint64_t getNumberOfSetBits() const
Returns the number of bits that are set to true in this bit vector.
uint64_t getNextUnsetIndex(uint64_t startingIndex) const
Retrieves the index of the bit that is the next bit set to false in the bit vector.
bool compareAndSwap(uint64_t start1, uint64_t start2, uint64_t length)
Compare two intervals [start1, start1+length] and [start2, start2+length] and swap them if the second...
BitVector operator&(BitVector const &other) const
Performs a logical "and" with the given bit vector.
void setFromInt(uint64_t bitIndex, uint64_t numberOfBits, uint64_t value)
Sets the selected number of lowermost bits of the provided value at the given bit index.
BitVector permute(std::vector< uint64_t > const &inversePermutation) const
Apply a permutation of entries.
void set(uint64_t index, bool value=true)
Sets the given truth value at the given index.
void increment()
Increments the (unsigned) number represented by this BitVector by one.
size_t bucketCount() const
Retrieves the number of buckets of the underlying storage.
bool matches(uint64_t bitIndex, BitVector const &other) const
Checks whether the given bit vector matches the bits starting from the given index in the current bit...
const_iterator begin() const
Returns an iterator to the indices of the set bits in the bit vector.
uint64_t getStartOfZeroSequenceBefore(uint64_t endIndex) const
Retrieves the smallest index i such that all bits in the range [i,endIndex) are 0.
uint64_t getAsInt(uint64_t bitIndex, uint64_t numberOfBits) const
Retrieves the content of the current bit vector at the given index for the given number of bits as an...
BitVector operator~() const
Performs a logical "not" on the bit vector.
void setBucket(uint64_t bucketIndex, uint64_t value)
Sets the bits in the given bucket to the given value.
bool operator!=(BitVector const &other) const
Compares the given bit vector with the current one.
size_t size() const
Retrieves the number of bits this bit vector can store.
void resize(uint64_t newLength, bool init=false)
Resizes the bit vector to hold the given new number of bits.
BitVector & operator&=(BitVector const &other)
Performs a logical "and" with the given bit vector and assigns the result to the current bit vector.
static BitVector load(std::string const &description)
void expandSize(bool init=false)
bool get(uint64_t index) const
Retrieves the truth value of the bit at the given index and performs a bound check.
bool operator==(BitVector const &other) const
Compares the given bit vector with the current one.
uint64_t getNumberOfSetBitsBeforeIndex(uint64_t index) const
Retrieves the number of bits set in this bit vector with an index strictly smaller than the given one...
BitVector permuteGroupedVector(std::vector< uint64_t > const &inversePermutation, std::vector< uint64_t > const &rowGroupIndices) const
Apply a permutation of entries assuming a grouped vector.
uint64_t getStartOfOneSequenceBefore(uint64_t endIndex) const
Retrieves the smallest index i such that all bits in the range [i,endIndex) are 1.
bool operator[](uint64_t index) const
Retrieves the truth value of the bit at the given index.
void concat(BitVector const &extension)
Concatenate this bitvector with another bitvector.
#define STORM_LOG_ERROR(message)
#define STORM_LOG_ASSERT(cond, message)
void writeValue(std::ostream &os, ValueType value, std::unordered_map< ValueType, std::string > const &placeholders)
Write value to stream while using the placeholders.
boost::container::flat_set< Key, std::less< Key >, boost::container::new_allocator< Key > > FlatSet
Redefinition of flat_set was needed, because from Boost 1.70 on the default allocator is set to void.
uint32_t rotl32(uint32_t x, int8_t r)
uint64_t rotl64(uint64_t x, int8_t r)
__attribute__((always_inline)) uint32_t fmix32(uint32_t h)
std::ostream & operator<<(std::ostream &out, ParameterRegion< ParametricType > const ®ion)
std::size_t operator()(storm::storage::BitVector const &bv) const
StateType operator()(storm::storage::BitVector const &bv) const