Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools / gopls@v0.5.2 / integration / parse / rlog.go
1 // Copyright 2019 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package parse
6
7 import (
8         "fmt"
9         "log"
10         "strings"
11 )
12
13 // Rlog contains the processed logs
14 type Rlog struct {
15         Logs         []*Logmsg          // In the order in the log file
16         ServerCall   map[string]*Logmsg // ID->Request, client->server
17         ServerReply  map[string]*Logmsg // ID->Response, server->client (includes Errors)
18         ClientCall   map[string]*Logmsg
19         ClientReply  map[string]*Logmsg
20         ClientNotifs []*Logmsg
21         ServerNotifs []*Logmsg
22         Histogram    *LogHist
23 }
24
25 func newRlog(x []*Logmsg) *Rlog {
26         return &Rlog{Logs: x,
27                 ServerCall:   make(map[string]*Logmsg),
28                 ServerReply:  make(map[string]*Logmsg),
29                 ClientCall:   make(map[string]*Logmsg),
30                 ClientReply:  make(map[string]*Logmsg),
31                 ClientNotifs: []*Logmsg{},
32                 ServerNotifs: []*Logmsg{},
33                 Histogram:    &LogHist{},
34         }
35 }
36
37 // Counts returns a one-line summary of an Rlog
38 func (r *Rlog) Counts() string {
39         return fmt.Sprintf("logs:%d srvC:%d srvR:%d clC:%d clR:%d clN:%d srvN:%d",
40                 len(r.Logs),
41                 len(r.ServerCall), len(r.ServerReply), len(r.ClientCall), len(r.ClientReply),
42                 len(r.ClientNotifs), len(r.ServerNotifs))
43 }
44
45 // ToRlog reads a log file and returns a *Rlog
46 func ToRlog(fname string) (*Rlog, error) {
47         x, err := ReadLogs(fname)
48         if err != nil {
49                 return nil, err
50         }
51         ans := newRlog(x)
52         for _, l := range x {
53                 switch l.Type {
54                 case ClRequest:
55                         ans.ServerCall[l.ID] = l
56                 case ClResponse:
57                         ans.ServerReply[l.ID] = l
58                         if l.Type != ReportErr {
59                                 n := 0
60                                 fmt.Sscanf(l.Elapsed, "%d", &n)
61                                 ans.Histogram.add(n)
62                         }
63                 case SvRequest:
64                         ans.ClientCall[l.ID] = l
65                 case SvResponse:
66                         ans.ClientReply[l.ID] = l
67                 case ToClient:
68                         ans.ClientNotifs = append(ans.ClientNotifs, l)
69                 case ToServer:
70                         ans.ServerNotifs = append(ans.ServerNotifs, l)
71                 case ReportErr:
72                         ans.ServerReply[l.ID] = l
73                         l.Method = ans.ServerCall[l.ID].Method // Method not in log message
74                 default:
75                         log.Fatalf("eh? %s/%s (%s)", l.Type, l.Method, l.ID)
76                 }
77         }
78         return ans, nil
79 }
80
81 // LogHist gets ints, and puts them into buckets:
82 // <=10, <=30, 100, 300, 1000, ...
83 // It produces a historgram of elapsed times in milliseconds
84 type LogHist struct {
85         cnts []int
86 }
87
88 func (l *LogHist) add(n int) {
89         if n < 0 {
90                 n = 0
91         }
92         bucket := 0
93         for ; n > 0; n /= 10 {
94                 if n < 10 {
95                         break
96                 }
97                 if n < 30 {
98                         bucket++
99                         break
100                 }
101                 bucket += 2
102         }
103         if len(l.cnts) <= bucket {
104                 for j := len(l.cnts); j < bucket+10; j++ {
105                         l.cnts = append(l.cnts, 0)
106                 }
107         }
108         l.cnts[bucket]++
109 }
110
111 // String returns a string describing a histogram
112 func (l *LogHist) String() string {
113         top := len(l.cnts) - 1
114         for ; top > 0 && l.cnts[top] == 0; top-- {
115         }
116         labs := []string{"10", "30"}
117         out := strings.Builder{}
118         out.WriteByte('[')
119         for i := 0; i <= top; i++ {
120                 label := labs[i%2]
121                 labs[i%2] += "0"
122                 fmt.Fprintf(&out, "%s:%d ", label, l.cnts[i])
123         }
124         out.WriteByte(']')
125         return out.String()
126 }