Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.0.0-20201028153306-37f0764111ff / internal / event / export / metric / exporter.go
1 // Copyright 2019 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 metric aggregates events into metrics that can be exported.
6 package metric
7
8 import (
9         "context"
10         "sync"
11         "time"
12
13         "golang.org/x/tools/internal/event"
14         "golang.org/x/tools/internal/event/core"
15         "golang.org/x/tools/internal/event/keys"
16         "golang.org/x/tools/internal/event/label"
17 )
18
19 var Entries = keys.New("metric_entries", "The set of metrics calculated for an event")
20
21 type Config struct {
22         subscribers map[interface{}][]subscriber
23 }
24
25 type subscriber func(time.Time, label.Map, label.Label) Data
26
27 func (e *Config) subscribe(key label.Key, s subscriber) {
28         if e.subscribers == nil {
29                 e.subscribers = make(map[interface{}][]subscriber)
30         }
31         e.subscribers[key] = append(e.subscribers[key], s)
32 }
33
34 func (e *Config) Exporter(output event.Exporter) event.Exporter {
35         var mu sync.Mutex
36         return func(ctx context.Context, ev core.Event, lm label.Map) context.Context {
37                 if !event.IsMetric(ev) {
38                         return output(ctx, ev, lm)
39                 }
40                 mu.Lock()
41                 defer mu.Unlock()
42                 var metrics []Data
43                 for index := 0; ev.Valid(index); index++ {
44                         l := ev.Label(index)
45                         if !l.Valid() {
46                                 continue
47                         }
48                         id := l.Key()
49                         if list := e.subscribers[id]; len(list) > 0 {
50                                 for _, s := range list {
51                                         metrics = append(metrics, s(ev.At(), lm, l))
52                                 }
53                         }
54                 }
55                 lm = label.MergeMaps(label.NewMap(Entries.Of(metrics)), lm)
56                 return output(ctx, ev, lm)
57         }
58 }