1
2
3
4
5
6
7 package profile
8
9 import "regexp"
10
11
12
13
14 func (p *Profile) FilterSamplesByName(focus, ignore, hide *regexp.Regexp) (fm, im, hm bool) {
15 focusOrIgnore := make(map[uint64]bool)
16 hidden := make(map[uint64]bool)
17 for _, l := range p.Location {
18 if ignore != nil && l.matchesName(ignore) {
19 im = true
20 focusOrIgnore[l.ID] = false
21 } else if focus == nil || l.matchesName(focus) {
22 fm = true
23 focusOrIgnore[l.ID] = true
24 }
25 if hide != nil && l.matchesName(hide) {
26 hm = true
27 l.Line = l.unmatchedLines(hide)
28 if len(l.Line) == 0 {
29 hidden[l.ID] = true
30 }
31 }
32 }
33
34 s := make([]*Sample, 0, len(p.Sample))
35 for _, sample := range p.Sample {
36 if focusedAndNotIgnored(sample.Location, focusOrIgnore) {
37 if len(hidden) > 0 {
38 var locs []*Location
39 for _, loc := range sample.Location {
40 if !hidden[loc.ID] {
41 locs = append(locs, loc)
42 }
43 }
44 if len(locs) == 0 {
45
46 continue
47 }
48 sample.Location = locs
49 }
50 s = append(s, sample)
51 }
52 }
53 p.Sample = s
54
55 return
56 }
57
58
59
60 func (loc *Location) matchesName(re *regexp.Regexp) bool {
61 for _, ln := range loc.Line {
62 if fn := ln.Function; fn != nil {
63 if re.MatchString(fn.Name) {
64 return true
65 }
66 if re.MatchString(fn.Filename) {
67 return true
68 }
69 }
70 }
71 return false
72 }
73
74
75
76 func (loc *Location) unmatchedLines(re *regexp.Regexp) []Line {
77 var lines []Line
78 for _, ln := range loc.Line {
79 if fn := ln.Function; fn != nil {
80 if re.MatchString(fn.Name) {
81 continue
82 }
83 if re.MatchString(fn.Filename) {
84 continue
85 }
86 }
87 lines = append(lines, ln)
88 }
89 return lines
90 }
91
92
93
94
95
96 func focusedAndNotIgnored(locs []*Location, m map[uint64]bool) bool {
97 var f bool
98 for _, loc := range locs {
99 if focus, focusOrIgnore := m[loc.ID]; focusOrIgnore {
100 if focus {
101
102
103 f = true
104 } else {
105
106 return false
107 }
108 }
109 }
110 return f
111 }
112
113
114 type TagMatch func(key, val string, nval int64) bool
115
116
117
118
119 func (p *Profile) FilterSamplesByTag(focus, ignore TagMatch) (fm, im bool) {
120 samples := make([]*Sample, 0, len(p.Sample))
121 for _, s := range p.Sample {
122 focused, ignored := focusedSample(s, focus, ignore)
123 fm = fm || focused
124 im = im || ignored
125 if focused && !ignored {
126 samples = append(samples, s)
127 }
128 }
129 p.Sample = samples
130 return
131 }
132
133
134
135 func focusedSample(s *Sample, focus, ignore TagMatch) (fm, im bool) {
136 fm = focus == nil
137 for key, vals := range s.Label {
138 for _, val := range vals {
139 if ignore != nil && ignore(key, val, 0) {
140 im = true
141 }
142 if !fm && focus(key, val, 0) {
143 fm = true
144 }
145 }
146 }
147 for key, vals := range s.NumLabel {
148 for _, val := range vals {
149 if ignore != nil && ignore(key, "", val) {
150 im = true
151 }
152 if !fm && focus(key, "", val) {
153 fm = true
154 }
155 }
156 }
157 return fm, im
158 }
159
View as plain text