forked from jshiffer/matterbridge
99 lines
1.8 KiB
Go
99 lines
1.8 KiB
Go
package logr
|
|
|
|
import (
|
|
"fmt"
|
|
"sync"
|
|
)
|
|
|
|
// LevelStatus represents whether a level is enabled and
|
|
// requires a stack trace.
|
|
type LevelStatus struct {
|
|
Enabled bool
|
|
Stacktrace bool
|
|
empty bool
|
|
}
|
|
|
|
type levelCache interface {
|
|
setup()
|
|
get(id LevelID) (LevelStatus, bool)
|
|
put(id LevelID, status LevelStatus) error
|
|
clear()
|
|
}
|
|
|
|
// syncMapLevelCache uses sync.Map which may better handle large concurrency
|
|
// scenarios.
|
|
type syncMapLevelCache struct {
|
|
m sync.Map
|
|
}
|
|
|
|
func (c *syncMapLevelCache) setup() {
|
|
c.clear()
|
|
}
|
|
|
|
func (c *syncMapLevelCache) get(id LevelID) (LevelStatus, bool) {
|
|
if id > MaxLevelID {
|
|
return LevelStatus{}, false
|
|
}
|
|
s, _ := c.m.Load(id)
|
|
status := s.(LevelStatus)
|
|
return status, !status.empty
|
|
}
|
|
|
|
func (c *syncMapLevelCache) put(id LevelID, status LevelStatus) error {
|
|
if id > MaxLevelID {
|
|
return fmt.Errorf("level id cannot exceed MaxLevelID (%d)", MaxLevelID)
|
|
}
|
|
c.m.Store(id, status)
|
|
return nil
|
|
}
|
|
|
|
func (c *syncMapLevelCache) clear() {
|
|
var i LevelID
|
|
for i = 0; i < MaxLevelID; i++ {
|
|
c.m.Store(i, LevelStatus{empty: true})
|
|
}
|
|
}
|
|
|
|
// arrayLevelCache using array and a mutex.
|
|
type arrayLevelCache struct {
|
|
arr [MaxLevelID + 1]LevelStatus
|
|
mux sync.RWMutex
|
|
}
|
|
|
|
func (c *arrayLevelCache) setup() {
|
|
c.clear()
|
|
}
|
|
|
|
//var dummy = LevelStatus{}
|
|
|
|
func (c *arrayLevelCache) get(id LevelID) (LevelStatus, bool) {
|
|
if id > MaxLevelID {
|
|
return LevelStatus{}, false
|
|
}
|
|
c.mux.RLock()
|
|
status := c.arr[id]
|
|
ok := !status.empty
|
|
c.mux.RUnlock()
|
|
return status, ok
|
|
}
|
|
|
|
func (c *arrayLevelCache) put(id LevelID, status LevelStatus) error {
|
|
if id > MaxLevelID {
|
|
return fmt.Errorf("level id cannot exceed MaxLevelID (%d)", MaxLevelID)
|
|
}
|
|
c.mux.Lock()
|
|
defer c.mux.Unlock()
|
|
|
|
c.arr[id] = status
|
|
return nil
|
|
}
|
|
|
|
func (c *arrayLevelCache) clear() {
|
|
c.mux.Lock()
|
|
defer c.mux.Unlock()
|
|
|
|
for i := range c.arr {
|
|
c.arr[i] = LevelStatus{empty: true}
|
|
}
|
|
}
|