github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/roachpb/app_stats.go (about) 1 // Copyright 2017 The Cockroach Authors. 2 // 3 // Use of this software is governed by the Business Source License 4 // included in the file licenses/BSL.txt. 5 // 6 // As of the Change Date specified in that file, in accordance with 7 // the Business Source License, use of this software will be governed 8 // by the Apache License, Version 2.0, included in the file 9 // licenses/APL.txt. 10 11 package roachpb 12 13 import ( 14 "math" 15 16 "github.com/cockroachdb/errors" 17 ) 18 19 // GetVariance retrieves the variance of the values. 20 func (l *NumericStat) GetVariance(count int64) float64 { 21 return l.SquaredDiffs / (float64(count) - 1) 22 } 23 24 // Record updates the underlying running counts, incorporating the given value. 25 // It follows Welford's algorithm (Technometrics, 1962). The running count must 26 // be stored as it is required to finalize and retrieve the variance. 27 func (l *NumericStat) Record(count int64, val float64) { 28 delta := val - l.Mean 29 l.Mean += delta / float64(count) 30 l.SquaredDiffs += delta * (val - l.Mean) 31 } 32 33 // Add combines b into this derived statistics. 34 func (l *NumericStat) Add(b NumericStat, countA, countB int64) { 35 *l = AddNumericStats(*l, b, countA, countB) 36 } 37 38 // AlmostEqual compares two NumericStats between a window of size eps. 39 func (l *NumericStat) AlmostEqual(b NumericStat, eps float64) bool { 40 return math.Abs(l.Mean-b.Mean) <= eps && 41 math.Abs(l.SquaredDiffs-b.SquaredDiffs) <= eps 42 } 43 44 // AddNumericStats combines derived statistics. 45 // Adapted from https://www.johndcook.com/blog/skewness_kurtosis/ 46 func AddNumericStats(a, b NumericStat, countA, countB int64) NumericStat { 47 total := float64(countA + countB) 48 delta := b.Mean - a.Mean 49 50 return NumericStat{ 51 Mean: ((a.Mean * float64(countA)) + (b.Mean * float64(countB))) / total, 52 SquaredDiffs: (a.SquaredDiffs + b.SquaredDiffs) + 53 delta*delta*float64(countA)*float64(countB)/total, 54 } 55 } 56 57 // GetScrubbedCopy returns a copy of the given SensitiveInfo with its fields redacted 58 // or omitted entirely. By default, fields are omitted: if a new field is 59 // added to the SensitiveInfo proto, it must be added here to make it to the 60 // reg cluster. 61 func (si SensitiveInfo) GetScrubbedCopy() SensitiveInfo { 62 output := SensitiveInfo{} 63 output.LastErr = errors.Redact(si.LastErr) 64 // Not copying over MostRecentPlanDescription until we have an algorithm to scrub plan nodes. 65 return output 66 } 67 68 // Add combines other into this TxnStats. 69 func (s *TxnStats) Add(other TxnStats) { 70 s.TxnTimeSec.Add(other.TxnTimeSec, s.TxnCount, other.TxnCount) 71 s.TxnCount += other.TxnCount 72 s.ImplicitCount += other.ImplicitCount 73 s.CommittedCount += other.CommittedCount 74 } 75 76 // Add combines other into this StatementStatistics. 77 func (s *StatementStatistics) Add(other *StatementStatistics) { 78 s.FirstAttemptCount += other.FirstAttemptCount 79 if other.MaxRetries > s.MaxRetries { 80 s.MaxRetries = other.MaxRetries 81 } 82 s.NumRows.Add(other.NumRows, s.Count, other.Count) 83 s.ParseLat.Add(other.ParseLat, s.Count, other.Count) 84 s.PlanLat.Add(other.PlanLat, s.Count, other.Count) 85 s.RunLat.Add(other.RunLat, s.Count, other.Count) 86 s.ServiceLat.Add(other.ServiceLat, s.Count, other.Count) 87 s.OverheadLat.Add(other.OverheadLat, s.Count, other.Count) 88 89 if other.SensitiveInfo.LastErr != "" { 90 s.SensitiveInfo.LastErr = other.SensitiveInfo.LastErr 91 } 92 93 if s.SensitiveInfo.MostRecentPlanTimestamp.Before(other.SensitiveInfo.MostRecentPlanTimestamp) { 94 s.SensitiveInfo = other.SensitiveInfo 95 } 96 97 s.BytesRead += other.BytesRead 98 s.RowsRead += other.RowsRead 99 s.Count += other.Count 100 } 101 102 // AlmostEqual compares two StatementStatistics and their contained NumericStats 103 // objects within an window of size eps. 104 func (s *StatementStatistics) AlmostEqual(other *StatementStatistics, eps float64) bool { 105 return s.Count == other.Count && 106 s.FirstAttemptCount == other.FirstAttemptCount && 107 s.MaxRetries == other.MaxRetries && 108 s.NumRows.AlmostEqual(other.NumRows, eps) && 109 s.ParseLat.AlmostEqual(other.ParseLat, eps) && 110 s.PlanLat.AlmostEqual(other.PlanLat, eps) && 111 s.RunLat.AlmostEqual(other.RunLat, eps) && 112 s.ServiceLat.AlmostEqual(other.ServiceLat, eps) && 113 s.OverheadLat.AlmostEqual(other.OverheadLat, eps) && 114 s.SensitiveInfo.Equal(other.SensitiveInfo) && 115 s.BytesRead == other.BytesRead && 116 s.RowsRead == other.RowsRead 117 }