/** {@inheritDoc} */ @Override public void updateTypeSpecificStats(NamedList stv) { if (computeSum) { sum += ((Number) stv.get("sum")).doubleValue(); } if (computeSumOfSquares) { sumOfSquares += ((Number) stv.get("sumOfSquares")).doubleValue(); } if (computePercentiles) { byte[] data = (byte[]) stv.get("percentiles"); ByteBuffer buf = ByteBuffer.wrap(data); tdigest.add(AVLTreeDigest.fromBytes(buf)); } }
/** {@inheritDoc} */ @Override public void updateTypeSpecificStats(Number v, int count) { double value = v.doubleValue(); if (computeSumOfSquares) { sumOfSquares += (value * value * count); // for std deviation } if (computeSum) { sum += value * count; } if (computePercentiles) { tdigest.add(value, count); } }
/** * Adds sum, sumOfSquares, mean, stddev, and percentiles to the given NamedList * * @param res NamedList to add the type specific statistics too */ @Override protected void addTypeSpecificStats(NamedList<Object> res) { if (statsField.includeInResponse(Stat.sum)) { res.add("sum", sum); } if (statsField.includeInResponse(Stat.sumOfSquares)) { res.add("sumOfSquares", sumOfSquares); } if (statsField.includeInResponse(Stat.mean)) { res.add("mean", sum / count); } if (statsField.includeInResponse(Stat.stddev)) { res.add("stddev", getStandardDeviation()); } if (statsField.includeInResponse(Stat.percentiles)) { if (statsField.getIsShard()) { // as of current t-digest version, smallByteSize() internally does a full conversion in // order to determine what the size is (can't be precomputed?) .. so rather then // serialize to a ByteBuffer twice, allocate the max possible size buffer, // serialize once, and then copy only the byte[] subset that we need, and free up the buffer ByteBuffer buf = ByteBuffer.allocate(tdigest.byteSize()); // upper bound tdigest.asSmallBytes(buf); res.add("percentiles", Arrays.copyOf(buf.array(), buf.position())); } else { NamedList<Object> percentileNameList = new NamedList<Object>(); for (Double percentile : statsField.getPercentilesList()) { // Empty document set case if (tdigest.size() == 0) { percentileNameList.add(percentile.toString(), null); } else { Double cutoff = tdigest.quantile(percentile / 100); percentileNameList.add(percentile.toString(), cutoff); } } res.add("percentiles", percentileNameList); } } }