12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485 |
- // Copyright (c) 2017 Arista Networks, Inc.
- // Use of this source code is governed by the Apache License 2.0
- // that can be found in the COPYING file.
- // This code was forked from the Go project, here's the original copyright header:
- // Copyright 2009 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 monitor
- import (
- "bytes"
- "expvar"
- "fmt"
- "sync"
- )
- // Map is a string-to-Var map variable that satisfies the Var interface.
- // This a streamlined, more efficient version of expvar.Map, that also
- // supports deletion.
- type Map struct {
- m sync.Map // map[string]expvar.Var
- }
- func (v *Map) String() string {
- var b bytes.Buffer
- b.WriteByte('{')
- first := true
- v.m.Range(func(k, value interface{}) bool {
- if !first {
- b.WriteString(", ")
- }
- fmt.Fprintf(&b, "%q: %v", k, value)
- first = false
- return true
- })
- b.WriteByte('}')
- return b.String()
- }
- // Get atomically returns the Var for the given key or nil.
- func (v *Map) Get(key string) expvar.Var {
- i, _ := v.m.Load(key)
- av, _ := i.(expvar.Var)
- return av
- }
- // Set atomically associates the given Var to the given key.
- func (v *Map) Set(key string, av expvar.Var) {
- // Before we store the value, check to see whether the key is new. Try a Load
- // before LoadOrStore: LoadOrStore causes the key interface to escape even on
- // the Load path.
- if _, ok := v.m.Load(key); !ok {
- if _, dup := v.m.LoadOrStore(key, av); !dup {
- return
- }
- }
- v.m.Store(key, av)
- }
- // Delete atomically deletes the given key if it exists.
- func (v *Map) Delete(key string) {
- v.m.Delete(key)
- }
- // Do calls f for each entry in the map.
- // The map is locked during the iteration,
- // but existing entries may be concurrently updated.
- func (v *Map) Do(f func(expvar.KeyValue)) {
- v.m.Range(func(k, value interface{}) bool {
- f(expvar.KeyValue{Key: k.(string), Value: value.(expvar.Var)})
- return true
- })
- }
- // NewMap creates a new Map and publishes it with the given name.
- func NewMap(name string) *Map {
- v := new(Map)
- expvar.Publish(name, v)
- return v
- }
|