mirror of
https://github.com/autc04/Retro68.git
synced 2024-11-03 07:07:20 +00:00
86 lines
2.4 KiB
Go
86 lines
2.4 KiB
Go
// 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 (
|
|
"context"
|
|
)
|
|
|
|
type label struct {
|
|
key string
|
|
value string
|
|
}
|
|
|
|
// LabelSet is a set of labels.
|
|
type LabelSet struct {
|
|
list []label
|
|
}
|
|
|
|
// labelContextKey is the type of contextKeys used for profiler labels.
|
|
type labelContextKey struct{}
|
|
|
|
func labelValue(ctx context.Context) labelMap {
|
|
labels, _ := ctx.Value(labelContextKey{}).(*labelMap)
|
|
if labels == nil {
|
|
return labelMap(nil)
|
|
}
|
|
return *labels
|
|
}
|
|
|
|
// labelMap is the representation of the label set held in the context type.
|
|
// This is an initial implementation, but it will be replaced with something
|
|
// that admits incremental immutable modification more efficiently.
|
|
type labelMap map[string]string
|
|
|
|
// WithLabels returns a new context.Context with the given labels added.
|
|
// A label overwrites a prior label with the same key.
|
|
func WithLabels(ctx context.Context, labels LabelSet) context.Context {
|
|
childLabels := make(labelMap)
|
|
parentLabels := labelValue(ctx)
|
|
// TODO(matloob): replace the map implementation with something
|
|
// more efficient so creating a child context WithLabels doesn't need
|
|
// to clone the map.
|
|
for k, v := range parentLabels {
|
|
childLabels[k] = v
|
|
}
|
|
for _, label := range labels.list {
|
|
childLabels[label.key] = label.value
|
|
}
|
|
return context.WithValue(ctx, labelContextKey{}, &childLabels)
|
|
}
|
|
|
|
// Labels takes an even number of strings representing key-value pairs
|
|
// and makes a LabelSet containing them.
|
|
// A label overwrites a prior label with the same key.
|
|
func Labels(args ...string) LabelSet {
|
|
if len(args)%2 != 0 {
|
|
panic("uneven number of arguments to pprof.Labels")
|
|
}
|
|
labels := LabelSet{}
|
|
for i := 0; i+1 < len(args); i += 2 {
|
|
labels.list = append(labels.list, label{key: args[i], value: args[i+1]})
|
|
}
|
|
return labels
|
|
}
|
|
|
|
// Label returns the value of the label with the given key on ctx, and a boolean indicating
|
|
// whether that label exists.
|
|
func Label(ctx context.Context, key string) (string, bool) {
|
|
ctxLabels := labelValue(ctx)
|
|
v, ok := ctxLabels[key]
|
|
return v, ok
|
|
}
|
|
|
|
// ForLabels invokes f with each label set on the context.
|
|
// The function f should return true to continue iteration or false to stop iteration early.
|
|
func ForLabels(ctx context.Context, f func(key, value string) bool) {
|
|
ctxLabels := labelValue(ctx)
|
|
for k, v := range ctxLabels {
|
|
if !f(k, v) {
|
|
break
|
|
}
|
|
}
|
|
}
|