mirror of
https://github.com/coalaura/up.git
synced 2025-07-17 21:44:35 +00:00
53 lines
794 B
Go
53 lines
794 B
Go
![]() |
package main
|
||
|
|
||
|
import (
|
||
|
"sync"
|
||
|
"sync/atomic"
|
||
|
)
|
||
|
|
||
|
type RateLimiter struct {
|
||
|
sync.Map
|
||
|
}
|
||
|
|
||
|
func NewRateLimiter() *RateLimiter {
|
||
|
return &RateLimiter{}
|
||
|
}
|
||
|
|
||
|
func (rl *RateLimiter) Get(key string) *atomic.Uint32 {
|
||
|
val, ok := rl.Map.Load(key)
|
||
|
if ok {
|
||
|
return val.(*atomic.Uint32)
|
||
|
}
|
||
|
|
||
|
actual, _ := rl.Map.LoadOrStore(key, &atomic.Uint32{})
|
||
|
|
||
|
return actual.(*atomic.Uint32)
|
||
|
}
|
||
|
|
||
|
func (rl *RateLimiter) Inc(key string) (uint32, func(), func()) {
|
||
|
val := rl.Get(key)
|
||
|
new := val.Add(1)
|
||
|
|
||
|
var done uint32
|
||
|
|
||
|
pass := func() {
|
||
|
atomic.CompareAndSwapUint32(&done, 0, 1)
|
||
|
}
|
||
|
|
||
|
fail := func() {
|
||
|
if !atomic.CompareAndSwapUint32(&done, 0, 1) {
|
||
|
return
|
||
|
}
|
||
|
|
||
|
val.Add(^uint32(0))
|
||
|
}
|
||
|
|
||
|
return new, pass, fail
|
||
|
}
|
||
|
|
||
|
func (rl *RateLimiter) Dec(key string) uint32 {
|
||
|
val := rl.Get(key)
|
||
|
|
||
|
return val.Add(^uint32(0))
|
||
|
}
|