memory.go 975 B

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. package ratelimiter
  2. import (
  3. "errors"
  4. "time"
  5. )
  6. const GC_SIZE int = 100
  7. type Memory struct {
  8. store map[string]LeakyBucket
  9. lastGCCollected time.Time
  10. }
  11. func NewMemory() *Memory {
  12. m := new(Memory)
  13. m.store = make(map[string]LeakyBucket)
  14. m.lastGCCollected = time.Now()
  15. return m
  16. }
  17. func (m *Memory) GetBucketFor(key string) (*LeakyBucket, error) {
  18. bucket, ok := m.store[key]
  19. if !ok {
  20. return nil, errors.New("miss")
  21. }
  22. return &bucket, nil
  23. }
  24. func (m *Memory) SetBucketFor(key string, bucket LeakyBucket) error {
  25. if len(m.store) > GC_SIZE {
  26. m.GarbageCollect()
  27. }
  28. m.store[key] = bucket
  29. return nil
  30. }
  31. func (m *Memory) GarbageCollect() {
  32. now := time.Now()
  33. // rate limit GC to once per minute
  34. if now.Add(60*time.Second).Unix() > m.lastGCCollected.Unix() {
  35. for key, bucket := range m.store {
  36. // if the bucket is drained, then GC
  37. if bucket.DrainedAt().Unix() > now.Unix() {
  38. delete(m.store, key)
  39. }
  40. }
  41. m.lastGCCollected = now
  42. }
  43. }