setup_instruments: use query with parameter
[pstop.git] / p_s / table_io_waits_summary_by_table / public.go
1 // p_s - library routines for pstop.
2 //
3 // This file contains the library routines for managing the
4 // table_io_waits_by_table table.
5 package table_io_waits_summary_by_table
6
7 import (
8         "database/sql"
9         "fmt"
10         "time"
11
12         "github.com/sjmudd/pstop/lib"
13         "github.com/sjmudd/pstop/p_s"
14 )
15
16 // a table of rows
17 type Object struct {
18         p_s.RelativeStats
19         p_s.InitialTime
20         want_latency bool
21         initial      table_rows // initial data for relative values
22         current      table_rows // last loaded values
23         results      table_rows // results (maybe with subtraction)
24         totals       table_row  // totals of results
25 }
26
27 func (t *Object) SetWantsLatency(want_latency bool) {
28         t.want_latency = want_latency
29 }
30
31 func (t Object) WantsLatency() bool {
32         return t.want_latency
33 }
34
35 // Collect() collects data from the db, updating initial
36 // values if needed, and then subtracting initial values if we want
37 // relative values, after which it stores totals.
38 func (t *Object) Collect(dbh *sql.DB) {
39         start := time.Now()
40         // lib.Logger.Println("Object.Collect() BEGIN")
41         t.current = select_rows(dbh)
42         lib.Logger.Println("t.current collected", len(t.current), "row(s) from SELECT")
43
44         if len(t.initial) == 0 && len(t.current) > 0 {
45                 lib.Logger.Println("t.initial: copying from t.current (initial setup)")
46                 t.initial = make(table_rows, len(t.current))
47                 copy(t.initial, t.current)
48         }
49
50         // check for reload initial characteristics
51         if t.initial.needs_refresh(t.current) {
52                 lib.Logger.Println("t.initial: copying from t.current (data needs refreshing)")
53                 t.initial = make(table_rows, len(t.current))
54                 copy(t.initial, t.current)
55         }
56
57         t.make_results()
58
59         // lib.Logger.Println( "t.initial:", t.initial )
60         // lib.Logger.Println( "t.current:", t.current )
61         lib.Logger.Println("t.initial.totals():", t.initial.totals())
62         lib.Logger.Println("t.current.totals():", t.current.totals())
63         // lib.Logger.Println("t.results:", t.results)
64         // lib.Logger.Println("t.totals:", t.totals)
65         lib.Logger.Println("Object.Collect() END, took:", time.Duration(time.Since(start)).String())
66 }
67
68 func (t *Object) make_results() {
69         // lib.Logger.Println( "- t.results set from t.current" )
70         t.results = make(table_rows, len(t.current))
71         copy(t.results, t.current)
72         if t.WantRelativeStats() {
73                 // lib.Logger.Println( "- subtracting t.initial from t.results as WantRelativeStats()" )
74                 t.results.subtract(t.initial)
75         }
76
77         // lib.Logger.Println( "- sorting t.results" )
78         t.results.Sort(t.want_latency)
79         // lib.Logger.Println( "- collecting t.totals from t.results" )
80         t.totals = t.results.totals()
81 }
82
83 // reset the statistics to current values
84 func (t *Object) SyncReferenceValues() {
85         // lib.Logger.Println( "Object.SyncReferenceValues() BEGIN" )
86
87         t.SetNow()
88         t.initial = make(table_rows, len(t.current))
89         copy(t.initial, t.current)
90
91         t.make_results()
92
93         // lib.Logger.Println( "Object.SyncReferenceValues() END" )
94 }
95
96 func (t *Object) Headings() string {
97         if t.want_latency {
98                 return t.latencyHeadings()
99         } else {
100                 return t.opsHeadings()
101         }
102 }
103
104 func (t Object) RowContent(max_rows int) []string {
105         if t.want_latency {
106                 return t.latencyRowContent(max_rows)
107         } else {
108                 return t.opsRowContent(max_rows)
109         }
110 }
111
112 func (t Object) EmptyRowContent() string {
113         if t.want_latency {
114                 return t.emptyLatencyRowContent()
115         } else {
116                 return t.emptyOpsRowContent()
117         }
118 }
119
120 func (t Object) TotalRowContent() string {
121         if t.want_latency {
122                 return t.totalLatencyRowContent()
123         } else {
124                 return t.totalOpsRowContent()
125         }
126 }
127
128 func (t Object) Description() string {
129         if t.want_latency {
130                 return t.latencyDescription()
131         } else {
132                 return t.opsDescription()
133         }
134 }
135
136 func (t *Object) latencyHeadings() string {
137         var r table_row
138
139         return r.latency_headings()
140 }
141
142 func (t *Object) opsHeadings() string {
143         var r table_row
144
145         return r.ops_headings()
146 }
147
148 func (t Object) opsRowContent(max_rows int) []string {
149         rows := make([]string, 0, max_rows)
150
151         for i := range t.results {
152                 if i < max_rows {
153                         rows = append(rows, t.results[i].ops_row_content(t.totals))
154                 }
155         }
156
157         return rows
158 }
159
160 func (t Object) latencyRowContent(max_rows int) []string {
161         rows := make([]string, 0, max_rows)
162
163         for i := range t.results {
164                 if i < max_rows {
165                         rows = append(rows, t.results[i].latency_row_content(t.totals))
166                 }
167         }
168
169         return rows
170 }
171
172 func (t Object) emptyOpsRowContent() string {
173         var r table_row
174
175         return r.ops_row_content(r)
176 }
177
178 func (t Object) emptyLatencyRowContent() string {
179         var r table_row
180
181         return r.latency_row_content(r)
182 }
183
184 func (t Object) totalOpsRowContent() string {
185         return t.totals.ops_row_content(t.totals)
186 }
187
188 func (t Object) totalLatencyRowContent() string {
189         return t.totals.latency_row_content(t.totals)
190 }
191
192 func (t Object) latencyDescription() string {
193         count := t.count_rows()
194         return fmt.Sprintf("Latency by Table Name (table_io_waits_summary_by_table) %d rows", count)
195 }
196
197 func (t Object) opsDescription() string {
198         count := t.count_rows()
199         return fmt.Sprintf("Operations by Table Name (table_io_waits_summary_by_table) %d rows", count)
200 }
201
202 func (t Object) count_rows() int {
203         var count int
204         for row := range t.results {
205                 if t.results[row].SUM_TIMER_WAIT > 0 {
206                         count++
207                 }
208         }
209         return count
210 }