in src/main/java/org/apache/datasketches/quantiles/ItemsMergeImpl.java [137:204]
static <T> void downSamplingMergeInto(final ItemsSketch<T> src, final ItemsSketch<T> tgt) {
final int sourceK = src.getK();
final int targetK = tgt.getK();
if ((sourceK % targetK) != 0) {
throw new SketchesArgumentException(
"source.getK() must equal target.getK() * 2^(nonnegative integer).");
}
final int downFactor = sourceK / targetK;
checkIfPowerOf2(downFactor, "source.getK()/target.getK() ratio");
final int lgDownFactor = Integer.numberOfTrailingZeros(downFactor);
final Object[] sourceLevels = src.getCombinedBuffer(); // aliasing is a bit dangerous
final Object[] sourceBaseBuffer = src.getCombinedBuffer(); // aliasing is a bit dangerous
final long nFinal = tgt.getN() + src.getN();
for (int i = 0; i < src.getBaseBufferCount(); i++) {
tgt.update((T) sourceBaseBuffer[i]);
}
ItemsUpdateImpl.maybeGrowLevels(tgt, nFinal);
final Object[] scratchBuf = new Object[2 * targetK];
final Object[] downBuf = new Object[targetK];
long srcBitPattern = src.getBitPattern();
for (int srcLvl = 0; srcBitPattern != 0L; srcLvl++, srcBitPattern >>>= 1) {
if ((srcBitPattern & 1L) > 0L) {
ItemsMergeImpl.justZipWithStride(
sourceLevels, (2 + srcLvl) * sourceK,
downBuf, 0,
targetK,
downFactor
);
ItemsUpdateImpl.inPlacePropagateCarry(
srcLvl + lgDownFactor,
(T[]) downBuf, 0,
(T[]) scratchBuf, 0,
false, tgt
);
// won't update target.n_ until the very end
}
}
tgt.n_ = nFinal;
assert (tgt.getN() / (2L * targetK)) == tgt.getBitPattern(); // internal consistency check
final T srcMax = src.isEmpty() ? null : src.getMaxItem();
final T srcMin = src.isEmpty() ? null : src.getMinItem();
final T tgtMax = tgt.isEmpty() ? null : tgt.getMaxItem();
final T tgtMin = tgt.isEmpty() ? null : tgt.getMinItem();
if ((srcMax != null) && (tgtMax != null)) {
tgt.maxItem_ = (src.getComparator().compare(srcMax, tgtMax) > 0) ? srcMax : tgtMax;
} //only one could be null
else if (tgtMax == null) { //if srcMax were null we would leave tgt alone
tgt.maxItem_ = srcMax;
}
if ((srcMin != null) && (tgtMin != null)) {
tgt.minItem_ = (src.getComparator().compare(srcMin, tgtMin) > 0) ? tgtMin : srcMin;
} //only one could be null
else if (tgtMin == null) { //if srcMin were null we would leave tgt alone
tgt.minItem_ = srcMin;
}
}