package main import ( "sync" "time" ) type SlidingWindowCounter struct { mu sync.Mutex events []time.Time windowSize time.Duration } func NewSlidingWindowCounter(windowSize time.Duration) *SlidingWindowCounter { return &SlidingWindowCounter{ events: make([]time.Time, 0), windowSize: windowSize, } } func (swc *SlidingWindowCounter) Increment() { swc.mu.Lock() defer swc.mu.Unlock() now := time.Now() swc.events = append(swc.events, now) swc.removeOldEvents(now) } func (swc *SlidingWindowCounter) Count() int { swc.mu.Lock() defer swc.mu.Unlock() now := time.Now() swc.removeOldEvents(now) return len(swc.events) } func (swc *SlidingWindowCounter) removeOldEvents(now time.Time) { cutoff := now.Add(-swc.windowSize) i := 0 for ; i < len(swc.events); i++ { if swc.events[i].After(cutoff) { break } } swc.events = swc.events[i:] }