// Copyright 2017 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 

// A profMap is a map from (stack, tag) to mapEntry.
// It grows without bound, but that's assumed to be OK.
type profMap struct {
	hash    map[uintptr]*profMapEntry
	all     *profMapEntry
	last    *profMapEntry
	free    []profMapEntry
	freeStk []uintptr
}

// A profMapEntry is a single entry in the profMap.
type profMapEntry struct {
	nextHash *profMapEntry // next in hash list
	nextAll  *profMapEntry // next in list of all entries
	stk      []uintptr
	tag      unsafe.Pointer
	count    int64
}

func ( *profMap) ( []uint64,  unsafe.Pointer) *profMapEntry {
	// Compute hash of (stk, tag).
	 := uintptr(0)
	for ,  := range  {
		 = <<8 | ( >> (8 * (unsafe.Sizeof() - 1)))
		 += uintptr() * 41
	}
	 = <<8 | ( >> (8 * (unsafe.Sizeof() - 1)))
	 += uintptr() * 41

	// Find entry if present.
	var  *profMapEntry
:
	for  := .hash[];  != nil; ,  = , .nextHash {
		if len(.stk) != len() || .tag !=  {
			continue
		}
		for  := range  {
			if .stk[] != uintptr([]) {
				continue 
			}
		}
		// Move to front.
		if  != nil {
			.nextHash = .nextHash
			.nextHash = .hash[]
			.hash[] = 
		}
		return 
	}

	// Add new entry.
	if len(.free) < 1 {
		.free = make([]profMapEntry, 128)
	}
	 := &.free[0]
	.free = .free[1:]
	.nextHash = .hash[]
	.tag = 

	if len(.freeStk) < len() {
		.freeStk = make([]uintptr, 1024)
	}
	// Limit cap to prevent append from clobbering freeStk.
	.stk = .freeStk[:len():len()]
	.freeStk = .freeStk[len():]

	for  := range  {
		.stk[] = uintptr([])
	}
	if .hash == nil {
		.hash = make(map[uintptr]*profMapEntry)
	}
	.hash[] = 
	if .all == nil {
		.all = 
		.last = 
	} else {
		.last.nextAll = 
		.last = 
	}
	return 
}