golang.org/toolchain@v0.0.1-go1.9rc2.windows-amd64/src/cmd/vendor/github.com/google/pprof/profile/encode.go (about)

     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  			vs := s.NumLabel[k]
    63  			for _, v := range vs {
    64  				s.labelX = append(s.labelX,
    65  					label{
    66  						keyX: addString(strings, k),
    67  						numX: v,
    68  					},
    69  				)
    70  			}
    71  		}
    72  		s.locationIDX = make([]uint64, len(s.Location))
    73  		for i, loc := range s.Location {
    74  			s.locationIDX[i] = loc.ID
    75  		}
    76  	}
    77  
    78  	for _, m := range p.Mapping {
    79  		m.fileX = addString(strings, m.File)
    80  		m.buildIDX = addString(strings, m.BuildID)
    81  	}
    82  
    83  	for _, l := range p.Location {
    84  		for i, ln := range l.Line {
    85  			if ln.Function != nil {
    86  				l.Line[i].functionIDX = ln.Function.ID
    87  			} else {
    88  				l.Line[i].functionIDX = 0
    89  			}
    90  		}
    91  		if l.Mapping != nil {
    92  			l.mappingIDX = l.Mapping.ID
    93  		} else {
    94  			l.mappingIDX = 0
    95  		}
    96  	}
    97  	for _, f := range p.Function {
    98  		f.nameX = addString(strings, f.Name)
    99  		f.systemNameX = addString(strings, f.SystemName)
   100  		f.filenameX = addString(strings, f.Filename)
   101  	}
   102  
   103  	p.dropFramesX = addString(strings, p.DropFrames)
   104  	p.keepFramesX = addString(strings, p.KeepFrames)
   105  
   106  	if pt := p.PeriodType; pt != nil {
   107  		pt.typeX = addString(strings, pt.Type)
   108  		pt.unitX = addString(strings, pt.Unit)
   109  	}
   110  
   111  	p.commentX = nil
   112  	for _, c := range p.Comments {
   113  		p.commentX = append(p.commentX, addString(strings, c))
   114  	}
   115  
   116  	p.defaultSampleTypeX = addString(strings, p.DefaultSampleType)
   117  
   118  	p.stringTable = make([]string, len(strings))
   119  	for s, i := range strings {
   120  		p.stringTable[i] = s
   121  	}
   122  }
   123  
   124  func (p *Profile) encode(b *buffer) {
   125  	for _, x := range p.SampleType {
   126  		encodeMessage(b, 1, x)
   127  	}
   128  	for _, x := range p.Sample {
   129  		encodeMessage(b, 2, x)
   130  	}
   131  	for _, x := range p.Mapping {
   132  		encodeMessage(b, 3, x)
   133  	}
   134  	for _, x := range p.Location {
   135  		encodeMessage(b, 4, x)
   136  	}
   137  	for _, x := range p.Function {
   138  		encodeMessage(b, 5, x)
   139  	}
   140  	encodeStrings(b, 6, p.stringTable)
   141  	encodeInt64Opt(b, 7, p.dropFramesX)
   142  	encodeInt64Opt(b, 8, p.keepFramesX)
   143  	encodeInt64Opt(b, 9, p.TimeNanos)
   144  	encodeInt64Opt(b, 10, p.DurationNanos)
   145  	if pt := p.PeriodType; pt != nil && (pt.typeX != 0 || pt.unitX != 0) {
   146  		encodeMessage(b, 11, p.PeriodType)
   147  	}
   148  	encodeInt64Opt(b, 12, p.Period)
   149  	encodeInt64s(b, 13, p.commentX)
   150  	encodeInt64(b, 14, p.defaultSampleTypeX)
   151  }
   152  
   153  var profileDecoder = []decoder{
   154  	nil, // 0
   155  	// repeated ValueType sample_type = 1
   156  	func(b *buffer, m message) error {
   157  		x := new(ValueType)
   158  		pp := m.(*Profile)
   159  		pp.SampleType = append(pp.SampleType, x)
   160  		return decodeMessage(b, x)
   161  	},
   162  	// repeated Sample sample = 2
   163  	func(b *buffer, m message) error {
   164  		x := new(Sample)
   165  		pp := m.(*Profile)
   166  		pp.Sample = append(pp.Sample, x)
   167  		return decodeMessage(b, x)
   168  	},
   169  	// repeated Mapping mapping = 3
   170  	func(b *buffer, m message) error {
   171  		x := new(Mapping)
   172  		pp := m.(*Profile)
   173  		pp.Mapping = append(pp.Mapping, x)
   174  		return decodeMessage(b, x)
   175  	},
   176  	// repeated Location location = 4
   177  	func(b *buffer, m message) error {
   178  		x := new(Location)
   179  		x.Line = make([]Line, 0, 8) // Pre-allocate Line buffer
   180  		pp := m.(*Profile)
   181  		pp.Location = append(pp.Location, x)
   182  		err := decodeMessage(b, x)
   183  		var tmp []Line
   184  		x.Line = append(tmp, x.Line...) // Shrink to allocated size
   185  		return err
   186  	},
   187  	// repeated Function function = 5
   188  	func(b *buffer, m message) error {
   189  		x := new(Function)
   190  		pp := m.(*Profile)
   191  		pp.Function = append(pp.Function, x)
   192  		return decodeMessage(b, x)
   193  	},
   194  	// repeated string string_table = 6
   195  	func(b *buffer, m message) error {
   196  		err := decodeStrings(b, &m.(*Profile).stringTable)
   197  		if err != nil {
   198  			return err
   199  		}
   200  		if m.(*Profile).stringTable[0] != "" {
   201  			return errors.New("string_table[0] must be ''")
   202  		}
   203  		return nil
   204  	},
   205  	// int64 drop_frames = 7
   206  	func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).dropFramesX) },
   207  	// int64 keep_frames = 8
   208  	func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).keepFramesX) },
   209  	// int64 time_nanos = 9
   210  	func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).TimeNanos) },
   211  	// int64 duration_nanos = 10
   212  	func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).DurationNanos) },
   213  	// ValueType period_type = 11
   214  	func(b *buffer, m message) error {
   215  		x := new(ValueType)
   216  		pp := m.(*Profile)
   217  		pp.PeriodType = x
   218  		return decodeMessage(b, x)
   219  	},
   220  	// int64 period = 12
   221  	func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).Period) },
   222  	// repeated int64 comment = 13
   223  	func(b *buffer, m message) error { return decodeInt64s(b, &m.(*Profile).commentX) },
   224  	// int64 defaultSampleType = 14
   225  	func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).defaultSampleTypeX) },
   226  }
   227  
   228  // postDecode takes the unexported fields populated by decode (with
   229  // suffix X) and populates the corresponding exported fields.
   230  // The unexported fields are cleared up to facilitate testing.
   231  func (p *Profile) postDecode() error {
   232  	var err error
   233  	mappings := make(map[uint64]*Mapping, len(p.Mapping))
   234  	mappingIds := make([]*Mapping, len(p.Mapping)+1)
   235  	for _, m := range p.Mapping {
   236  		m.File, err = getString(p.stringTable, &m.fileX, err)
   237  		m.BuildID, err = getString(p.stringTable, &m.buildIDX, err)
   238  		if m.ID < uint64(len(mappingIds)) {
   239  			mappingIds[m.ID] = m
   240  		} else {
   241  			mappings[m.ID] = m
   242  		}
   243  	}
   244  
   245  	functions := make(map[uint64]*Function, len(p.Function))
   246  	functionIds := make([]*Function, len(p.Function)+1)
   247  	for _, f := range p.Function {
   248  		f.Name, err = getString(p.stringTable, &f.nameX, err)
   249  		f.SystemName, err = getString(p.stringTable, &f.systemNameX, err)
   250  		f.Filename, err = getString(p.stringTable, &f.filenameX, err)
   251  		if f.ID < uint64(len(functionIds)) {
   252  			functionIds[f.ID] = f
   253  		} else {
   254  			functions[f.ID] = f
   255  		}
   256  	}
   257  
   258  	locations := make(map[uint64]*Location, len(p.Location))
   259  	locationIds := make([]*Location, len(p.Location)+1)
   260  	for _, l := range p.Location {
   261  		if id := l.mappingIDX; id < uint64(len(mappingIds)) {
   262  			l.Mapping = mappingIds[id]
   263  		} else {
   264  			l.Mapping = mappings[id]
   265  		}
   266  		l.mappingIDX = 0
   267  		for i, ln := range l.Line {
   268  			if id := ln.functionIDX; id != 0 {
   269  				l.Line[i].functionIDX = 0
   270  				if id < uint64(len(functionIds)) {
   271  					l.Line[i].Function = functionIds[id]
   272  				} else {
   273  					l.Line[i].Function = functions[id]
   274  				}
   275  			}
   276  		}
   277  		if l.ID < uint64(len(locationIds)) {
   278  			locationIds[l.ID] = l
   279  		} else {
   280  			locations[l.ID] = l
   281  		}
   282  	}
   283  
   284  	for _, st := range p.SampleType {
   285  		st.Type, err = getString(p.stringTable, &st.typeX, err)
   286  		st.Unit, err = getString(p.stringTable, &st.unitX, err)
   287  	}
   288  
   289  	for _, s := range p.Sample {
   290  		labels := make(map[string][]string, len(s.labelX))
   291  		numLabels := make(map[string][]int64, len(s.labelX))
   292  		for _, l := range s.labelX {
   293  			var key, value string
   294  			key, err = getString(p.stringTable, &l.keyX, err)
   295  			if l.strX != 0 {
   296  				value, err = getString(p.stringTable, &l.strX, err)
   297  				labels[key] = append(labels[key], value)
   298  			} else if l.numX != 0 {
   299  				numLabels[key] = append(numLabels[key], l.numX)
   300  			}
   301  		}
   302  		if len(labels) > 0 {
   303  			s.Label = labels
   304  		}
   305  		if len(numLabels) > 0 {
   306  			s.NumLabel = numLabels
   307  		}
   308  		s.Location = make([]*Location, len(s.locationIDX))
   309  		for i, lid := range s.locationIDX {
   310  			if lid < uint64(len(locationIds)) {
   311  				s.Location[i] = locationIds[lid]
   312  			} else {
   313  				s.Location[i] = locations[lid]
   314  			}
   315  		}
   316  		s.locationIDX = nil
   317  	}
   318  
   319  	p.DropFrames, err = getString(p.stringTable, &p.dropFramesX, err)
   320  	p.KeepFrames, err = getString(p.stringTable, &p.keepFramesX, err)
   321  
   322  	if pt := p.PeriodType; pt == nil {
   323  		p.PeriodType = &ValueType{}
   324  	}
   325  
   326  	if pt := p.PeriodType; pt != nil {
   327  		pt.Type, err = getString(p.stringTable, &pt.typeX, err)
   328  		pt.Unit, err = getString(p.stringTable, &pt.unitX, err)
   329  	}
   330  
   331  	for _, i := range p.commentX {
   332  		var c string
   333  		c, err = getString(p.stringTable, &i, err)
   334  		p.Comments = append(p.Comments, c)
   335  	}
   336  
   337  	p.commentX = nil
   338  	p.DefaultSampleType, err = getString(p.stringTable, &p.defaultSampleTypeX, err)
   339  	p.stringTable = nil
   340  	return err
   341  }
   342  
   343  func (p *ValueType) decoder() []decoder {
   344  	return valueTypeDecoder
   345  }
   346  
   347  func (p *ValueType) encode(b *buffer) {
   348  	encodeInt64Opt(b, 1, p.typeX)
   349  	encodeInt64Opt(b, 2, p.unitX)
   350  }
   351  
   352  var valueTypeDecoder = []decoder{
   353  	nil, // 0
   354  	// optional int64 type = 1
   355  	func(b *buffer, m message) error { return decodeInt64(b, &m.(*ValueType).typeX) },
   356  	// optional int64 unit = 2
   357  	func(b *buffer, m message) error { return decodeInt64(b, &m.(*ValueType).unitX) },
   358  }
   359  
   360  func (p *Sample) decoder() []decoder {
   361  	return sampleDecoder
   362  }
   363  
   364  func (p *Sample) encode(b *buffer) {
   365  	encodeUint64s(b, 1, p.locationIDX)
   366  	encodeInt64s(b, 2, p.Value)
   367  	for _, x := range p.labelX {
   368  		encodeMessage(b, 3, x)
   369  	}
   370  }
   371  
   372  var sampleDecoder = []decoder{
   373  	nil, // 0
   374  	// repeated uint64 location = 1
   375  	func(b *buffer, m message) error { return decodeUint64s(b, &m.(*Sample).locationIDX) },
   376  	// repeated int64 value = 2
   377  	func(b *buffer, m message) error { return decodeInt64s(b, &m.(*Sample).Value) },
   378  	// repeated Label label = 3
   379  	func(b *buffer, m message) error {
   380  		s := m.(*Sample)
   381  		n := len(s.labelX)
   382  		s.labelX = append(s.labelX, label{})
   383  		return decodeMessage(b, &s.labelX[n])
   384  	},
   385  }
   386  
   387  func (p label) decoder() []decoder {
   388  	return labelDecoder
   389  }
   390  
   391  func (p label) encode(b *buffer) {
   392  	encodeInt64Opt(b, 1, p.keyX)
   393  	encodeInt64Opt(b, 2, p.strX)
   394  	encodeInt64Opt(b, 3, p.numX)
   395  }
   396  
   397  var labelDecoder = []decoder{
   398  	nil, // 0
   399  	// optional int64 key = 1
   400  	func(b *buffer, m message) error { return decodeInt64(b, &m.(*label).keyX) },
   401  	// optional int64 str = 2
   402  	func(b *buffer, m message) error { return decodeInt64(b, &m.(*label).strX) },
   403  	// optional int64 num = 3
   404  	func(b *buffer, m message) error { return decodeInt64(b, &m.(*label).numX) },
   405  }
   406  
   407  func (p *Mapping) decoder() []decoder {
   408  	return mappingDecoder
   409  }
   410  
   411  func (p *Mapping) encode(b *buffer) {
   412  	encodeUint64Opt(b, 1, p.ID)
   413  	encodeUint64Opt(b, 2, p.Start)
   414  	encodeUint64Opt(b, 3, p.Limit)
   415  	encodeUint64Opt(b, 4, p.Offset)
   416  	encodeInt64Opt(b, 5, p.fileX)
   417  	encodeInt64Opt(b, 6, p.buildIDX)
   418  	encodeBoolOpt(b, 7, p.HasFunctions)
   419  	encodeBoolOpt(b, 8, p.HasFilenames)
   420  	encodeBoolOpt(b, 9, p.HasLineNumbers)
   421  	encodeBoolOpt(b, 10, p.HasInlineFrames)
   422  }
   423  
   424  var mappingDecoder = []decoder{
   425  	nil, // 0
   426  	func(b *buffer, m message) error { return decodeUint64(b, &m.(*Mapping).ID) },            // optional uint64 id = 1
   427  	func(b *buffer, m message) error { return decodeUint64(b, &m.(*Mapping).Start) },         // optional uint64 memory_offset = 2
   428  	func(b *buffer, m message) error { return decodeUint64(b, &m.(*Mapping).Limit) },         // optional uint64 memory_limit = 3
   429  	func(b *buffer, m message) error { return decodeUint64(b, &m.(*Mapping).Offset) },        // optional uint64 file_offset = 4
   430  	func(b *buffer, m message) error { return decodeInt64(b, &m.(*Mapping).fileX) },          // optional int64 filename = 5
   431  	func(b *buffer, m message) error { return decodeInt64(b, &m.(*Mapping).buildIDX) },       // optional int64 build_id = 6
   432  	func(b *buffer, m message) error { return decodeBool(b, &m.(*Mapping).HasFunctions) },    // optional bool has_functions = 7
   433  	func(b *buffer, m message) error { return decodeBool(b, &m.(*Mapping).HasFilenames) },    // optional bool has_filenames = 8
   434  	func(b *buffer, m message) error { return decodeBool(b, &m.(*Mapping).HasLineNumbers) },  // optional bool has_line_numbers = 9
   435  	func(b *buffer, m message) error { return decodeBool(b, &m.(*Mapping).HasInlineFrames) }, // optional bool has_inline_frames = 10
   436  }
   437  
   438  func (p *Location) decoder() []decoder {
   439  	return locationDecoder
   440  }
   441  
   442  func (p *Location) encode(b *buffer) {
   443  	encodeUint64Opt(b, 1, p.ID)
   444  	encodeUint64Opt(b, 2, p.mappingIDX)
   445  	encodeUint64Opt(b, 3, p.Address)
   446  	for i := range p.Line {
   447  		encodeMessage(b, 4, &p.Line[i])
   448  	}
   449  }
   450  
   451  var locationDecoder = []decoder{
   452  	nil, // 0
   453  	func(b *buffer, m message) error { return decodeUint64(b, &m.(*Location).ID) },         // optional uint64 id = 1;
   454  	func(b *buffer, m message) error { return decodeUint64(b, &m.(*Location).mappingIDX) }, // optional uint64 mapping_id = 2;
   455  	func(b *buffer, m message) error { return decodeUint64(b, &m.(*Location).Address) },    // optional uint64 address = 3;
   456  	func(b *buffer, m message) error { // repeated Line line = 4
   457  		pp := m.(*Location)
   458  		n := len(pp.Line)
   459  		pp.Line = append(pp.Line, Line{})
   460  		return decodeMessage(b, &pp.Line[n])
   461  	},
   462  }
   463  
   464  func (p *Line) decoder() []decoder {
   465  	return lineDecoder
   466  }
   467  
   468  func (p *Line) encode(b *buffer) {
   469  	encodeUint64Opt(b, 1, p.functionIDX)
   470  	encodeInt64Opt(b, 2, p.Line)
   471  }
   472  
   473  var lineDecoder = []decoder{
   474  	nil, // 0
   475  	// optional uint64 function_id = 1
   476  	func(b *buffer, m message) error { return decodeUint64(b, &m.(*Line).functionIDX) },
   477  	// optional int64 line = 2
   478  	func(b *buffer, m message) error { return decodeInt64(b, &m.(*Line).Line) },
   479  }
   480  
   481  func (p *Function) decoder() []decoder {
   482  	return functionDecoder
   483  }
   484  
   485  func (p *Function) encode(b *buffer) {
   486  	encodeUint64Opt(b, 1, p.ID)
   487  	encodeInt64Opt(b, 2, p.nameX)
   488  	encodeInt64Opt(b, 3, p.systemNameX)
   489  	encodeInt64Opt(b, 4, p.filenameX)
   490  	encodeInt64Opt(b, 5, p.StartLine)
   491  }
   492  
   493  var functionDecoder = []decoder{
   494  	nil, // 0
   495  	// optional uint64 id = 1
   496  	func(b *buffer, m message) error { return decodeUint64(b, &m.(*Function).ID) },
   497  	// optional int64 function_name = 2
   498  	func(b *buffer, m message) error { return decodeInt64(b, &m.(*Function).nameX) },
   499  	// optional int64 function_system_name = 3
   500  	func(b *buffer, m message) error { return decodeInt64(b, &m.(*Function).systemNameX) },
   501  	// repeated int64 filename = 4
   502  	func(b *buffer, m message) error { return decodeInt64(b, &m.(*Function).filenameX) },
   503  	// optional int64 start_line = 5
   504  	func(b *buffer, m message) error { return decodeInt64(b, &m.(*Function).StartLine) },
   505  }
   506  
   507  func addString(strings map[string]int, s string) int64 {
   508  	i, ok := strings[s]
   509  	if !ok {
   510  		i = len(strings)
   511  		strings[s] = i
   512  	}
   513  	return int64(i)
   514  }
   515  
   516  func getString(strings []string, strng *int64, err error) (string, error) {
   517  	if err != nil {
   518  		return "", err
   519  	}
   520  	s := int(*strng)
   521  	if s < 0 || s >= len(strings) {
   522  		return "", errMalformed
   523  	}
   524  	*strng = 0
   525  	return strings[s], nil
   526  }