@ -11,6 +11,9 @@ import (
"io"
"io"
"slices"
"slices"
"strings"
"strings"
"sync"
"tailscale.com/syncs"
)
)
// Set is a string-to-Var map variable that satisfies the expvar.Var
// Set is a string-to-Var map variable that satisfies the expvar.Var
@ -37,6 +40,8 @@ type Set struct {
type LabelMap struct {
type LabelMap struct {
Label string
Label string
expvar . Map
expvar . Map
// shardedIntMu orders the initialization of new shardedint keys
shardedIntMu sync . Mutex
}
}
// SetInt64 sets the *Int value stored under the given map key.
// SetInt64 sets the *Int value stored under the given map key.
@ -44,6 +49,19 @@ func (m *LabelMap) SetInt64(key string, v int64) {
m . Get ( key ) . Set ( v )
m . Get ( key ) . Set ( v )
}
}
// Add adds delta to the any int-like value stored under the given map key.
func ( m * LabelMap ) Add ( key string , delta int64 ) {
type intAdder interface {
Add ( delta int64 )
}
o := m . Map . Get ( key )
if o == nil {
m . Map . Add ( key , delta )
return
}
o . ( intAdder ) . Add ( delta )
}
// Get returns a direct pointer to the expvar.Int for key, creating it
// Get returns a direct pointer to the expvar.Int for key, creating it
// if necessary.
// if necessary.
func ( m * LabelMap ) Get ( key string ) * expvar . Int {
func ( m * LabelMap ) Get ( key string ) * expvar . Int {
@ -51,6 +69,23 @@ func (m *LabelMap) Get(key string) *expvar.Int {
return m . Map . Get ( key ) . ( * expvar . Int )
return m . Map . Get ( key ) . ( * expvar . Int )
}
}
// GetShardedInt returns a direct pointer to the syncs.ShardedInt for key,
// creating it if necessary.
func ( m * LabelMap ) GetShardedInt ( key string ) * syncs . ShardedInt {
i := m . Map . Get ( key )
if i == nil {
m . shardedIntMu . Lock ( )
defer m . shardedIntMu . Unlock ( )
i = m . Map . Get ( key )
if i != nil {
return i . ( * syncs . ShardedInt )
}
i = syncs . NewShardedInt ( )
m . Set ( key , i )
}
return i . ( * syncs . ShardedInt )
}
// GetIncrFunc returns a function that increments the expvar.Int named by key.
// GetIncrFunc returns a function that increments the expvar.Int named by key.
//
//
// Most callers should not need this; it exists to satisfy an
// Most callers should not need this; it exists to satisfy an