addLabelNodes adds pseudo stack frames "label:value" to each Sample with labels matching the supplied keys. rootKeys adds frames at the root of the callgraph (first key becomes new root). leafKeys adds frames at the leaf of the callgraph (last key becomes new leaf). Returns whether there were matc
(p *profile.Profile, rootKeys, leafKeys []string, outputUnit string)
| 15 | // |
| 16 | // Returns whether there were matches found for the label keys. |
| 17 | func addLabelNodes(p *profile.Profile, rootKeys, leafKeys []string, outputUnit string) (rootm, leafm bool) { |
| 18 | // Find where to insert the new locations and functions at the end of |
| 19 | // their ID spaces. |
| 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 | // Intern the new locations and functions we are generating. |
| 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 | // Loop backwards, ensuring the first tag is closest to the root, |
| 74 | // and the last tag is closest to the leaves. |
searching dependent graphs…