...
1 package driver
2
3 import (
4 "strings"
5
6 "github.com/google/pprof/internal/measurement"
7 "github.com/google/pprof/profile"
8 )
9
10
11
12
13
14
15
16
17 func addLabelNodes(p *profile.Profile, rootKeys, leafKeys []string, outputUnit string) (rootm, leafm bool) {
18
19
20 var maxLocID uint64
21 var maxFunctionID uint64
22 for _, loc := range p.Location {
23 if loc.ID > maxLocID {
24 maxLocID = loc.ID
25 }
26 }
27 for _, f := range p.Function {
28 if f.ID > maxFunctionID {
29 maxFunctionID = f.ID
30 }
31 }
32 nextLocID := maxLocID + 1
33 nextFuncID := maxFunctionID + 1
34
35
36 type locKey struct {
37 functionName, fileName string
38 }
39 locs := map[locKey]*profile.Location{}
40
41 internLoc := func(locKey locKey) *profile.Location {
42 loc, found := locs[locKey]
43 if found {
44 return loc
45 }
46
47 function := &profile.Function{
48 ID: nextFuncID,
49 Name: locKey.functionName,
50 Filename: locKey.fileName,
51 }
52 nextFuncID++
53 p.Function = append(p.Function, function)
54
55 loc = &profile.Location{
56 ID: nextLocID,
57 Line: []profile.Line{
58 {
59 Function: function,
60 },
61 },
62 }
63 nextLocID++
64 p.Location = append(p.Location, loc)
65 locs[locKey] = loc
66 return loc
67 }
68
69 makeLabelLocs := func(s *profile.Sample, keys []string) ([]*profile.Location, bool) {
70 var locs []*profile.Location
71 var match bool
72 for i := range keys {
73
74
75 k := keys[len(keys)-1-i]
76 values := formatLabelValues(s, k, outputUnit)
77 if len(values) > 0 {
78 match = true
79 }
80 locKey := locKey{
81 functionName: strings.Join(values, ","),
82 fileName: k,
83 }
84 loc := internLoc(locKey)
85 locs = append(locs, loc)
86 }
87 return locs, match
88 }
89
90 for _, s := range p.Sample {
91 rootsToAdd, sampleMatchedRoot := makeLabelLocs(s, rootKeys)
92 if sampleMatchedRoot {
93 rootm = true
94 }
95 leavesToAdd, sampleMatchedLeaf := makeLabelLocs(s, leafKeys)
96 if sampleMatchedLeaf {
97 leafm = true
98 }
99
100 if len(leavesToAdd)+len(rootsToAdd) == 0 {
101 continue
102 }
103
104 var newLocs []*profile.Location
105 newLocs = append(newLocs, leavesToAdd...)
106 newLocs = append(newLocs, s.Location...)
107 newLocs = append(newLocs, rootsToAdd...)
108 s.Location = newLocs
109 }
110 return
111 }
112
113
114
115 func formatLabelValues(s *profile.Sample, k string, outputUnit string) []string {
116 var values []string
117 values = append(values, s.Label[k]...)
118 numLabels := s.NumLabel[k]
119 numUnits := s.NumUnit[k]
120 if len(numLabels) != len(numUnits) && len(numUnits) != 0 {
121 return values
122 }
123 for i, numLabel := range numLabels {
124 var value string
125 if len(numUnits) != 0 {
126 value = measurement.ScaledLabel(numLabel, numUnits[i], outputUnit)
127 } else {
128 value = measurement.ScaledLabel(numLabel, "", "")
129 }
130 values = append(values, value)
131 }
132 return values
133 }
134
View as plain text