58 lines
1002 B
Go
58 lines
1002 B
Go
package store
|
|
|
|
import (
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
const MaxHistoryPoints = 10000
|
|
|
|
type Sample struct {
|
|
At time.Time
|
|
Value int
|
|
}
|
|
|
|
type Store struct {
|
|
mu sync.RWMutex
|
|
value int
|
|
updatedAt time.Time
|
|
history []Sample
|
|
}
|
|
|
|
func (s *Store) Get() int {
|
|
s.mu.RLock()
|
|
defer s.mu.RUnlock()
|
|
return s.value
|
|
}
|
|
|
|
func (s *Store) Set(v int) {
|
|
s.mu.Lock()
|
|
s.value = v
|
|
now := time.Now()
|
|
s.updatedAt = now
|
|
s.history = append(s.history, Sample{At: now, Value: v})
|
|
s.trimHistoryLocked(now)
|
|
s.mu.Unlock()
|
|
}
|
|
|
|
func (s *Store) trimHistoryLocked(now time.Time) {
|
|
cutoff := now.Add(-12 * time.Hour)
|
|
keep := s.history[:0]
|
|
for _, point := range s.history {
|
|
if point.At.After(cutoff) {
|
|
keep = append(keep, point)
|
|
}
|
|
}
|
|
if len(keep) > MaxHistoryPoints {
|
|
keep = keep[len(keep)-MaxHistoryPoints:]
|
|
}
|
|
s.history = keep
|
|
}
|
|
|
|
func (s *Store) Snapshot() (int, time.Time, []Sample) {
|
|
s.mu.RLock()
|
|
defer s.mu.RUnlock()
|
|
history := append([]Sample(nil), s.history...)
|
|
return s.value, s.updatedAt, history
|
|
}
|