diff --git a/local_counter.go b/local_counter.go index 87a6ca4..ed7cca9 100644 --- a/local_counter.go +++ b/local_counter.go @@ -60,23 +60,6 @@ func (c *localCounter) Get(key string, currentWindow, previousWindow time.Time) return 0, 0, nil } -func (c *localCounter) evict(currentWindow time.Time) { - if c.latestWindow == currentWindow { - return - } - - previousWindow := currentWindow.Add(-c.windowLength) - if c.latestWindow == previousWindow { - c.latestWindow = currentWindow - c.latestCounters, c.previousCounters = make(map[uint64]int), c.latestCounters - return - } - - c.latestWindow = currentWindow - // NOTE: Don't use clear() to keep backward-compatibility. - c.previousCounters, c.latestCounters = make(map[uint64]int), make(map[uint64]int) -} - func limitCounterKey(key string) uint64 { h := xxhash.New() h.WriteString(key) diff --git a/local_counter_go1.20.go b/local_counter_go1.20.go new file mode 100644 index 0000000..e73a839 --- /dev/null +++ b/local_counter_go1.20.go @@ -0,0 +1,21 @@ +//go:build !go1.21 + +package httprate + +import "time" + +func (c *localCounter) evict(currentWindow time.Time) { + if c.latestWindow == currentWindow { + return + } + + previousWindow := currentWindow.Add(-c.windowLength) + if c.latestWindow == previousWindow { + c.latestWindow = currentWindow + c.latestCounters, c.previousCounters = make(map[uint64]int), c.latestCounters + return + } + + c.latestWindow = currentWindow + c.previousCounters, c.latestCounters = make(map[uint64]int), make(map[uint64]int) +} diff --git a/local_counter_go1.21.go b/local_counter_go1.21.go new file mode 100644 index 0000000..5aab646 --- /dev/null +++ b/local_counter_go1.21.go @@ -0,0 +1,25 @@ +//go:build go1.21 + +package httprate + +import "time" + +func (c *localCounter) evict(currentWindow time.Time) { + if c.latestWindow == currentWindow { + return + } + + previousWindow := currentWindow.Add(-c.windowLength) + if c.latestWindow == previousWindow { + c.latestWindow = currentWindow + // Shift the windows without map re-allocation. + clear(c.previousCounters) + c.latestCounters, c.previousCounters = c.previousCounters, c.latestCounters + return + } + + c.latestWindow = currentWindow + + clear(c.previousCounters) + clear(c.latestCounters) +}