1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package profile
16
17 import (
18 "errors"
19 "sort"
20 )
21
22 func (p *Profile) decoder() []decoder {
23 return profileDecoder
24 }
25
26
27
28
29 func (p *Profile) preEncode() {
30 strings := make(map[string]int)
31 addString(strings, "")
32
33 for _, st := range p.SampleType {
34 st.typeX = addString(strings, st.Type)
35 st.unitX = addString(strings, st.Unit)
36 }
37
38 for _, s := range p.Sample {
39 s.labelX = nil
40 var keys []string
41 for k := range s.Label {
42 keys = append(keys, k)
43 }
44 sort.Strings(keys)
45 for _, k := range keys {
46 vs := s.Label[k]
47 for _, v := range vs {
48 s.labelX = append(s.labelX,
49 label{
50 keyX: addString(strings, k),
51 strX: addString(strings, v),
52 },
53 )
54 }
55 }
56 var numKeys []string
57 for k := range s.NumLabel {
58 numKeys = append(numKeys, k)
59 }
60 sort.Strings(numKeys)
61 for _, k := range numKeys {
62 keyX := addString(strings, k)
63 vs := s.NumLabel[k]
64 units := s.NumUnit[k]
65 for i, v := range vs {
66 var unitX int64
67 if len(units) != 0 {
68 unitX = addString(strings, units[i])
69 }
70 s.labelX = append(s.labelX,
71 label{
72 keyX: keyX,
73 numX: v,
74 unitX: unitX,
75 },
76 )
77 }
78 }
79 s.locationIDX = make([]uint64, len(s.Location))
80 for i, loc := range s.Location {
81 s.locationIDX[i] = loc.ID
82 }
83 }
84
85 for _, m := range p.Mapping {
86 m.fileX = addString(strings, m.File)
87 m.buildIDX = addString(strings, m.BuildID)
88 }
89
90 for _, l := range p.Location {
91 for i, ln := range l.Line {
92 if ln.Function != nil {
93 l.Line[i].functionIDX = ln.Function.ID
94 } else {
95 l.Line[i].functionIDX = 0
96 }
97 }
98 if l.Mapping != nil {
99 l.mappingIDX = l.Mapping.ID
100 } else {
101 l.mappingIDX = 0
102 }
103 }
104 for _, f := range p.Function {
105 f.nameX = addString(strings, f.Name)
106 f.systemNameX = addString(strings, f.SystemName)
107 f.filenameX = addString(strings, f.Filename)
108 }
109
110 p.dropFramesX = addString(strings, p.DropFrames)
111 p.keepFramesX = addString(strings, p.KeepFrames)
112
113 if pt := p.PeriodType; pt != nil {
114 pt.typeX = addString(strings, pt.Type)
115 pt.unitX = addString(strings, pt.Unit)
116 }
117
118 p.commentX = nil
119 for _, c := range p.Comments {
120 p.commentX = append(p.commentX, addString(strings, c))
121 }
122
123 p.defaultSampleTypeX = addString(strings, p.DefaultSampleType)
124
125 p.stringTable = make([]string, len(strings))
126 for s, i := range strings {
127 p.stringTable[i] = s
128 }
129 }
130
131 func (p *Profile) encode(b *buffer) {
132 for _, x := range p.SampleType {
133 encodeMessage(b, 1, x)
134 }
135 for _, x := range p.Sample {
136 encodeMessage(b, 2, x)
137 }
138 for _, x := range p.Mapping {
139 encodeMessage(b, 3, x)
140 }
141 for _, x := range p.Location {
142 encodeMessage(b, 4, x)
143 }
144 for _, x := range p.Function {
145 encodeMessage(b, 5, x)
146 }
147 encodeStrings(b, 6, p.stringTable)
148 encodeInt64Opt(b, 7, p.dropFramesX)
149 encodeInt64Opt(b, 8, p.keepFramesX)
150 encodeInt64Opt(b, 9, p.TimeNanos)
151 encodeInt64Opt(b, 10, p.DurationNanos)
152 if pt := p.PeriodType; pt != nil && (pt.typeX != 0 || pt.unitX != 0) {
153 encodeMessage(b, 11, p.PeriodType)
154 }
155 encodeInt64Opt(b, 12, p.Period)
156 encodeInt64s(b, 13, p.commentX)
157 encodeInt64(b, 14, p.defaultSampleTypeX)
158 }
159
160 var profileDecoder = []decoder{
161 nil,
162
163 func(b *buffer, m message) error {
164 x := new(ValueType)
165 pp := m.(*Profile)
166 pp.SampleType = append(pp.SampleType, x)
167 return decodeMessage(b, x)
168 },
169
170 func(b *buffer, m message) error {
171 x := new(Sample)
172 pp := m.(*Profile)
173 pp.Sample = append(pp.Sample, x)
174 return decodeMessage(b, x)
175 },
176
177 func(b *buffer, m message) error {
178 x := new(Mapping)
179 pp := m.(*Profile)
180 pp.Mapping = append(pp.Mapping, x)
181 return decodeMessage(b, x)
182 },
183
184 func(b *buffer, m message) error {
185 x := new(Location)
186 x.Line = make([]Line, 0, 8)
187 pp := m.(*Profile)
188 pp.Location = append(pp.Location, x)
189 err := decodeMessage(b, x)
190 var tmp []Line
191 x.Line = append(tmp, x.Line...)
192 return err
193 },
194
195 func(b *buffer, m message) error {
196 x := new(Function)
197 pp := m.(*Profile)
198 pp.Function = append(pp.Function, x)
199 return decodeMessage(b, x)
200 },
201
202 func(b *buffer, m message) error {
203 err := decodeStrings(b, &m.(*Profile).stringTable)
204 if err != nil {
205 return err
206 }
207 if m.(*Profile).stringTable[0] != "" {
208 return errors.New("string_table[0] must be ''")
209 }
210 return nil
211 },
212
213 func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).dropFramesX) },
214
215 func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).keepFramesX) },
216
217 func(b *buffer, m message) error {
218 if m.(*Profile).TimeNanos != 0 {
219 return errConcatProfile
220 }
221 return decodeInt64(b, &m.(*Profile).TimeNanos)
222 },
223
224 func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).DurationNanos) },
225
226 func(b *buffer, m message) error {
227 x := new(ValueType)
228 pp := m.(*Profile)
229 pp.PeriodType = x
230 return decodeMessage(b, x)
231 },
232
233 func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).Period) },
234
235 func(b *buffer, m message) error { return decodeInt64s(b, &m.(*Profile).commentX) },
236
237 func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).defaultSampleTypeX) },
238 }
239
240
241
242
243 func (p *Profile) postDecode() error {
244 var err error
245 mappings := make(map[uint64]*Mapping, len(p.Mapping))
246 mappingIds := make([]*Mapping, len(p.Mapping)+1)
247 for _, m := range p.Mapping {
248 m.File, err = getString(p.stringTable, &m.fileX, err)
249 m.BuildID, err = getString(p.stringTable, &m.buildIDX, err)
250 if m.ID < uint64(len(mappingIds)) {
251 mappingIds[m.ID] = m
252 } else {
253 mappings[m.ID] = m
254 }
255 }
256
257 functions := make(map[uint64]*Function, len(p.Function))
258 functionIds := make([]*Function, len(p.Function)+1)
259 for _, f := range p.Function {
260 f.Name, err = getString(p.stringTable, &f.nameX, err)
261 f.SystemName, err = getString(p.stringTable, &f.systemNameX, err)
262 f.Filename, err = getString(p.stringTable, &f.filenameX, err)
263 if f.ID < uint64(len(functionIds)) {
264 functionIds[f.ID] = f
265 } else {
266 functions[f.ID] = f
267 }
268 }
269
270 locations := make(map[uint64]*Location, len(p.Location))
271 locationIds := make([]*Location, len(p.Location)+1)
272 for _, l := range p.Location {
273 if id := l.mappingIDX; id < uint64(len(mappingIds)) {
274 l.Mapping = mappingIds[id]
275 } else {
276 l.Mapping = mappings[id]
277 }
278 l.mappingIDX = 0
279 for i, ln := range l.Line {
280 if id := ln.functionIDX; id != 0 {
281 l.Line[i].functionIDX = 0
282 if id < uint64(len(functionIds)) {
283 l.Line[i].Function = functionIds[id]
284 } else {
285 l.Line[i].Function = functions[id]
286 }
287 }
288 }
289 if l.ID < uint64(len(locationIds)) {
290 locationIds[l.ID] = l
291 } else {
292 locations[l.ID] = l
293 }
294 }
295
296 for _, st := range p.SampleType {
297 st.Type, err = getString(p.stringTable, &st.typeX, err)
298 st.Unit, err = getString(p.stringTable, &st.unitX, err)
299 }
300
301 for _, s := range p.Sample {
302 labels := make(map[string][]string, len(s.labelX))
303 numLabels := make(map[string][]int64, len(s.labelX))
304 numUnits := make(map[string][]string, len(s.labelX))
305 for _, l := range s.labelX {
306 var key, value string
307 key, err = getString(p.stringTable, &l.keyX, err)
308 if l.strX != 0 {
309 value, err = getString(p.stringTable, &l.strX, err)
310 labels[key] = append(labels[key], value)
311 } else if l.numX != 0 || l.unitX != 0 {
312 numValues := numLabels[key]
313 units := numUnits[key]
314 if l.unitX != 0 {
315 var unit string
316 unit, err = getString(p.stringTable, &l.unitX, err)
317 units = padStringArray(units, len(numValues))
318 numUnits[key] = append(units, unit)
319 }
320 numLabels[key] = append(numLabels[key], l.numX)
321 }
322 }
323 if len(labels) > 0 {
324 s.Label = labels
325 }
326 if len(numLabels) > 0 {
327 s.NumLabel = numLabels
328 for key, units := range numUnits {
329 if len(units) > 0 {
330 numUnits[key] = padStringArray(units, len(numLabels[key]))
331 }
332 }
333 s.NumUnit = numUnits
334 }
335 s.Location = make([]*Location, len(s.locationIDX))
336 for i, lid := range s.locationIDX {
337 if lid < uint64(len(locationIds)) {
338 s.Location[i] = locationIds[lid]
339 } else {
340 s.Location[i] = locations[lid]
341 }
342 }
343 s.locationIDX = nil
344 }
345
346 p.DropFrames, err = getString(p.stringTable, &p.dropFramesX, err)
347 p.KeepFrames, err = getString(p.stringTable, &p.keepFramesX, err)
348
349 if pt := p.PeriodType; pt == nil {
350 p.PeriodType = &ValueType{}
351 }
352
353 if pt := p.PeriodType; pt != nil {
354 pt.Type, err = getString(p.stringTable, &pt.typeX, err)
355 pt.Unit, err = getString(p.stringTable, &pt.unitX, err)
356 }
357
358 for _, i := range p.commentX {
359 var c string
360 c, err = getString(p.stringTable, &i, err)
361 p.Comments = append(p.Comments, c)
362 }
363
364 p.commentX = nil
365 p.DefaultSampleType, err = getString(p.stringTable, &p.defaultSampleTypeX, err)
366 p.stringTable = nil
367 return err
368 }
369
370
371
372 func padStringArray(arr []string, l int) []string {
373 if l <= len(arr) {
374 return arr
375 }
376 return append(arr, make([]string, l-len(arr))...)
377 }
378
379 func (p *ValueType) decoder() []decoder {
380 return valueTypeDecoder
381 }
382
383 func (p *ValueType) encode(b *buffer) {
384 encodeInt64Opt(b, 1, p.typeX)
385 encodeInt64Opt(b, 2, p.unitX)
386 }
387
388 var valueTypeDecoder = []decoder{
389 nil,
390
391 func(b *buffer, m message) error { return decodeInt64(b, &m.(*ValueType).typeX) },
392
393 func(b *buffer, m message) error { return decodeInt64(b, &m.(*ValueType).unitX) },
394 }
395
396 func (p *Sample) decoder() []decoder {
397 return sampleDecoder
398 }
399
400 func (p *Sample) encode(b *buffer) {
401 encodeUint64s(b, 1, p.locationIDX)
402 encodeInt64s(b, 2, p.Value)
403 for _, x := range p.labelX {
404 encodeMessage(b, 3, x)
405 }
406 }
407
408 var sampleDecoder = []decoder{
409 nil,
410
411 func(b *buffer, m message) error { return decodeUint64s(b, &m.(*Sample).locationIDX) },
412
413 func(b *buffer, m message) error { return decodeInt64s(b, &m.(*Sample).Value) },
414
415 func(b *buffer, m message) error {
416 s := m.(*Sample)
417 n := len(s.labelX)
418 s.labelX = append(s.labelX, label{})
419 return decodeMessage(b, &s.labelX[n])
420 },
421 }
422
423 func (p label) decoder() []decoder {
424 return labelDecoder
425 }
426
427 func (p label) encode(b *buffer) {
428 encodeInt64Opt(b, 1, p.keyX)
429 encodeInt64Opt(b, 2, p.strX)
430 encodeInt64Opt(b, 3, p.numX)
431 encodeInt64Opt(b, 4, p.unitX)
432 }
433
434 var labelDecoder = []decoder{
435 nil,
436
437 func(b *buffer, m message) error { return decodeInt64(b, &m.(*label).keyX) },
438
439 func(b *buffer, m message) error { return decodeInt64(b, &m.(*label).strX) },
440
441 func(b *buffer, m message) error { return decodeInt64(b, &m.(*label).numX) },
442
443 func(b *buffer, m message) error { return decodeInt64(b, &m.(*label).unitX) },
444 }
445
446 func (p *Mapping) decoder() []decoder {
447 return mappingDecoder
448 }
449
450 func (p *Mapping) encode(b *buffer) {
451 encodeUint64Opt(b, 1, p.ID)
452 encodeUint64Opt(b, 2, p.Start)
453 encodeUint64Opt(b, 3, p.Limit)
454 encodeUint64Opt(b, 4, p.Offset)
455 encodeInt64Opt(b, 5, p.fileX)
456 encodeInt64Opt(b, 6, p.buildIDX)
457 encodeBoolOpt(b, 7, p.HasFunctions)
458 encodeBoolOpt(b, 8, p.HasFilenames)
459 encodeBoolOpt(b, 9, p.HasLineNumbers)
460 encodeBoolOpt(b, 10, p.HasInlineFrames)
461 }
462
463 var mappingDecoder = []decoder{
464 nil,
465 func(b *buffer, m message) error { return decodeUint64(b, &m.(*Mapping).ID) },
466 func(b *buffer, m message) error { return decodeUint64(b, &m.(*Mapping).Start) },
467 func(b *buffer, m message) error { return decodeUint64(b, &m.(*Mapping).Limit) },
468 func(b *buffer, m message) error { return decodeUint64(b, &m.(*Mapping).Offset) },
469 func(b *buffer, m message) error { return decodeInt64(b, &m.(*Mapping).fileX) },
470 func(b *buffer, m message) error { return decodeInt64(b, &m.(*Mapping).buildIDX) },
471 func(b *buffer, m message) error { return decodeBool(b, &m.(*Mapping).HasFunctions) },
472 func(b *buffer, m message) error { return decodeBool(b, &m.(*Mapping).HasFilenames) },
473 func(b *buffer, m message) error { return decodeBool(b, &m.(*Mapping).HasLineNumbers) },
474 func(b *buffer, m message) error { return decodeBool(b, &m.(*Mapping).HasInlineFrames) },
475 }
476
477 func (p *Location) decoder() []decoder {
478 return locationDecoder
479 }
480
481 func (p *Location) encode(b *buffer) {
482 encodeUint64Opt(b, 1, p.ID)
483 encodeUint64Opt(b, 2, p.mappingIDX)
484 encodeUint64Opt(b, 3, p.Address)
485 for i := range p.Line {
486 encodeMessage(b, 4, &p.Line[i])
487 }
488 encodeBoolOpt(b, 5, p.IsFolded)
489 }
490
491 var locationDecoder = []decoder{
492 nil,
493 func(b *buffer, m message) error { return decodeUint64(b, &m.(*Location).ID) },
494 func(b *buffer, m message) error { return decodeUint64(b, &m.(*Location).mappingIDX) },
495 func(b *buffer, m message) error { return decodeUint64(b, &m.(*Location).Address) },
496 func(b *buffer, m message) error {
497 pp := m.(*Location)
498 n := len(pp.Line)
499 pp.Line = append(pp.Line, Line{})
500 return decodeMessage(b, &pp.Line[n])
501 },
502 func(b *buffer, m message) error { return decodeBool(b, &m.(*Location).IsFolded) },
503 }
504
505 func (p *Line) decoder() []decoder {
506 return lineDecoder
507 }
508
509 func (p *Line) encode(b *buffer) {
510 encodeUint64Opt(b, 1, p.functionIDX)
511 encodeInt64Opt(b, 2, p.Line)
512 }
513
514 var lineDecoder = []decoder{
515 nil,
516
517 func(b *buffer, m message) error { return decodeUint64(b, &m.(*Line).functionIDX) },
518
519 func(b *buffer, m message) error { return decodeInt64(b, &m.(*Line).Line) },
520 }
521
522 func (p *Function) decoder() []decoder {
523 return functionDecoder
524 }
525
526 func (p *Function) encode(b *buffer) {
527 encodeUint64Opt(b, 1, p.ID)
528 encodeInt64Opt(b, 2, p.nameX)
529 encodeInt64Opt(b, 3, p.systemNameX)
530 encodeInt64Opt(b, 4, p.filenameX)
531 encodeInt64Opt(b, 5, p.StartLine)
532 }
533
534 var functionDecoder = []decoder{
535 nil,
536
537 func(b *buffer, m message) error { return decodeUint64(b, &m.(*Function).ID) },
538
539 func(b *buffer, m message) error { return decodeInt64(b, &m.(*Function).nameX) },
540
541 func(b *buffer, m message) error { return decodeInt64(b, &m.(*Function).systemNameX) },
542
543 func(b *buffer, m message) error { return decodeInt64(b, &m.(*Function).filenameX) },
544
545 func(b *buffer, m message) error { return decodeInt64(b, &m.(*Function).StartLine) },
546 }
547
548 func addString(strings map[string]int, s string) int64 {
549 i, ok := strings[s]
550 if !ok {
551 i = len(strings)
552 strings[s] = i
553 }
554 return int64(i)
555 }
556
557 func getString(strings []string, strng *int64, err error) (string, error) {
558 if err != nil {
559 return "", err
560 }
561 s := int(*strng)
562 if s < 0 || s >= len(strings) {
563 return "", errMalformed
564 }
565 *strng = 0
566 return strings[s], nil
567 }
568
View as plain text