package main
// NOTE:
// Go maps do not have a size cap. Use LRU-caches instead for anything serious.
import (
"sync"
"time"
"github.com/faroedev/faroe"
)
type rateLimitStorageStruct struct {
records map[string]rateLimitStorageRecordStruct
m *sync.Mutex
}
func newRateLimitStorage() *rateLimitStorageStruct {
storage := &rateLimitStorageStruct{
records: map[string]rateLimitStorageRecordStruct{},
m: &sync.Mutex{},
}
return storage
}
func (rateLimitStorage *rateLimitStorageStruct) Get(key string) ([]byte, string, int32, error) {
rateLimitStorage.m.Lock()
defer rateLimitStorage.m.Unlock()
record, ok := rateLimitStorage.records[key]
if !ok {
return nil, "", 0, faroe.ErrRateLimitStorageEntryNotFound
}
return record.value, record.id, record.counter, nil
}
func (rateLimitStorage *rateLimitStorageStruct) Add(key string, value []byte, entryId string, expiresAt time.Time) error {
rateLimitStorage.m.Lock()
defer rateLimitStorage.m.Unlock()
_, ok := rateLimitStorage.records[key]
if ok {
return faroe.ErrRateLimitStorageEntryAlreadyExists
}
rateLimitStorage.records[key] = rateLimitStorageRecordStruct{
value: value,
id: entryId,
counter: 0,
}
return nil
}
func (rateLimitStorage *rateLimitStorageStruct) Update(key string, value []byte, expiresAt time.Time, entryId string, counter int32) error {
rateLimitStorage.m.Lock()
defer rateLimitStorage.m.Unlock()
record, ok := rateLimitStorage.records[key]
if !ok {
return faroe.ErrRateLimitStorageEntryNotFound
}
if record.id != entryId || record.counter != counter {
return faroe.ErrRateLimitStorageEntryNotFound
}
record.value = value
record.counter++
rateLimitStorage.records[key] = record
return nil
}
func (rateLimitStorage *rateLimitStorageStruct) Delete(key string, entryId string, counter int32) error {
rateLimitStorage.m.Lock()
defer rateLimitStorage.m.Unlock()
record, ok := rateLimitStorage.records[key]
if !ok {
return faroe.ErrRateLimitStorageEntryNotFound
}
if record.id != entryId || record.counter != counter {
return faroe.ErrRateLimitStorageEntryNotFound
}
delete(rateLimitStorage.records, key)
return nil
}
type rateLimitStorageRecordStruct struct {
value []byte
id string
counter int32
}