boolean expectingSparseRunNext = false;
int lastCompressedSize = 0;
int compUnitSize = 1 << getCompressionUnitSize();
while (getUInt8(offset) != 0x0) {
final DataRun dataRun = new DataRun(this, offset, vcn, previousLCN);
if (compressed) {
if (dataRun.isSparse() && expectingSparseRunNext) {
// This is the sparse run which follows a compressed run.
// The number of runs it contains does not count towards the total
// as the compressed run reports holding all the runs for the pair.
// But we do need to move the offsets.
expectingSparseRunNext = false;
// Also the sparse run following a compressed run can be coalesced with a subsequent 'real' sparse
// run. So add that in if we hit one
if (dataRun.getLength() + lastCompressedSize > compUnitSize) {
int length = dataRun.getLength() - (compUnitSize - lastCompressedSize);
dataruns.add(new DataRun(0, length, true, 0, vcn));
this.numberOfVCNs += length;
vcn += length;
lastCompressedSize = 0;
}
} else if (dataRun.getLength() >= compUnitSize) {
// Compressed/sparse pairs always add to the compression unit size. If
// the unit only compresses to 16, the system will store it uncompressed.
// Also if one-or more of these uncompressed runs happen next to each other then they can be
// coalesced into a single run and even coalesced into the next compressed run. In that case the
// compressed run needs to be split off
int remainder = dataRun.getLength() % compUnitSize;
if (remainder != 0) {
// Uncompressed run coalesced with compressed run. First add in the uncompressed portion:
int uncompressedLength = dataRun.getLength() - remainder;
DataRun uncompressed = new DataRun(dataRun.getCluster(), uncompressedLength, false, 0, vcn);
dataruns.add(uncompressed);
vcn += uncompressedLength;
this.numberOfVCNs += uncompressedLength;
// Next add in the compressed portion
DataRun compressedRun =
new DataRun(dataRun.getCluster() + uncompressedLength, remainder, false, 0, vcn);
dataruns.add(new CompressedDataRun(compressedRun, compUnitSize));
expectingSparseRunNext = true;
lastCompressedSize = remainder;
this.numberOfVCNs += compUnitSize;