// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package pprof

import (
	
	
	
	
	
)

// writeHeapProto writes the current heap profile in protobuf format to w.
func writeHeapProto( io.Writer,  []profilerecord.MemProfileRecord,  int64,  string) error {
	 := newProfileBuilder()
	.pbValueType(tagProfile_PeriodType, "space", "bytes")
	.pb.int64Opt(tagProfile_Period, )
	.pbValueType(tagProfile_SampleType, "alloc_objects", "count")
	.pbValueType(tagProfile_SampleType, "alloc_space", "bytes")
	.pbValueType(tagProfile_SampleType, "inuse_objects", "count")
	.pbValueType(tagProfile_SampleType, "inuse_space", "bytes")
	if  != "" {
		.pb.int64Opt(tagProfile_DefaultSampleType, .stringIndex())
	}

	 := []int64{0, 0, 0, 0}
	var  []uint64
	for ,  := range  {
		 := true
		for  := 0;  < 2; ++ {
			 := .Stack
			// For heap profiles, all stack
			// addresses are return PCs, which is
			// what appendLocsForStack expects.
			if  {
				for ,  := range  {
					if  := runtime.FuncForPC();  != nil && strings.HasPrefix(.Name(), "runtime.") {
						continue
					}
					// Found non-runtime. Show any runtime uses above it.
					 = [:]
					break
				}
			}
			 = .appendLocsForStack([:0], )
			if len() > 0 {
				break
			}
			 = false // try again, and show all frames next time.
		}

		[0], [1] = scaleHeapSample(.AllocObjects, .AllocBytes, )
		[2], [3] = scaleHeapSample(.InUseObjects(), .InUseBytes(), )
		var  int64
		if .AllocObjects > 0 {
			 = .AllocBytes / .AllocObjects
		}
		.pbSample(, , func() {
			if  != 0 {
				.pbLabel(tagSample_Label, "bytes", "", )
			}
		})
	}
	.build()
	return nil
}

// scaleHeapSample adjusts the data from a heap Sample to
// account for its probability of appearing in the collected
// data. heap profiles are a sampling of the memory allocations
// requests in a program. We estimate the unsampled value by dividing
// each collected sample by its probability of appearing in the
// profile. heap profiles rely on a poisson process to determine
// which samples to collect, based on the desired average collection
// rate R. The probability of a sample of size S to appear in that
// profile is 1-exp(-S/R).
func scaleHeapSample(, ,  int64) (int64, int64) {
	if  == 0 ||  == 0 {
		return 0, 0
	}

	if  <= 1 {
		// if rate==1 all samples were collected so no adjustment is needed.
		// if rate<1 treat as unknown and skip scaling.
		return , 
	}

	 := float64() / float64()
	 := 1 / (1 - math.Exp(-/float64()))

	return int64(float64() * ), int64(float64() * )
}