parseJavaSamples parses the samples from a java profile and populates the Samples in a profile. Returns the remainder of the buffer after the samples.
(pType string, b []byte, p *Profile)
| 165 | // populates the Samples in a profile. Returns the remainder of the |
| 166 | // buffer after the samples. |
| 167 | func parseJavaSamples(pType string, b []byte, p *Profile) ([]byte, map[uint64]*Location, error) { |
| 168 | nextNewLine := bytes.IndexByte(b, byte('\n')) |
| 169 | locs := make(map[uint64]*Location) |
| 170 | for nextNewLine != -1 { |
| 171 | line := string(bytes.TrimSpace(b[0:nextNewLine])) |
| 172 | if line != "" { |
| 173 | sample := javaSampleRx.FindStringSubmatch(line) |
| 174 | if sample == nil { |
| 175 | // Not a valid sample, exit. |
| 176 | return b, locs, nil |
| 177 | } |
| 178 | |
| 179 | // Java profiles have data/fields inverted compared to other |
| 180 | // profile types. |
| 181 | var err error |
| 182 | value1, value2, value3 := sample[2], sample[1], sample[3] |
| 183 | addrs, err := parseHexAddresses(value3) |
| 184 | if err != nil { |
| 185 | return nil, nil, fmt.Errorf("malformed sample: %s: %v", line, err) |
| 186 | } |
| 187 | |
| 188 | var sloc []*Location |
| 189 | for _, addr := range addrs { |
| 190 | loc := locs[addr] |
| 191 | if locs[addr] == nil { |
| 192 | loc = &Location{ |
| 193 | Address: addr, |
| 194 | } |
| 195 | p.Location = append(p.Location, loc) |
| 196 | locs[addr] = loc |
| 197 | } |
| 198 | sloc = append(sloc, loc) |
| 199 | } |
| 200 | s := &Sample{ |
| 201 | Value: make([]int64, 2), |
| 202 | Location: sloc, |
| 203 | } |
| 204 | |
| 205 | if s.Value[0], err = strconv.ParseInt(value1, 0, 64); err != nil { |
| 206 | return nil, nil, fmt.Errorf("parsing sample %s: %v", line, err) |
| 207 | } |
| 208 | if s.Value[1], err = strconv.ParseInt(value2, 0, 64); err != nil { |
| 209 | return nil, nil, fmt.Errorf("parsing sample %s: %v", line, err) |
| 210 | } |
| 211 | |
| 212 | switch pType { |
| 213 | case "heap": |
| 214 | const javaHeapzSamplingRate = 524288 // 512K |
| 215 | if s.Value[0] == 0 { |
| 216 | return nil, nil, fmt.Errorf("parsing sample %s: second value must be non-zero", line) |
| 217 | } |
| 218 | s.NumLabel = map[string][]int64{"bytes": {s.Value[1] / s.Value[0]}} |
| 219 | s.Value[0], s.Value[1] = scaleHeapSample(s.Value[0], s.Value[1], javaHeapzSamplingRate) |
| 220 | case "contention": |
| 221 | if period := p.Period; period != 0 { |
| 222 | s.Value[0] = s.Value[0] * p.Period |
| 223 | s.Value[1] = s.Value[1] * p.Period |
| 224 | } |
no test coverage detected
searching dependent graphs…