in src/main/java/org/apache/datasketches/cpc/CpcCompression.java [242:333]
static long lowLevelCompressPairs(
final int[] pairArray, // input
final int numPairsToEncode, // input
final int numBaseBits, // input //cannot exceed 63 or 6 bits, could be byte
final int[] compressedWords) { // output
int pairIndex = 0;
final long[] ptrArr = new long[3];
int nextWordIndex = 0; //must be int
long bitBuf = 0; //must be long
int bufBits = 0; //could be byte
final long golombLoMask = (1L << numBaseBits) - 1L;
int predictedRowIndex = 0;
int predictedColIndex = 0;
for (pairIndex = 0; pairIndex < numPairsToEncode; pairIndex++) {
final int rowCol = pairArray[pairIndex];
final int rowIndex = rowCol >>> 6;
final int colIndex = rowCol & 0X3F; //63
if (rowIndex != predictedRowIndex) { predictedColIndex = 0; }
assert (rowIndex >= predictedRowIndex);
assert (colIndex >= predictedColIndex);
final long yDelta = rowIndex - predictedRowIndex; //cannot exceed 2^26
final int xDelta = colIndex - predictedColIndex; //cannot exceed 65
predictedRowIndex = rowIndex;
predictedColIndex = colIndex + 1;
final long codeInfo = lengthLimitedUnaryEncodingTable65[xDelta] & 0XFFFFL;
final long codeVal = codeInfo & 0XFFFL;
final int codeLen = (int) (codeInfo >>> 12);
bitBuf |= (codeVal << bufBits);
bufBits += codeLen;
//MAYBE_FLUSH_BITBUF(compressedWords, nextWordIndex);
if (bufBits >= 32) {
compressedWords[nextWordIndex++] = (int) bitBuf;
bitBuf >>>= 32;
bufBits -= 32;
}
final long golombLo = yDelta & golombLoMask; //long for bitBuf
final long golombHi = yDelta >>> numBaseBits; //cannot exceed 2^26
// Inline WriteUnary
ptrArr[NEXT_WORD_IDX] = nextWordIndex;
ptrArr[BIT_BUF] = bitBuf;
ptrArr[BUF_BITS] = bufBits;
assert nextWordIndex == ptrArr[NEXT_WORD_IDX]; //catch sign extension error
writeUnary(compressedWords, ptrArr, (int) golombHi);
nextWordIndex = (int) ptrArr[NEXT_WORD_IDX];
bitBuf = ptrArr[BIT_BUF];
bufBits = (int) ptrArr[BUF_BITS];
assert nextWordIndex == ptrArr[NEXT_WORD_IDX]; //catch truncation error
//END Inline WriteUnary
bitBuf |= golombLo << bufBits;
bufBits += numBaseBits;
//MAYBE_FLUSH_BITBUF(compressedWords, nextWordIndex);
if (bufBits >= 32) {
compressedWords[nextWordIndex++] = (int) bitBuf;
bitBuf >>>= 32;
bufBits -= 32;
}
}
// Pad the bitstream so that the decompressor's 12-bit peek can't overrun its input.
int padding = 10 - numBaseBits;
if (padding < 0) { padding = 0; }
bufBits += padding;
//MAYBE_FLUSH_BITBUF(compressedWords, nextWordIndex);
if (bufBits >= 32) {
compressedWords[nextWordIndex++] = (int) bitBuf;
bitBuf >>>= 32;
bufBits -= 32;
}
if (bufBits > 0) { // We are done encoding now, so we flush the bit buffer.
assert (bufBits < 32);
compressedWords[nextWordIndex++] = (int) bitBuf;
//bitBuf = 0;
//bufBits = 0; // not really necessary
}
return nextWordIndex;
}