77
88package com .datadoghq .dogstatsd .http .serializer ;
99
10+ import com .datadoghq .dogstatsd .Sketch ;
11+ import java .nio .BufferOverflowException ;
12+
1013/** Builder for sketch timeseries. */
1114public class SketchMetric extends Metric <SketchMetric > {
15+ static final long maxBinCount = (1L << 32 ) - 1 ;
16+ static final long maxBinBytes = ProtoUtil .varintLen (maxBinCount );
17+
18+ static class BinConsumer implements Sketch .BinConsumer {
19+ int numBins ;
20+ ColumnarBuffer r ;
21+ DeltaEncoder dk = new DeltaEncoder ();
22+
23+ BinConsumer (ColumnarBuffer record ) {
24+ r = record ;
25+ }
26+
27+ @ Override
28+ public void consumeBin (short key , long count ) {
29+ while (count > maxBinCount ) {
30+ r .putSint64 (Column .sketchBinKeys , dk .encode (key ));
31+ r .putUint64 (Column .sketchBinCnts , maxBinCount );
32+ count -= maxBinCount ;
33+ numBins ++;
34+ }
35+ r .putSint64 (Column .sketchBinKeys , dk .encode (key ));
36+ r .putUint64 (Column .sketchBinCnts , count );
37+ numBins ++;
38+ }
39+ }
1240
1341 SketchMetric (PayloadBuilder pb , int type , String name ) {
1442 super (pb , type , name );
@@ -20,44 +48,29 @@ protected SketchMetric self() {
2048 }
2149
2250 /**
23- * Add a new timeseries point.
51+ * Add a new timeseries point sourced from a {@link Sketch} .
2452 *
2553 * @param timestamp Timestamp of the point in seconds since Unix epoch.
26- * @param sum Total sum of all observed values.
27- * @param min Minimum observed value.
28- * @param max Maximum observed value.
29- * @param cnt Number of observed values.
30- * @param binKeys Array of keys for each bin in the sketch.
31- * @param binCnts Array of number of observations for each bin.
54+ * @param sketch Sketch supplying the summary statistics and bin distribution.
3255 * @return This.
3356 */
34- public SketchMetric addPoint (
35- long timestamp ,
36- double sum ,
37- double min ,
38- double max ,
39- long cnt ,
40- int [] binKeys ,
41- int [] binCnts ) {
42-
43- if (binKeys .length != binCnts .length ) {
44- throw new IllegalArgumentException ("binKeys and binCnts must have the same length" );
57+ public SketchMetric addPoint (long timestamp , Sketch sketch ) {
58+ // Skip doing the work if just the bin data would exceed payload size limit.
59+ if (sketch .count () / maxBinCount * maxBinBytes >= pb .maxPayloadSize ) {
60+ throw new BufferOverflowException ();
4561 }
4662
4763 pb .timestamps .put (timestamp );
48- pb .values .put (sum );
49- pb .values .put (min );
50- pb .values .put (max );
51- pb .counts .put (cnt );
64+ pb .values .put (sketch . sum () );
65+ pb .values .put (sketch . min () );
66+ pb .values .put (sketch . max () );
67+ pb .counts .put (sketch . count () );
5268
53- ColumnarBuffer r = pb .currentRecord ();
54- DeltaEncoder dk = new DeltaEncoder ( );
69+ final ColumnarBuffer r = pb .currentRecord ();
70+ final BinConsumer bc = new BinConsumer ( r );
5571
56- r .putUint64 (Column .sketchNumBins , binKeys .length );
57- for (int i = 0 ; i < binKeys .length ; i ++) {
58- r .putSint64 (Column .sketchBinKeys , dk .encode (binKeys [i ]));
59- r .putUint64 (Column .sketchBinCnts , binCnts [i ]);
60- }
72+ sketch .bins (bc );
73+ r .putUint64 (Column .sketchNumBins , bc .numBins );
6174
6275 return this ;
6376 }
0 commit comments