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