stats.go 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. package stats
  2. import (
  3. "errors"
  4. "fmt"
  5. "math"
  6. )
  7. type StatType string
  8. const (
  9. Val StatType = ""
  10. Avg StatType = "avg"
  11. Max StatType = "max"
  12. Min StatType = "min"
  13. P95 StatType = "p95"
  14. P85 StatType = "p85"
  15. )
  16. type Stats map[StatType]float64
  17. func NewStats(capacity ...int) Stats {
  18. if len(capacity) == 1 {
  19. s := make(map[StatType]float64, capacity[0])
  20. return s
  21. }
  22. return map[StatType]float64{}
  23. }
  24. func (s Stats) Value() (float64, bool) {
  25. if s == nil {
  26. return 0.0, false
  27. }
  28. val, ok := s[Val]
  29. return val, ok
  30. }
  31. func (s Stats) Avg() (float64, bool) {
  32. if s == nil {
  33. return 0.0, false
  34. }
  35. val, ok := s[Avg]
  36. return val, ok
  37. }
  38. func (s Stats) Max() (float64, bool) {
  39. if s == nil {
  40. return 0.0, false
  41. }
  42. val, ok := s[Max]
  43. return val, ok
  44. }
  45. func (s Stats) Min() (float64, bool) {
  46. if s == nil {
  47. return 0.0, false
  48. }
  49. val, ok := s[Min]
  50. return val, ok
  51. }
  52. func (s Stats) P95() (float64, bool) {
  53. if s == nil {
  54. return 0.0, false
  55. }
  56. val, ok := s[P95]
  57. return val, ok
  58. }
  59. func (s Stats) P85() (float64, bool) {
  60. if s == nil {
  61. return 0.0, false
  62. }
  63. val, ok := s[P85]
  64. return val, ok
  65. }
  66. func (s Stats) Sanitize() error {
  67. if s == nil {
  68. return nil
  69. }
  70. var errs []error
  71. for t := range s {
  72. if math.IsNaN(s[t]) {
  73. delete(s, t)
  74. errs = append(errs, fmt.Errorf("%v is NaN", t))
  75. }
  76. if math.IsInf(s[t], 0) {
  77. delete(s, t)
  78. errs = append(errs, fmt.Errorf("%v is Inf", t))
  79. }
  80. }
  81. if len(errs) > 0 {
  82. errStr := fmt.Sprintf("%d errors:", len(errs))
  83. for _, e := range errs {
  84. errStr += fmt.Sprintf(" [%s]", e)
  85. }
  86. return errors.New(errStr)
  87. }
  88. return nil
  89. }