podman

Форк
0
567 строк · 16.3 Кб
1
// Copyright 2014 Google Inc. All Rights Reserved.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
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
// preEncode populates the unexported fields to be used by encode
27
// (with suffix X) from the corresponding exported fields. The
28
// exported fields are cleared up to facilitate testing.
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, // 0
162
	// repeated ValueType sample_type = 1
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
	// repeated Sample sample = 2
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
	// repeated Mapping mapping = 3
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
	// repeated Location location = 4
184
	func(b *buffer, m message) error {
185
		x := new(Location)
186
		x.Line = make([]Line, 0, 8) // Pre-allocate Line buffer
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...) // Shrink to allocated size
192
		return err
193
	},
194
	// repeated Function function = 5
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
	// repeated string string_table = 6
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
	// int64 drop_frames = 7
213
	func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).dropFramesX) },
214
	// int64 keep_frames = 8
215
	func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).keepFramesX) },
216
	// int64 time_nanos = 9
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
	// int64 duration_nanos = 10
224
	func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).DurationNanos) },
225
	// ValueType period_type = 11
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
	// int64 period = 12
233
	func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).Period) },
234
	// repeated int64 comment = 13
235
	func(b *buffer, m message) error { return decodeInt64s(b, &m.(*Profile).commentX) },
236
	// int64 defaultSampleType = 14
237
	func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).defaultSampleTypeX) },
238
}
239

240
// postDecode takes the unexported fields populated by decode (with
241
// suffix X) and populates the corresponding exported fields.
242
// The unexported fields are cleared up to facilitate testing.
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
// padStringArray pads arr with enough empty strings to make arr
371
// length l when arr's length is less than l.
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, // 0
390
	// optional int64 type = 1
391
	func(b *buffer, m message) error { return decodeInt64(b, &m.(*ValueType).typeX) },
392
	// optional int64 unit = 2
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, // 0
410
	// repeated uint64 location = 1
411
	func(b *buffer, m message) error { return decodeUint64s(b, &m.(*Sample).locationIDX) },
412
	// repeated int64 value = 2
413
	func(b *buffer, m message) error { return decodeInt64s(b, &m.(*Sample).Value) },
414
	// repeated Label label = 3
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, // 0
436
	// optional int64 key = 1
437
	func(b *buffer, m message) error { return decodeInt64(b, &m.(*label).keyX) },
438
	// optional int64 str = 2
439
	func(b *buffer, m message) error { return decodeInt64(b, &m.(*label).strX) },
440
	// optional int64 num = 3
441
	func(b *buffer, m message) error { return decodeInt64(b, &m.(*label).numX) },
442
	// optional int64 num = 4
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, // 0
465
	func(b *buffer, m message) error { return decodeUint64(b, &m.(*Mapping).ID) },            // optional uint64 id = 1
466
	func(b *buffer, m message) error { return decodeUint64(b, &m.(*Mapping).Start) },         // optional uint64 memory_offset = 2
467
	func(b *buffer, m message) error { return decodeUint64(b, &m.(*Mapping).Limit) },         // optional uint64 memory_limit = 3
468
	func(b *buffer, m message) error { return decodeUint64(b, &m.(*Mapping).Offset) },        // optional uint64 file_offset = 4
469
	func(b *buffer, m message) error { return decodeInt64(b, &m.(*Mapping).fileX) },          // optional int64 filename = 5
470
	func(b *buffer, m message) error { return decodeInt64(b, &m.(*Mapping).buildIDX) },       // optional int64 build_id = 6
471
	func(b *buffer, m message) error { return decodeBool(b, &m.(*Mapping).HasFunctions) },    // optional bool has_functions = 7
472
	func(b *buffer, m message) error { return decodeBool(b, &m.(*Mapping).HasFilenames) },    // optional bool has_filenames = 8
473
	func(b *buffer, m message) error { return decodeBool(b, &m.(*Mapping).HasLineNumbers) },  // optional bool has_line_numbers = 9
474
	func(b *buffer, m message) error { return decodeBool(b, &m.(*Mapping).HasInlineFrames) }, // optional bool has_inline_frames = 10
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, // 0
493
	func(b *buffer, m message) error { return decodeUint64(b, &m.(*Location).ID) },         // optional uint64 id = 1;
494
	func(b *buffer, m message) error { return decodeUint64(b, &m.(*Location).mappingIDX) }, // optional uint64 mapping_id = 2;
495
	func(b *buffer, m message) error { return decodeUint64(b, &m.(*Location).Address) },    // optional uint64 address = 3;
496
	func(b *buffer, m message) error { // repeated Line line = 4
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) }, // optional bool is_folded = 5;
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, // 0
516
	// optional uint64 function_id = 1
517
	func(b *buffer, m message) error { return decodeUint64(b, &m.(*Line).functionIDX) },
518
	// optional int64 line = 2
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, // 0
536
	// optional uint64 id = 1
537
	func(b *buffer, m message) error { return decodeUint64(b, &m.(*Function).ID) },
538
	// optional int64 function_name = 2
539
	func(b *buffer, m message) error { return decodeInt64(b, &m.(*Function).nameX) },
540
	// optional int64 function_system_name = 3
541
	func(b *buffer, m message) error { return decodeInt64(b, &m.(*Function).systemNameX) },
542
	// repeated int64 filename = 4
543
	func(b *buffer, m message) error { return decodeInt64(b, &m.(*Function).filenameX) },
544
	// optional int64 start_line = 5
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

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.