> partition) {
mPartition = partition;
}
/**
* Note: Two calls to this method result in different {@link Pair} objects.
*
* {@inheritDoc}
*/
@Override
public Iterator> iterator() {
final Iterator> iterator = mPartition.iterator();
if (iterator.hasNext()) {
return new IteratorFromPartition<>(iterator);
}
return Collections.emptyIterator();
}
@Override
public void addPair(final E lhs, final E rhs) {
throw new UnsupportedOperationException("The partition must be specified at construction time.");
}
@Override
public boolean containsPair(final E lhs, final E rhs) {
throw new UnsupportedOperationException("This class does not support a contains() method. Use the "
+ PartitionAndMapBackedSetOfPairs.class.getSimpleName() + " class instead.");
}
@Override
public Collection> getRelation() {
return mPartition;
}
/**
* @return Size information of the partition.
*/
public PartitionSizeInformation getOrConstructPartitionSizeInformation() {
if (mPartitionSizeInformation == null) {
mPartitionSizeInformation = new PartitionSizeInformation(mPartition);
}
return mPartitionSizeInformation;
}
/**
* Iterator wrapper.
*
* @author Christian Schilling (schillic@informatik.uni-freiburg.de)
* @param
* element type
*/
static final class IteratorFromPartition implements Iterator> {
private final Iterator> mBlockIt;
private Iterator mElemLhsIt;
private Iterator mElemRhsIt;
private Iterable mBlock;
private E mElemLhs;
public IteratorFromPartition(final Iterator> blockIterator) {
mBlockIt = blockIterator;
advanceToNextBlock();
}
@Override
public boolean hasNext() {
if (mElemRhsIt.hasNext()) {
return true;
}
if (mElemLhsIt.hasNext()) {
mElemLhs = mElemLhsIt.next();
mElemRhsIt = mBlock.iterator();
return true;
}
if (mBlockIt.hasNext()) {
advanceToNextBlock();
return true;
}
return false;
}
@Override
public Pair next() {
final E rhs = mElemRhsIt.next();
return new Pair<>(mElemLhs, rhs);
}
private void advanceToNextBlock() {
mBlock = mBlockIt.next();
mElemLhsIt = mBlock.iterator();
if (mElemLhsIt.hasNext()) {
mElemLhs = mElemLhsIt.next();
}
mElemRhsIt = mBlock.iterator();
}
}
/**
* Size information of the partition.
*
* @author Matthias Heizmann (heizmann@informatik.uni-freiburg.de)
*/
public static class PartitionSizeInformation {
private long mNumberOfPairs;
private int mSizeOfLargestBlock;
private final int mNumberOfBlocks;
/**
* @param partition
* Partition.
*/
public PartitionSizeInformation(final Collection extends Set>> partition) {
mNumberOfBlocks = partition.size();
for (final Set> block : partition) {
mSizeOfLargestBlock = Math.max(mSizeOfLargestBlock, block.size());
mNumberOfPairs += ((long) block.size()) * ((long) block.size()) - block.size();
}
}
public long getNumberOfPairs() {
return mNumberOfPairs;
}
public int getSizeOfLargestBlock() {
return mSizeOfLargestBlock;
}
public int getNumberOfBlocks() {
return mNumberOfBlocks;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
// @formatter:off
sb.append(getNumberOfPairs())
.append(" pairs, ")
.append(getNumberOfBlocks())
.append(" blocks, ")
.append("largest block has ")
.append(getSizeOfLargestBlock())
.append(" elements");
// @formatter:on
return sb.toString();
}
}
@Override
public String toString() {
return mPartition.toString();
}
}