...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package profile
16
17
18
19 import "regexp"
20
21
22
23
24 func (p *Profile) FilterSamplesByName(focus, ignore, hide, show *regexp.Regexp) (fm, im, hm, hnm bool) {
25 if focus == nil && ignore == nil && hide == nil && show == nil {
26 fm = true
27 return
28 }
29 focusOrIgnore := make(map[uint64]bool)
30 hidden := make(map[uint64]bool)
31 for _, l := range p.Location {
32 if ignore != nil && l.matchesName(ignore) {
33 im = true
34 focusOrIgnore[l.ID] = false
35 } else if focus == nil || l.matchesName(focus) {
36 fm = true
37 focusOrIgnore[l.ID] = true
38 }
39
40 if hide != nil && l.matchesName(hide) {
41 hm = true
42 l.Line = l.unmatchedLines(hide)
43 if len(l.Line) == 0 {
44 hidden[l.ID] = true
45 }
46 }
47 if show != nil {
48 l.Line = l.matchedLines(show)
49 if len(l.Line) == 0 {
50 hidden[l.ID] = true
51 } else {
52 hnm = true
53 }
54 }
55 }
56
57 s := make([]*Sample, 0, len(p.Sample))
58 for _, sample := range p.Sample {
59 if focusedAndNotIgnored(sample.Location, focusOrIgnore) {
60 if len(hidden) > 0 {
61 var locs []*Location
62 for _, loc := range sample.Location {
63 if !hidden[loc.ID] {
64 locs = append(locs, loc)
65 }
66 }
67 if len(locs) == 0 {
68
69 continue
70 }
71 sample.Location = locs
72 }
73 s = append(s, sample)
74 }
75 }
76 p.Sample = s
77
78 return
79 }
80
81
82
83
84
85
86
87
88
89
90
91 func (p *Profile) ShowFrom(showFrom *regexp.Regexp) (matched bool) {
92 if showFrom == nil {
93 return false
94 }
95
96 showFromLocs := make(map[uint64]bool)
97
98 for _, loc := range p.Location {
99 if filterShowFromLocation(loc, showFrom) {
100 showFromLocs[loc.ID] = true
101 matched = true
102 }
103 }
104
105 s := make([]*Sample, 0, len(p.Sample))
106 for _, sample := range p.Sample {
107 for i := len(sample.Location) - 1; i >= 0; i-- {
108 if showFromLocs[sample.Location[i].ID] {
109 sample.Location = sample.Location[:i+1]
110 s = append(s, sample)
111 break
112 }
113 }
114 }
115 p.Sample = s
116 return matched
117 }
118
119
120
121
122 func filterShowFromLocation(loc *Location, showFrom *regexp.Regexp) bool {
123 if m := loc.Mapping; m != nil && showFrom.MatchString(m.File) {
124 return true
125 }
126 if i := loc.lastMatchedLineIndex(showFrom); i >= 0 {
127 loc.Line = loc.Line[:i+1]
128 return true
129 }
130 return false
131 }
132
133
134
135 func (loc *Location) lastMatchedLineIndex(re *regexp.Regexp) int {
136 for i := len(loc.Line) - 1; i >= 0; i-- {
137 if fn := loc.Line[i].Function; fn != nil {
138 if re.MatchString(fn.Name) || re.MatchString(fn.Filename) {
139 return i
140 }
141 }
142 }
143 return -1
144 }
145
146
147
148 func (p *Profile) FilterTagsByName(show, hide *regexp.Regexp) (sm, hm bool) {
149 matchRemove := func(name string) bool {
150 matchShow := show == nil || show.MatchString(name)
151 matchHide := hide != nil && hide.MatchString(name)
152
153 if matchShow {
154 sm = true
155 }
156 if matchHide {
157 hm = true
158 }
159 return !matchShow || matchHide
160 }
161 for _, s := range p.Sample {
162 for lab := range s.Label {
163 if matchRemove(lab) {
164 delete(s.Label, lab)
165 }
166 }
167 for lab := range s.NumLabel {
168 if matchRemove(lab) {
169 delete(s.NumLabel, lab)
170 }
171 }
172 }
173 return
174 }
175
176
177
178
179 func (loc *Location) matchesName(re *regexp.Regexp) bool {
180 for _, ln := range loc.Line {
181 if fn := ln.Function; fn != nil {
182 if re.MatchString(fn.Name) || re.MatchString(fn.Filename) {
183 return true
184 }
185 }
186 }
187 if m := loc.Mapping; m != nil && re.MatchString(m.File) {
188 return true
189 }
190 return false
191 }
192
193
194
195 func (loc *Location) unmatchedLines(re *regexp.Regexp) []Line {
196 if m := loc.Mapping; m != nil && re.MatchString(m.File) {
197 return nil
198 }
199 var lines []Line
200 for _, ln := range loc.Line {
201 if fn := ln.Function; fn != nil {
202 if re.MatchString(fn.Name) || re.MatchString(fn.Filename) {
203 continue
204 }
205 }
206 lines = append(lines, ln)
207 }
208 return lines
209 }
210
211
212
213 func (loc *Location) matchedLines(re *regexp.Regexp) []Line {
214 if m := loc.Mapping; m != nil && re.MatchString(m.File) {
215 return loc.Line
216 }
217 var lines []Line
218 for _, ln := range loc.Line {
219 if fn := ln.Function; fn != nil {
220 if !re.MatchString(fn.Name) && !re.MatchString(fn.Filename) {
221 continue
222 }
223 }
224 lines = append(lines, ln)
225 }
226 return lines
227 }
228
229
230
231
232
233 func focusedAndNotIgnored(locs []*Location, m map[uint64]bool) bool {
234 var f bool
235 for _, loc := range locs {
236 if focus, focusOrIgnore := m[loc.ID]; focusOrIgnore {
237 if focus {
238
239
240 f = true
241 } else {
242
243 return false
244 }
245 }
246 }
247 return f
248 }
249
250
251 type TagMatch func(s *Sample) bool
252
253
254
255
256 func (p *Profile) FilterSamplesByTag(focus, ignore TagMatch) (fm, im bool) {
257 samples := make([]*Sample, 0, len(p.Sample))
258 for _, s := range p.Sample {
259 focused, ignored := true, false
260 if focus != nil {
261 focused = focus(s)
262 }
263 if ignore != nil {
264 ignored = ignore(s)
265 }
266 fm = fm || focused
267 im = im || ignored
268 if focused && !ignored {
269 samples = append(samples, s)
270 }
271 }
272 p.Sample = samples
273 return
274 }
275
View as plain text