Skip to content

Commit

Permalink
Local counter: Don't re-allocate maps in Go 1.21+
Browse files Browse the repository at this point in the history
  • Loading branch information
VojtechVitek committed Jul 25, 2024
1 parent 05a79e9 commit 116024c
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 17 deletions.
17 changes: 0 additions & 17 deletions local_counter.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
21 changes: 21 additions & 0 deletions local_counter_go1.20.go
Original file line number Diff line number Diff line change
@@ -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)
}
25 changes: 25 additions & 0 deletions local_counter_go1.21.go
Original file line number Diff line number Diff line change
@@ -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)
}

0 comments on commit 116024c

Please sign in to comment.