validity_map.go 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. package collect
  2. import (
  3. "sync"
  4. "sync/atomic"
  5. )
  6. type Validity interface {
  7. IsValid() bool
  8. }
  9. type entry struct {
  10. key string
  11. value Validity
  12. }
  13. type ValidityMap struct {
  14. sync.RWMutex
  15. cache map[string]Validity
  16. opCount int32
  17. }
  18. func NewValidityMap(cleanupIntervalSec int) *ValidityMap {
  19. instance := &ValidityMap{
  20. cache: make(map[string]Validity),
  21. }
  22. return instance
  23. }
  24. func (this *ValidityMap) cleanup() {
  25. entry2Remove := make([]entry, 0, 128)
  26. this.RLock()
  27. for key, value := range this.cache {
  28. if !value.IsValid() {
  29. entry2Remove = append(entry2Remove, entry{
  30. key: key,
  31. value: value,
  32. })
  33. }
  34. }
  35. this.RUnlock()
  36. for _, entry := range entry2Remove {
  37. if !entry.value.IsValid() {
  38. this.Lock()
  39. delete(this.cache, entry.key)
  40. this.Unlock()
  41. }
  42. }
  43. }
  44. func (this *ValidityMap) Set(key string, value Validity) {
  45. this.Lock()
  46. this.cache[key] = value
  47. this.Unlock()
  48. opCount := atomic.AddInt32(&this.opCount, 1)
  49. if opCount > 1000 {
  50. atomic.StoreInt32(&this.opCount, 0)
  51. go this.cleanup()
  52. }
  53. }
  54. func (this *ValidityMap) Get(key string) Validity {
  55. this.RLock()
  56. defer this.RUnlock()
  57. if value, found := this.cache[key]; found {
  58. return value
  59. }
  60. return nil
  61. }