]> Cypherpunks.ru repositories - gostls13.git/blob - src/runtime/pprof/label.go
[dev.boringcrypto] all: merge master into dev.boringcrypto
[gostls13.git] / src / runtime / pprof / label.go
1 // Copyright 2016 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package pprof
6
7 import (
8         "context"
9 )
10
11 type label struct {
12         key   string
13         value string
14 }
15
16 // LabelSet is a set of labels.
17 type LabelSet struct {
18         list []label
19 }
20
21 // labelContextKey is the type of contextKeys used for profiler labels.
22 type labelContextKey struct{}
23
24 func labelValue(ctx context.Context) labelMap {
25         labels, _ := ctx.Value(labelContextKey{}).(*labelMap)
26         if labels == nil {
27                 return labelMap(nil)
28         }
29         return *labels
30 }
31
32 // labelMap is the representation of the label set held in the context type.
33 // This is an initial implementation, but it will be replaced with something
34 // that admits incremental immutable modification more efficiently.
35 type labelMap map[string]string
36
37 // WithLabels returns a new context.Context with the given labels added.
38 // A label overwrites a prior label with the same key.
39 func WithLabels(ctx context.Context, labels LabelSet) context.Context {
40         childLabels := make(labelMap)
41         parentLabels := labelValue(ctx)
42         // TODO(matloob): replace the map implementation with something
43         // more efficient so creating a child context WithLabels doesn't need
44         // to clone the map.
45         for k, v := range parentLabels {
46                 childLabels[k] = v
47         }
48         for _, label := range labels.list {
49                 childLabels[label.key] = label.value
50         }
51         return context.WithValue(ctx, labelContextKey{}, &childLabels)
52 }
53
54 // Labels takes an even number of strings representing key-value pairs
55 // and makes a LabelSet containing them.
56 // A label overwrites a prior label with the same key.
57 // Currently only CPU profile utilizes labels information.
58 // See https://golang.org/issue/23458 for details.
59 func Labels(args ...string) LabelSet {
60         if len(args)%2 != 0 {
61                 panic("uneven number of arguments to pprof.Labels")
62         }
63         list := make([]label, 0, len(args)/2)
64         for i := 0; i+1 < len(args); i += 2 {
65                 list = append(list, label{key: args[i], value: args[i+1]})
66         }
67         return LabelSet{list: list}
68 }
69
70 // Label returns the value of the label with the given key on ctx, and a boolean indicating
71 // whether that label exists.
72 func Label(ctx context.Context, key string) (string, bool) {
73         ctxLabels := labelValue(ctx)
74         v, ok := ctxLabels[key]
75         return v, ok
76 }
77
78 // ForLabels invokes f with each label set on the context.
79 // The function f should return true to continue iteration or false to stop iteration early.
80 func ForLabels(ctx context.Context, f func(key, value string) bool) {
81         ctxLabels := labelValue(ctx)
82         for k, v := range ctxLabels {
83                 if !f(k, v) {
84                         break
85                 }
86         }
87 }