in src/main/java/org/apache/datasketches/quantiles/DoublesMergeImpl.java [62:131]
static void mergeInto(final DoublesSketch src, final UpdateDoublesSketch tgt) {
final int srcK = src.getK();
final int tgtK = tgt.getK();
final long srcN = src.getN();
final long tgtN = tgt.getN();
if (srcK != tgtK) {
downSamplingMergeInto(src, tgt);
return;
}
//The remainder of this code is for the case where the k's are equal
final DoublesSketchAccessor srcSketchBuf = DoublesSketchAccessor.wrap(src);
final long nFinal = tgtN + srcN;
for (int i = 0; i < srcSketchBuf.numItems(); i++) { // update only the base buffer
tgt.update(srcSketchBuf.get(i));
}
final int spaceNeeded = DoublesUpdateImpl.getRequiredItemCapacity(tgtK, nFinal);
final int tgtCombBufItemCap = tgt.getCombinedBufferItemCapacity();
if (spaceNeeded > tgtCombBufItemCap) { //copies base buffer plus current levels
tgt.growCombinedBuffer(tgtCombBufItemCap, spaceNeeded);
}
final DoublesArrayAccessor scratch2KAcc = DoublesArrayAccessor.initialize(2 * tgtK);
long srcBitPattern = src.getBitPattern();
assert srcBitPattern == (srcN / (2L * srcK));
final DoublesSketchAccessor tgtSketchBuf = DoublesSketchAccessor.wrap(tgt, true);
long newTgtBitPattern = tgt.getBitPattern();
for (int srcLvl = 0; srcBitPattern != 0L; srcLvl++, srcBitPattern >>>= 1) {
if ((srcBitPattern & 1L) > 0L) {
newTgtBitPattern = DoublesUpdateImpl.inPlacePropagateCarry(
srcLvl,
srcSketchBuf.setLevel(srcLvl),
scratch2KAcc,
false,
tgtK,
tgtSketchBuf,
newTgtBitPattern
);
}
}
if (tgt.hasMemory() && (nFinal > 0)) {
final WritableMemory mem = tgt.getMemory();
mem.clearBits(FLAGS_BYTE, (byte) EMPTY_FLAG_MASK);
}
tgt.putN(nFinal);
tgt.putBitPattern(newTgtBitPattern); // no-op if direct
assert (tgt.getN() / (2L * tgtK)) == tgt.getBitPattern(); // internal consistency check
double srcMax = src.getMaxItem();
srcMax = Double.isNaN(srcMax) ? Double.NEGATIVE_INFINITY : srcMax;
double srcMin = src.getMinItem();
srcMin = Double.isNaN(srcMin) ? Double.POSITIVE_INFINITY : srcMin;
double tgtMax = tgt.getMaxItem();
tgtMax = Double.isNaN(tgtMax) ? Double.NEGATIVE_INFINITY : tgtMax;
double tgtMin = tgt.getMinItem();
tgtMin = Double.isNaN(tgtMin) ? Double.POSITIVE_INFINITY : tgtMin;
tgt.putMaxItem(Math.max(srcMax, tgtMax));
tgt.putMinItem(Math.min(srcMin, tgtMin));
}