Add TDigest.Clone and TDigest.Compression
- Id
- a1bd725b464889c3fa9c0dfdee16cf27e3269603
- Author
- Vladimir Mihailenco
- Commit time
- 2018-11-05T11:50:51+02:00
Modified tdigest.go
return previousMean*previousWeight + nextMean*nextWeight
}
+// Compression returns the TDigest compression.
+func (t *TDigest) Compression() float64 {
+ return t.compression
+}
+
// Quantile returns the desired percentile estimation.
//
// Values of p must be between 0 and 1 (inclusive), will panic otherwise.
return (tot + aCount*interpolate(value, aMean-left, aMean+right)) / float64(t.Count())
}
return 1
+}
+
+// Clone returns a deep copy of a TDigest.
+func (t *TDigest) Clone() *TDigest {
+ summary := t.summary.Clone()
+ summary.rebuildFenwickTree()
+ return &TDigest{
+ summary: summary,
+ compression: t.compression,
+ count: t.count,
+ rng: t.rng,
+ }
}
func interpolate(x, x0, x1 float64) float64 {
Modified tdigest_test.go
return sum / float64(count)
}
+func TestClone(t *testing.T) {
+ seed := func(td *TDigest) {
+ for i := 0; i < 100; i++ {
+ err := td.Add(rand.Float64())
+ if err != nil {
+ t.Fatal(err)
+ }
+ }
+ }
+
+ td := uncheckedNew()
+ seed(td)
+ clone := td.Clone()
+
+ // Clone behaves like td.
+
+ if clone.Compression() != td.Compression() {
+ t.Fatalf("got %f, wanted %f", clone.Compression(), td.Compression())
+ }
+
+ cloneCount := clone.Count()
+ if cloneCount != td.Count() {
+ t.Fatalf("got %d, wanted %d", cloneCount, td.Count())
+ }
+
+ cloneQuantile := clone.Quantile(1)
+ if cloneQuantile != td.Quantile(1) {
+ t.Fatalf("got %f, wanted %f", cloneQuantile, td.Quantile(1))
+ }
+
+ seed(td)
+ if td.Count() == clone.Count() {
+ t.Fatal("seed does not work")
+ }
+
+ // Clone is not changed after td is changed.
+
+ if clone.Count() != cloneCount {
+ t.Fatalf("got %d, wanted %d", clone.Count(), cloneCount)
+ }
+
+ if clone.Quantile(1) != cloneQuantile {
+ t.Fatalf("got %f, wanted %f", clone.Quantile(1), cloneQuantile)
+ }
+
+ // Clone is fully functional.
+
+ err := clone.Add(1)
+ if err != nil {
+ t.Fatal(err)
+ }
+}
+
func benchmarkAddCompression(compression uint32, b *testing.B) {
t := uncheckedNew(Compression(compression))