12[[maybe_unused]] std::size_t countBlocks(
Partition const& partition) {
13 std::size_t result = 0;
23 return containedBlockIndices.size();
27 return containedBlockIndices.empty();
31 return blockIndices.get(partition.getBlockIndex(block));
36 STORM_LOG_ASSERT(!partition.isProperSuperBlock(block),
"Cannot insert block that is a proper superblock.");
37 if (BlockIndex i = partition.getBlockIndex(block); !blockIndices.get(i)) {
38 blockIndices.set(i,
true);
39 containedBlockIndices.push_back(i);
45 BlockIndex
const i = containedBlockIndices.back();
46 blockIndices.set(i,
false);
47 containedBlockIndices.pop_back();
48 return partition.getBlockFromIndex(i);
52 STORM_LOG_THROW(numElements > 0, storm::exceptions::InvalidArgumentException,
"Cannot create a partition without elements.");
53 auto indexRange = std::ranges::iota_view<ElementIndex, ElementIndex>(0, numElements);
54 blockContents.assign(indexRange.begin(), indexRange.end());
55 blockContentsInverse = blockContents;
56 elementToBlockIndex.assign(numElements, 0);
57 blockSizes.assign(numElements, 0);
58 blockSizes[0] = blockContents.size();
62 STORM_LOG_ASSERT(countBlocks(*
this) == numBlocks,
"The cached number of blocks is inconsistent with the actual number of blocks");
67 return elementToBlockIndex.size();
71 return Block(blockContents.begin(), blockContents.end());
75 STORM_LOG_ASSERT(element < elementToBlockIndex.size(),
"Element index out of bounds");
76 return getBlockFromIndex(elementToBlockIndex[element]);
88 return subblock.data() >= superblock.data() && (subblock.data() + subblock.size()) <= (superblock.data() + superblock.size());
94 return lhs.data() == rhs.data() && lhs.size() == rhs.size();
98 STORM_LOG_ASSERT(element1 < elementToBlockIndex.size() && element2 < elementToBlockIndex.size(),
"Element index out of bounds");
100 return elementToBlockIndex[element1] == elementToBlockIndex[element2];
105 return eBlock.data() == block.data() && eBlock.size() == block.size();
108Partition::BlockIndex Partition::getBlockIndex(Block
const& block)
const {
110 return std::distance(blockContents.data(), block.data());
114 STORM_LOG_ASSERT(blockIndex < blockContents.size(),
"Block index out of bounds");
115 STORM_LOG_ASSERT(blockSizes[blockIndex] > 0,
"Block index points to a non-existent block");
116 return Block(blockContents.data() + blockIndex, blockSizes[blockIndex]);
119Partition::Block Partition::registerNewBlock(BlockIndex
const start, BlockIndex
const end) {
120 STORM_LOG_ASSERT(start < end && end <= blockContents.size(),
"Invalid block range");
121 Block newBlock(blockContents.data() + start, end - start);
123 if (blockSizes[start] == 0) {
125 elementToBlockIndex[e] = start;
128 STORM_LOG_ASSERT(blockSizes[start] >= newBlock.size(),
"Shrinking a block should not increase its size");
130 blockSizes[start] = newBlock.size();
140 if (block.data() < blockContents.data() || block.data() + block.size() > blockContents.data() + blockContents.size()) {
144 BlockIndex
const blockIndex = std::distance(blockContents.data(), block.data());
145 BlockIndex
const blockEndIndex = blockIndex + block.size();
148 if (!(blockSizes[blockIndex] > 0 && (blockEndIndex == blockContents.size() || blockSizes[blockEndIndex] != 0))) {
153 if (elementToBlockIndex[block[0]] != blockIndex) {
158 if (&blockContents[blockContentsInverse[block.front()]] != &block.front() || &blockContents[blockContentsInverse[block.back()]] != &block.back()) {
165 if (blockSizes[blockIndex] != block.size()) {
170 return (elementToBlockIndex[block.front()] == blockIndex) && (elementToBlockIndex[block.back()] == blockIndex);
174 if (blockSizes[blockIndex] >= block.size()) {
178 return std::all_of(block.begin(), block.end(), [
this, blockIndex, blockEndIndex](
ElementIndex const& e) {
180 return elementToBlockIndex[e] >= blockIndex && elementToBlockIndex[e] < blockEndIndex;
NonSuperBlockSet(Partition const &partition)
Creates an empty set associated with the given partition.
void insert(Block const &block)
Inserts the given block into the set.
Block pop()
Removes and returns an arbitrary block from the set.
bool contains(Block const &block) const
Represents a partition of a set of consecutive indices.
bool contains(Block const &block, ElementIndex element) const
void forEachBlock(Func const &f) const
Applies the given function on each block in the partition.
uint64_t ElementIndex
The type used to index the elements of the partition.
std::size_t getNumberOfBlocks() const
Retrieves the number of blocks.
bool isSameBlock(ElementIndex const &element1, ElementIndex const &element2) const
bool isBlockOfElement(Block const &block, ElementIndex const &element) const
std::size_t getNumberOfElements() const
Retrieves the number of elements.
std::span< ElementIndex const > Block
A contiguous range of elements that form a (possibly proper super-) block of the partition.
bool isSubBlockOf(Block const &subblock, Block const &superblock) const
Block getBlockOfElement(ElementIndex element) const
Block getUniversalBlock() const
bool isProperSuperBlock(Block const &block) const
bool isEqualBlock(Block const &lhs, Block const &rhs) const
bool checkBlockValidity(Block const &block) const
Checks if the given block is a valid block in the partition.
#define STORM_LOG_ASSERT(cond, message)
#define STORM_LOG_THROW(cond, exception, message)
std::ostream & operator<<(std::ostream &os, const Partition &partition)