ipld-eth-server/vendor/github.com/aristanetworks/goarista/monitor/map.go

85 lines
2.1 KiB
Go
Raw Normal View History

// 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
}