github.com/nsqio/nsq@v1.3.0/internal/quantile/aggregate.go (about) 1 package quantile 2 3 import ( 4 "encoding/json" 5 "math" 6 "sort" 7 ) 8 9 type E2eProcessingLatencyAggregate struct { 10 Count int `json:"count"` 11 Percentiles []map[string]float64 `json:"percentiles"` 12 Topic string `json:"topic"` 13 Channel string `json:"channel"` 14 Addr string `json:"host"` 15 } 16 17 func (e *E2eProcessingLatencyAggregate) UnmarshalJSON(b []byte) error { 18 var resp struct { 19 Count int `json:"count"` 20 Percentiles []map[string]float64 `json:"percentiles"` 21 Topic string `json:"topic"` 22 Channel string `json:"channel"` 23 Addr string `json:"host"` 24 } 25 err := json.Unmarshal(b, &resp) 26 if err != nil { 27 return err 28 } 29 30 for _, p := range resp.Percentiles { 31 p["min"] = p["value"] 32 p["max"] = p["value"] 33 p["average"] = p["value"] 34 p["count"] = float64(resp.Count) 35 } 36 37 e.Count = resp.Count 38 e.Percentiles = resp.Percentiles 39 e.Topic = resp.Topic 40 e.Channel = resp.Channel 41 e.Addr = resp.Addr 42 43 return nil 44 } 45 46 func (e *E2eProcessingLatencyAggregate) Len() int { return len(e.Percentiles) } 47 func (e *E2eProcessingLatencyAggregate) Swap(i, j int) { 48 e.Percentiles[i], e.Percentiles[j] = e.Percentiles[j], e.Percentiles[i] 49 } 50 func (e *E2eProcessingLatencyAggregate) Less(i, j int) bool { 51 return e.Percentiles[i]["percentile"] > e.Percentiles[j]["percentile"] 52 } 53 54 // Add merges e2 into e by averaging the percentiles 55 func (e *E2eProcessingLatencyAggregate) Add(e2 *E2eProcessingLatencyAggregate) { 56 e.Addr = "*" 57 p := e.Percentiles 58 e.Count += e2.Count 59 for _, value := range e2.Percentiles { 60 i := -1 61 for j, v := range p { 62 if value["quantile"] == v["quantile"] { 63 i = j 64 break 65 } 66 } 67 if i == -1 { 68 i = len(p) 69 e.Percentiles = append(p, make(map[string]float64)) 70 p = e.Percentiles 71 p[i]["quantile"] = value["quantile"] 72 } 73 p[i]["max"] = math.Max(value["max"], p[i]["max"]) 74 p[i]["min"] = math.Min(value["max"], p[i]["max"]) 75 p[i]["count"] += value["count"] 76 if p[i]["count"] == 0 { 77 p[i]["average"] = 0 78 continue 79 } 80 delta := value["average"] - p[i]["average"] 81 R := delta * value["count"] / p[i]["count"] 82 p[i]["average"] = p[i]["average"] + R 83 } 84 sort.Sort(e) 85 }