in velox/dwio/dwrf/common/RLEv2.cpp [469:565]
uint64_t RleDecoderV2<isSigned>::nextDelta(
int64_t* const data,
uint64_t offset,
uint64_t numValues,
const uint64_t* const nulls) {
if (runRead == runLength) {
// extract the number of fixed bits
unsigned char fbo = (firstByte >> 1) & 0x1f;
if (fbo != 0) {
bitSize = decodeBitWidth(fbo);
} else {
bitSize = 0;
}
// extract the run length
runLength = static_cast<uint64_t>(firstByte & 0x01) << 8;
runLength |= readByte();
++runLength; // account for first value
runRead = deltaBase = 0;
// read the first value stored as vint
if constexpr (isSigned) {
firstValue = IntDecoder<isSigned>::readVsLong();
} else {
firstValue = static_cast<int64_t>(IntDecoder<isSigned>::readVuLong());
}
prevValue = firstValue;
// read the fixed delta value stored as vint (deltas can be negative even
// if all number are positive)
deltaBase = IntDecoder<isSigned>::readVsLong();
}
uint64_t nRead = std::min(runLength - runRead, numValues);
uint64_t pos = offset;
for (; pos < offset + nRead; ++pos) {
// skip null positions
if (!nulls || !bits::isBitNull(nulls, pos)) {
break;
}
}
if (runRead == 0 && pos < offset + nRead) {
data[pos++] = firstValue;
++runRead;
}
if (bitSize == 0) {
// add fixed deltas to adjacent values
for (; pos < offset + nRead; ++pos) {
// skip null positions
if (nulls && bits::isBitNull(nulls, pos)) {
continue;
}
prevValue = data[pos] = prevValue + deltaBase;
++runRead;
}
} else {
for (; pos < offset + nRead; ++pos) {
// skip null positions
if (!nulls || !bits::isBitNull(nulls, pos)) {
break;
}
}
if (runRead < 2 && pos < offset + nRead) {
// add delta base and first value
prevValue = data[pos++] = firstValue + deltaBase;
++runRead;
}
// write the unpacked values, add it to previous value and store final
// value to result buffer. if the delta base value is negative then it
// is a decreasing sequence else an increasing sequence
uint64_t remaining = (offset + nRead) - pos;
runRead += readLongs(data, pos, remaining, bitSize, nulls);
if (deltaBase < 0) {
for (; pos < offset + nRead; ++pos) {
// skip null positions
if (nulls && bits::isBitNull(nulls, pos)) {
continue;
}
prevValue = data[pos] = prevValue - data[pos];
}
} else {
for (; pos < offset + nRead; ++pos) {
// skip null positions
if (nulls && bits::isBitNull(nulls, pos)) {
continue;
}
prevValue = data[pos] = prevValue + data[pos];
}
}
}
return nRead;
}